Higher Timeframe Moving Average MQL5

 

Hi, 

I've been coding in MQL4 for a while, and am 'reasonably' good at it. Recently I have switched to MQL5 and having difficulty converting my higher timeframe indicators over.

This is a Higher Timeframe Moving average. I think the issue is I am referencing the shift from the curent timeframe but I cannot see how to fix it.

Any help you could offer would be greatly appreacisted as really racking my brains with this. 

This is what it looks like on the chart: 

https://screenrec.com/share/vDUFsz6J31


Thanks in Advance: 


//+------------------------------------------------------------------+
//|                                                          CB-.mq5 |
//|                                                            Chris |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Chris"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#include <CustomFunctions.mqh>

//+------------------------------------------------------------------+
//| indicator properties                                             |
//+------------------------------------------------------------------+
#property indicator_buffers 2
#property indicator_plots 1

// main line properties
#property indicator_color1 clrRed
#property indicator_label1 "Main"
#property indicator_style1 STYLE_SOLID
#property indicator_type1 DRAW_LINE
#property indicator_width1 1

//+------------------------------------------------------------------+
//|inputs                                                            |
//+------------------------------------------------------------------+

input int                  inpMAPeriod          =  50;               // Period
input ENUM_MA_METHOD       inpMAMethod          =  MODE_EMA;         // Method
input ENUM_APPLIED_PRICE   inpAppliedPrice      =  PRICE_CLOSE;      // Applied Price
input ENUM_TIMEFRAMES      inpTimeFrame         =  PERIOD_CURRENT;   // Timeframe

//+------------------------------------------------------------------+
//| buffers and handles                                              |
//+------------------------------------------------------------------+

// indicator data buffers
double   buffer[];
double   values[];

//handles
int      handle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0, buffer, INDICATOR_DATA);

   ArraySetAsSeries(buffer, true);
   ArraySetAsSeries(values, true);

   handle    =  iMA(Symbol(), inpTimeFrame, inpMAPeriod, 0, inpMAMethod, inpAppliedPrice);

   if(handle == INVALID_HANDLE)
     {
      printf("Failed to create Indicator handles");
      return(INIT_FAILED);
     }
   printf("handles created successfully");


   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[])
  {

//control statement
   int limit   =  rates_total - prev_calculated;
   if(prev_calculated > 0)
      limit++;


//for loop
   for(int i = limit; i < rates_total; i++)
     {
     
      int i_bar_shift = iBarShift(Symbol(), inpTimeFrame, time[i], false);
      datetime i_time = iTime(Symbol(), inpTimeFrame, i_bar_shift);

      double arr_ma[1];

      int copy_buffer = CopyBuffer(handle, 0, i_time, 1, arr_ma);

      buffer[i] = arr_ma[0];
     }

   return(rates_total);
  }
//+------------------------------------------------------------------+
07.01.2023_16.40.13_REC
07.01.2023_16.40.13_REC
  • screenrec.com
Recorded with ScreenRec
 
  1.    for(int i = limit; i < rates_total; i++)
    
          int i_bar_shift = iBarShift(Symbol(), inpTimeFrame, time[i], false);
    
          buffer[i] = arr_ma[0];
    You did not set the time[] array and your buffer[] to match your loop direction. In MT5, you must set the direction.
    To define the indexing direction in the time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[] arrays, call the ArrayGetAsSeries() function. In order not to depend on defaults, call the ArraySetAsSeries() function for the arrays to work with.
              Event Handling / OnCalculate - Reference on algorithmic/automated trading language for MetaTrader 5
  2.    int limit   =  rates_total - prev_calculated;
       if(prev_calculated > 0) limit++;
       for(int i = limit; i < rates_total; i++)

    First run, prev_calculated is zero, therefor limit is rates_total+1 and your loop does nothing.
              How to do your lookbacks correctly #9#14 & #19 (2016)

 

Hi WIlliam, Thanks for your help, greatly appreciated.


I've set my time to ArraySetAsSeries(time, true) now. The Buffer was already set to ArraySeries 'true' at the top in the OnInit() funciton, was that what you were refering to? 

I see what you mean about the limit never being smaller than rates_total; 

If I understand the rest of your post correctly; these 2 components are counting in different directions is that the case?


Thanks 


   if(prev_calculated > 0)
      limit++;


//for loop
   for(int i = limit; i < rates_total; i++)
     {
Reason: