# Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

Questions about MultiCharts .NET and user contributed studies.
Jobauma
Posts: 113
Joined: 16 Apr 2013
Has thanked: 25 times
Been thanked: 5 times

### Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

Hi.

I've discovered that doing different things in "CalcBar()" affects what is treated as 1st bar on a chart, or where the calculation of an indicator starts.

I have done some work on discovering what was the cause. For example, doing this...

Code: Select all

``` // Core Functions: m_CF_curHigh = Bars.High[0]; m_CF_curLow = Bars.Low[0]; m_CF_preHigh = Bars.High[1]; m_CF_preLow = Bars.Low[1]; m_CF_curClose = Bars.Close[0]; ```
...somewhat affects this.

Or this:

Code: Select all

``` p_PlotObject.Reset(55); ```
I use IQFeed, and the greatest chart with minutes I use is M233 with an indicator 55 bars back.. I need 343 bars back on each chart, and this is enough with IQFeed.

Code: Select all

``` if ( Bars.FullSymbolData.Current > Bars.FullSymbolData.Count - ( 288 + 55 ) ) Counter++; ```
This should return "343", but it doesn't. This causes problems with greater charts.

The solution would be to force MultiCharts to start the calculation on the 1st bar every time.

Can this be fixed in the next upcoming version of MultiCharts?

Best regards,

Jobauma
Posts: 113
Joined: 16 Apr 2013
Has thanked: 25 times
Been thanked: 5 times

### Re: Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

If a moving average is, for example, "34" in length, it would calculate the moving average of bar "1", and the rest is calculated as "0" ( or the same as value of the 1st bar ).

The solution would be to add virtual bars (values), as "0", from actual 1st bar to where the calculation starts, as bars back of virtual bars.

To prevent moving averages to bring virtual bars:

Code: Select all

``` if ( Length <= Bars.FullSymbolData.Current ) Length = Bars.FullSymbolData.Current; ```
This would also apply to, for example, TrendLine Objects. If the length is above 1st bar, the 1st point is applied to some virtual bar ( or the 1st bar ), outside the chart.

To manually decide where the calculation starts with, for example, "89" bars back, and a moving average of length "34" ( to skip virtual bars ):

Code: Select all

``` public double Average( VariableSeries<double> Value, int Length ) { // SOME CODE } if ( Bars.FullSymbolData.Current > Bars.FullSymbolData.Count - 55 ) Average( Value, 34 ); ```
Here the calculation of the moving average is calculated after "34" bars, and the rest is "55" bars.

Alternatively there could be a preference for this behaviour for virtual bars, in "Preferences...", or in the study it self; "[ForceCalculationFrom1stBar(true)]". Problem solved.

~Zola~
Posts: 20
Joined: 28 Nov 2016
Has thanked: 5 times
Been thanked: 1 time

### Re: Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

If a moving average is, for example, "34" in length, it would calculate the moving average of bar "1", and the rest is calculated as "0" ( or the same as value of the 1st bar ).

The solution would be to add virtual bars (values), as "0", from actual 1st bar to where the calculation starts, as bars back of virtual bars.

To prevent moving averages to bring virtual bars:

Code: Select all

```if ( Length <= Bars.FullSymbolData.Current ) Length = Bars.FullSymbolData.Current; ```
This would also apply to, for example, TrendLine Objects. If the length is above 1st bar, the 1st point is applied to some virtual bar ( or the 1st bar ), outside the chart.

To manually decide where the calculation starts with, for example, "89" bars back, and a moving average of length "34" ( to skip virtual bars ):

Code: Select all

```public double Average( VariableSeries<double> Value, int Length ) { // SOME CODE } if ( Bars.FullSymbolData.Current > Bars.FullSymbolData.Count - 55 ) Average( Value, 34 ); ```
Here the calculation of the moving average is calculated after "34" bars, and the rest is "55" bars.

Alternatively there could be a preference for this behaviour for virtual bars, in "Preferences...", or in the study it self; "[ForceCalculationFrom1stBar(true)]". Problem solved.
I noted your this issue previously, could I know how to use [ForceCalculationFrom1stBar(true)] in detail, i.e. the syntax.

Svetlana MultiCharts
Posts: 377
Joined: 19 Oct 2017
Has thanked: 2 times
Been thanked: 101 times

### Re: Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

Hello, Jobauma,

By design, the calculation may start not from the first bar if the study refers to a certain number of previous bars for initial calculation. In this case MultiCharts steps that number of bars from the begging of the data series to let the study access the values of those historical bars. One should take it into account when coding a study.

Jobauma
Posts: 113
Joined: 16 Apr 2013
Has thanked: 25 times
Been thanked: 5 times

### Re: Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

Hi.

I've seen through my code, and it should work with 233 bars. The indicator needs 144 + 55 bars, but even with 1000 bars back, the indicator can turn red some times, and sometimes not ( indication of not enough bars ). Recalculation of the indicator can make it work. I have automatic recalculation, and then the indicator can turn red, but if I recalculate manually afterwards, there are enough bars. I think there are some bugs to the initial calculation.

An option of turning off initial calculation would still be nice.

Best regards,

Jobauma
Posts: 113
Joined: 16 Apr 2013
Has thanked: 25 times
Been thanked: 5 times

### Re: Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

I solved it by switching some code from "while" to "for".

The "while" even had a limit to it. This is probably a bug with the initial calculation.

Example - "while":

Code: Select all

```// Core Functions private int m_From1stBarCounter; // Begins counting 144 + 55 bars back // Initialize I = 0; Done = false; // Calculate while ( !Done && I < m_From1stBarCounter ) { if ( [ SOME CODE ] ) { [ SOME CODE ] } else Done = true; // Finalize: I ++ I++; } ```

Example - "for":

Code: Select all

```// Initialize Done = false; // Calculate for ( int I = 0; I < 89 ) { if (!Done) { if ( [ SOME CODE ] ) { [ SOME CODE ] } else Done = true; } } ```

Best regards,

Jobauma
Posts: 113
Joined: 16 Apr 2013
Has thanked: 25 times
Been thanked: 5 times

### Re: Doing Different Things in "CalcBar()" Affects what is Treated as 1st Bar

It's "m_From1stBarCounter" that is causing the bug.

Code: Select all

```public double Method( double Value ) { // Initialie: I = "0" · Done = "False" I = 0; Done = false; while ( !Done && I < m_From1stBarCounter ) { if ( [ SOME CODE ] ) Done = true; // Finalize: I ++ I++; } } protected override void StartCalc() { m_CF_From1stBar_Counter = 0; } protected override void CalcBar() { // Initialize: Number of Bars · Current Bar m_CF_NumberOfBars = Bars.FullSymbolData.Count; m_CF_CurrentBar = Bars.FullSymbolData.Current; if ( m_CF_CurrentBar > m_CF_NumberOfBars - ( 144 + 55 ) ) m_CF_From1stBar_Counter++; } ```

This works:

Code: Select all

```// Initialie: I = "0" · Done = "False" I = 0; Done = false; while ( !Done && I < 89 ) { if ( [ SOME CODE ] ) Done = true; // Finalize: I ++ I++; } ```