OBVIOUS BUG

 

I use the simple code:


#property indicator_chart_window

#property indicator_buffers 1

double test[];

int OnInit(){

  SetIndexBuffer(0, test,INDICATOR_DATA);

  return(INIT_SUCCEEDED);

}


int DaysGone = 0;

int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[])

{

  int first= prev_calculated > 0?  prev_calculated-1 : 21;

  for(int i=rates_total-first; i>=0; i--)

  {

DaysGone = ( TimeDay(Time[i]) != TimeDay(Time[i+1])  ? DaysGone +  1 : DaysGone );

test[i]=DaysGone ;

  }

return(rates_total);

}



the buffer  "TEST" should count passed days from the start.. however, as more as you scroll to left of chart (i.e. 5 min or 1 hr or etc chart), the number gets to 0, then increases randomly and goes crazy... as more as you scroll the left, the number rises up non-adequately..

 

There is an obvious bug, but it is with your code.

If you scroll to the left of the chart, you load new history.

That affects rates_total and prev_calculated.

But you never reset DaysRolled()

 

and how to code that? 

I am newbie, any help will be appreciated...

how to do that?

So, the whole indicator will misbehave? because my indicator highly depend on the "NewDayStarted" variable, 

and if you say that the variable is not calculated until i scroll left, then it means my whole indicator is blatant?

 
selnomeria:

and how to code that? 

I am newbie, any help will be appreciated...

how to do that?

So, the whole indicator will misbehave? because my indicator highly depend on the "NewDayStarted" variable

and if you say that the variable is not calculated until i scroll left, then it means my whole indicator is blatant?


Are you just trying to detect when a new day starts? If so, there are much easier ways to do that.

Regarding chart history:

If you have never opened a chart up before (i.e. no history for the symbol yet), it will initially load with around 2048 bars.

If you manually scroll back further than the first bar, it will try to load more bars from the broker.

If you keep going, it will stop when you reach the limit provided by your broker, or the limit set in Options > Charts > Max bars in chart (whichever comes first).

 
honest_knave:


Are you just trying to detect when a new day starts?


in my indicator i have complex calculations, like to total sum of volume and price from day to day...


inside logic i have:

Total_Sum = newday_starts ?  Total_Sum + close[i] :  Total_Sum +open[i];


on the last chart bar, the value is divided on the amount of days loaded in chart....


I dont know if it is so hard to understand what i need.

Even ThinkOrSwim has that. 
You load chart, and the function is executed from 1st bar to last bar, no need to scroll left or etc, to load data.



======UPDATE:=======


Thanks for updating your post. NOW I UNDERSTAND WHAT HAPPENS!  

thanks , now everything is clear!


 

let's say:

in comment, there i show the number of days passed from start of chart.


 how can i force indicator to update it's value while scrolling left?

 
selnomeria:

let's say:

in comment, there i show the number of days passed from start of chart.


 how can i force indicator to update it's value while scrolling left?

Check the time of the first (oldest) bar against some statically stored control value and if they are not the same, force a complete recalculation loop (something like this :

   static datetime control_time=0;
          bool force_recalculation = control_time!=time[rates_total-1];
                                     control_time =time[rates_total-1];
   for (int i=(force_recalculation ? rates_total-1 : rates_total-first); i>=0; i--)   
 
selnomeria how can i force indicator to update it's value while scrolling left?
If prev_calculated is zero, reset everything.
 
whroeder1:
If prev_calculated is zero, reset everything.

whoeder1,

how to reset, i am asking that, what is code for that?



Mladen Rakic:

Check the time of the first (oldest) bar against some statically stored control value and if they are not the same, force a complete recalculation loop (something like this :


thanks!!

 

@whroeder1 has a good post explaining how to do lookbacks which should help you understand how to work with prev_calculated and rates_total, now you know that prev_calculated will reset if you load more history.

Forum on trading, automated trading systems and testing trading strategies

Range not behaving as expected

whroeder1, 2016.05.11 18:55

First define your maximum lookback.
int lookback = ... // iMA(period) has look back of period.
                        // buffer[i+2] has look back of 2 (as TimeSeries)
                        // buffer[i-2] has look back of 2 (not TimeSeries)
                       // use maximum of all.
int lookback = ... // iMA(period) has look back of period.
                   // buffer[i+2] has look back of 2 (as TimeSeries)
                   // buffer[i-2] has look back of 2 (not TimeSeries)
                   // use maximum of all.
Old way, counting down as a TimeSeries
   int counted = IndicatorCounted();
   for(int iBar = Bars - 1 - MathMax(lookback, counted); iBar >= 0; --iBar){
      // Timeseries and Indicators Access uses index=iBar
   }
New way, counting down as a TimeSeries (Bars always equals rates_total so can be substituted.)
   for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar){
      // Timeseries and Indicators Access uses index=iBar
      https://docs.mql4.com/series
   }
   return rates_total-1; // Recalculate current bar next tick.

Returning rates_total-1 makes prev_calculated the same as IndicatorCounted().

Alternatively if you return rates_total then must decrement prev_calculated if non-zero at the beginning of On_Calculate to recalculate the current bar.

Always count down so you're not using future values.

New way, counting up, not a TimeSeries.
   set all accessed arrays and buffers to ArraySetAsSeries(false) Not the Predefined Variables

   for(int iBar = MathMax(lookback, prev_calculated; iBar < Bars; ++iBar){
      // To access a Timeseries use index=Bars -1- iBar
      // and convert any results back index=Bars -1- result
   }
   return rates_total-1; // Recalculate current bar next tick.
Always count up so you're not using future values.

Forum on trading, automated trading systems and testing trading strategies

Range not behaving as expected

whroeder1, 2016.07.28 15:25

New way, counting down as a TimeSeries, but not through bar zero.
   #define LAST 1
   for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= LAST; --iBar){
      :
   }
   return rates_total-MathMax(1,LAST); // Recalculate Bar LAST once on new bar.
This can be used to not cover newest bars, or can be used to update the indicator in steps, e.g. 1000-900, 899-799, ... 99-0, 0...




Reason: