Trying to dislocate the iMA but it is not working

 

Hi.

I am trying to develop a HiLo indicator but I am having trouble with the information that comes from the iMA formula. If I try to use 1 at the iMA formula, it does not dislocate the result.

Here is the code. 

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1

//--- plot HiLo
#property indicator_label1  "HiLo"
#property indicator_type1   DRAW_COLOR_ARROW
#property indicator_color1  clrOrangeRed,clrSpringGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- indicator buffers
double         HiLoBuffer[];
double         HiLoColors[];

double ma1[], ma2[];

input int                  periodoHiLo = 13;        //period of ma
input ENUM_MA_METHOD       metodo=MODE_EMA;     // type of smoothing

int mm1, mm2;
bool lado = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,HiLoBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,HiLoColors,INDICATOR_COLOR_INDEX);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(0,PLOT_ARROW,159);   
//---
   return(INIT_SUCCEEDED);
  }
  

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
                
  {  
//---
   // 1 = PRICE_LOW
   // 0 = PRICE_HIGH
   
   mm1 = iMA(Symbol(),Period(),periodoHiLo,1,metodo,PRICE_HIGH);
   mm2 = iMA(Symbol(),Period(),periodoHiLo,1,metodo,PRICE_LOW);
   CopyBuffer(mm1, 0, 0, rates_total, ma1);
   CopyBuffer(mm2, 0, 0, rates_total, ma2);
   
   if(prev_calculated==0)   
     {   
      for(int i=rates_total; i>=10; i--)
      {
         if(lado==1)          
           {
           if(close[rates_total-i] <= ma2[rates_total-i])
             {
             HiLoBuffer[rates_total - i] = ma1[rates_total-i];
             HiLoColors[rates_total - i] = 0;
             lado = 0;
             }
           else
             {
             HiLoBuffer[rates_total - i] = ma2[rates_total-i];
             HiLoColors[rates_total - i] = 1;
             lado = 1;
             }           
           }
           else
           {
           if(close[rates_total - i] >= ma1[rates_total - i])
             {
             HiLoBuffer[rates_total - i] = ma2[rates_total-i];
             HiLoColors[rates_total - i] = 1;
             lado = 1;
             }
           else
             {
             HiLoBuffer[rates_total - i] = ma1[rates_total-i];
             HiLoColors[rates_total - i] = 0;
             lado = 0;
             }
           }
      }
     }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

I know that it is only running when I load the indicator, but the ideia is to make this work, so I can do the other part later

 

1) You are copying the whole indicator buffer on every tick.

2) In MQL 5, close is not a series unlike MQL 4. You need to make up your mind in which order you want to loop through the buffers.

 

On top of what @lippmaje mentioned,

(1) you need to move these lines to OnInit():

   mm1 = iMA(Symbol(),Period(),periodoHiLo,1,metodo,PRICE_HIGH);
   mm2 = iMA(Symbol(),Period(),periodoHiLo,1,metodo,PRICE_LOW);

Because they just need to be executed once, and they need time to complete their work, before you call CopyBuffer().

(2) Then check that this statement is what you want:

   if(prev_calculated==0)   

because with this, coupled with "return (rates_total);" at the end, your indicator will only be executed once at the first tick. 

Fixing (1) and you'll immediately see things being drawn on chart. Fixing (2) as well, and you'll see updates every bar, and fixing @lippmaje's recommendations (together with proper determination of how many bars to compute for every new tick/bar), you'll see improvements in speed.

 

First of all, thanks @lippmaje and @Seng Joo Thio, for your answers.

This is my first indicator, so I am having trouble to understand the construction structure. The idea here is to calculate the history bars on load of the chart. and calculate the actual bar in real time.  Then, when a new bar is started se the value of one that became old now and continue to calculate the new one.

I understood the First point, and changed the mm1 and mm2 to OnInit(), now the second point couldn't get. I don't know about the close. Is the way to return (rates_total - 2) and calculate for this difference?

Reason: