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

Postby Jobauma » 09 Nov 2019

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. :D

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



Best regards,
Johannes Hillestad Baumann

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

Postby Jobauma » 10 Nov 2019

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. :D

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. :D

~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

Postby ~Zola~ » 04 Dec 2019

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. :D

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. :D
I noted your this issue previously, could I know how to use [ForceCalculationFrom1stBar(true)] in detail, i.e. the syntax.

User avatar
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

Postby Svetlana MultiCharts » 16 Jan 2020

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

Postby Jobauma » 02 Mar 2020

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,
Johannes Hillestad Baumann

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

Postby Jobauma » 03 Mar 2020

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,
Johannes Hillestad Baumann

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

Postby Jobauma » 10 Mar 2020

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++; }


Return to “MultiCharts .NET”