Range not behaving as expected - page 2

To add comments, please log in or register
whroeder1
18071
whroeder1  
When drawing pivots, there is no need to redraw bar zero as the value doesn't change. Unlike a moving average.
        #define REDRAW_BAR_ZERO false           // Don't redraw Bar zero.
        return rates_total - MathMax(REDRAW_BAR_ZERO, iLast);
whroeder1
18071
whroeder1  
Here's how to do the drawing in groups (when the terminal becomes unresponsive on startup.)
   #define LAST 0
   const int   LB_MA    = LengthMMA-1;
   int      iMA     = rates_total - 1 - MathMax(LB_MA, prev_calculated);
   int      iLast   = MathMax(LAST, iMA - 2000);        // Do in groups
   for(; iMA >= iLast; --iMA){
      :
   }  // iMA
//----
   #define REDRAW_BAR_ZERO true     // Redraw Bar zero.
   return rates_total - MathMax(REDRAW_BAR_ZERO, iLast);
whroeder1
18071
whroeder1  
The last line above can be optimized (and must be for MTF version.)
   return   rates_total - REDRAW_BAR_ZERO - iLast;
For multi-timeframe indicators, there are changes.
// Input(s)
extern ENUM_TIMEFRAMES TimeFrame    = PERIOD_CURRENT;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(){
   if(TimeFrame == PERIOD_CURRENT)  TimeFrame   = (ENUM_TIMEFRAMES) _Period;
   if(TimeFrame < _Period) return INIT_PARAMETERS_INCORRECT;
  1. The look back must adjusted when the look back is from a higher TF.
  2. Don't mix apples and oranges
   const int   lookback    = TimeFrame/_Period; // * 1
   int      iBar  =  Rates_total - 1 - MathMax(lookback, prev_calculated);
   #define LAST 0
   int      iLast = MathMax(LAST, iBar - 2000);   // Do in groups
   for(; iBar >= iLast; --iBar){
      int       iTF = iBarShift(NULL, TimeFrame, Time[iBar]);
      double   hiCur    = iHigh(NULL, TimeFrame, iTF)  //High[iBar],  
               hiPre    = iHigh(NULL, TimeFrame, iTF+1); //High[iBar+1];
      :
Redraw bar zero of the higher TF to get the stair step not just the chart's bar zero.
(See images Multi TimeFrame Moving Average or Moving Average Ex from the codebase)
   #define  REDRAW_BAR_ZERO true       // Redraw Bar zero.
   iLast = iBarShift(NULL, 0, Time[iLast] - Time[iLast] % (TimeFrame * 60));
   return   rates_total - REDRAW_BAR_ZERO - iLast;
whroeder1
18071
whroeder1  
Rather then computing iLast (as I did above,) I could "back up" to the last non-zero TimeFrame bar for the stair step effect. Note the dropping the minus one from iBar calculation and changing the for to a while loop, simplify things.
   const int   lookback    = TimeFrame/_Period; // * 1
   int      iBar  = Rates_total - MathMax(lookback, prev_calculated);
   int      iLast = iBar;
   while(iBar > 0){  --iBar;
      int       iTF = iBarShift(NULL, TimeFrame, Time[iBar]);
      if(iTF != 0) iLast = iBar;
      double   hiCur    = iHigh(NULL, TimeFrame, iTF),   //High[iBar],  
      :
   }
   #define  REDRAW_BAR_LAST false      // Don't redraw TF Bar one.
   return   rates_total - REDRAW_BAR_LAST - iLast;
Victor Epand
702
Victor Epand  

The lookback limit works very well for me in MT5 to limit the number of bars drawn by the custom indicator and save resources. However, when a new chart is downloading new data, I can sometimes witness garbled data appearing past bar 1000, which was never filled in by the custom indicator. I know that the indicator didn't fill in those values, as it never looked past 1000 bars, and it cancels if it cannot access any price data yet (downloading a new chart). Where does the garbled data come from? Of course, I found an easy way to fix this, which was to fill all 50,000 bars on the chart with EMPTY_VALUE. That solves the problem. The fix looks like this:

   if (prev_calculated==0) for (j=0; j<rates_total; j++) indicatorBuffer[j]=EMPTY_VALUE;

This works, and is fast because it only has to loop once on the first tick, or only a few times when new data is being downloaded to a new chart. However, it looks a bit messy and has to loop 50,000 bars, or even 500,000 if that many are on the chart. Is there a nicer, cleaner solution for this?

whroeder1
18071
whroeder1  
Victor Epand: I know that the indicator didn't fill in those values, as it never looked past 1000 bars,
  1. >Yes it did. It filled them when there were less than 1K bars on chart. Then newer history came in. Now there are 2K bars with values in the older part.

    Always set buffer values, do not assume that they are empty values.

      while(iBar > 0){  --iBar;
         buffer[iBar] = EMPTY_VALUE;
         :

  2. I never liked those arbitrary look back limits. I use the attached file to process as many bars as possible in 1.5 seconds and then continue periodically(either by time or by tick,) until all bars are done.
12
To add comments, please log in or register