Timeframe Dataset Question

 

Good day to you all.


I have experience coding in other languages so I am not a complete noob. That being said, being so new to MQL5, I know that I am making mistakes and need to learn the proper use and limitations of the language, which I am working on. I am not here looking for code or strategies, those are skills I will be learning on my own as I continue to code and trade. I have deep respect for those of you with a wealth of knowledge and understanding of the language and my purpose here is just to ask for some guidance and advice, please. 


Currently, I am working on an EA which trades on the Crash 1000 Index, M1 timeframe. I have coded a few simple EA's already and I am now attempting to code a more complex strategy. I need to determine whether or not the market is in uptrend or downtrend at the M30 timeframe and H1 timeframe and whether any crossover occurs between the two moving average periods, but from the M1 timeframe. My thought was to use the iMA() function, buffers, handles and CopyBuffer. I read up on the MQL5 Reference about the function. I decided to use the example code in a simple indicator to prove the concept before adapting that code into my EA as a condition. Modifying the iMA() example code, I was able to plot a simple moving average at a period of 17 and a second moving average at a period of 80, in the same chart window on the PERIOD_CURRENT timeframe. I then tried to do the same for the M30 and H1 timeframe and I still see my PERIOD_CURRENT plots on the market window, but the M30 and H1 plots are not visible. This is likely because I receive an error code: 4806.


I did some research on the forums and that code relating to the iMA() function seems to be because iMA() is not happy running multiple timeframes in the same indicator. Which leads me to my question for all of you. What is the best way for me to obtain the M30 and H1 timeframe datasets for use in the M1 timeframe? I want the EA to look at the M3 and H1 timeframe datasets and determine if there is a crossover between the slow period MA and the fast period MA to determine the market trends at those timeframes and to also alert me to a crossover between the two when it occurs. I don't need to plot them, I was only using this as verification that the datasets were being pulled correctly and available for my EA to use.


My code is below, if this helps but I think that I am going about this in the wrong way to begin with. It is just a modified version of the iMA() example anyway.


As I've said, I'd just like some advise or guidance please.


#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots   6

// Current Period SMA plot
#property indicator_label1  "Current Slow Moving Average"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

// Current Period FMA plot
#property indicator_label2  "Current Fast Moving Average"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrLime
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

// M30 Period FMA plot
#property indicator_label3  "M30 Slow Moving Average"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrGreenYellow
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

// M30 Period FMA plot
#property indicator_label4  "M30 Fast Moving Average"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrOrangeRed
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1

// H1 Period FMA plot
#property indicator_label5  "H1 Slow Moving Average"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrGreen
#property indicator_style5  STYLE_SOLID
#property indicator_width5  1

// H1 Period FMA plot
#property indicator_label6  "H1 Fast Moving Average"
#property indicator_type6   DRAW_LINE
#property indicator_color6  clrDarkRed
#property indicator_style6  STYLE_SOLID
#property indicator_width6  1


//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
input group "----- SMA Inputs -----";
input int                  sma_period=80;                   // period of sma plots
input int                  sma_shift=0;                     // shift of sma  plots
input ENUM_MA_METHOD       sma_method=MODE_LWMA;            // type of smoothing of sma plots
input ENUM_APPLIED_PRICE   sma_applied_price=PRICE_CLOSE;   // type of price of sma plots
input group "----- FMA Inputs -----";
input int                  fma_period=17;                   // period of fma plots
input int                  fma_shift=0;                     // shift of fma plots
input ENUM_MA_METHOD       fma_method=MODE_LWMA;            // type of smoothing of fma plots
input ENUM_APPLIED_PRICE   fma_applied_price=PRICE_CLOSE;   // type of price of fma plots

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+

string               symbol=" ";                            // symbol name

// Timeframe variables
ENUM_TIMEFRAMES      period=PERIOD_CURRENT;                 // timeframe of current period
ENUM_TIMEFRAMES      periodm30=PERIOD_M30;                  // timeframe of M30 period
ENUM_TIMEFRAMES      periodh1=PERIOD_H1;                    // timeframe of H1 period


// iMA indicator buffers
double         sma_buffer[];                                // sma current period buffer
double         fma_buffer[];                                // fma current period buffer
double         sma_m30_buffer[];                            // sma M30 period buffer
double         fma_m30_buffer[];                            // fma M30 period buffer
double         sma_h1_buffer[];                             // sma H1 period buffer
double         fma_h1_buffer[];                             // fma H1 period buffer


// iMA indicator handles
int    sma_handle;                                          // sma current period handle
int    fma_handle;                                          // fma current period handle
int    sma_m30_handle;                                      // sma M30 period handle
int    fma_m30_handle;                                      // fma M30 period handle
int    sma_h1_handle;                                       // sma H1 period handle
int    fma_h1_handle;                                       // fma H1 period handle


// Names
string sma_name=symbol;
string fma_name=symbol;
string sma_m30_name=symbol;
string fma_m30_name=symbol;
string sma_h1_name=symbol;
string fma_h1_name=symbol;


// Name of the plots on chart
string sma_short_name;
string fma_short_name;
string sma_m30_short_name;
string fma_m30_short_name;
string sma_h1_short_name;
string fma_h1_short_name;


// Store the number of values in the Moving Average indicators
int    sma_bars_calculated=0;
int    fma_bars_calculated=0;
int    sma_m30_bars_calculated=0;
int    fma_m30_bars_calculated=0;
int    sma_h1_bars_calculated=0;
int    fma_h1_bars_calculated=0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {

// Assign array to indicator buffers
   SetIndexBuffer(0,sma_buffer,INDICATOR_DATA);
   SetIndexBuffer(1,fma_buffer,INDICATOR_DATA);
   SetIndexBuffer(2,sma_m30_buffer,INDICATOR_DATA);
   SetIndexBuffer(3,fma_m30_buffer,INDICATOR_DATA);
   SetIndexBuffer(4,sma_h1_buffer,INDICATOR_DATA);
   SetIndexBuffer(5,fma_h1_buffer,INDICATOR_DATA);


// Add input shift values to the plot
   PlotIndexSetInteger(0,PLOT_SHIFT,sma_shift);
   PlotIndexSetInteger(1,PLOT_SHIFT,fma_shift);
   PlotIndexSetInteger(2,PLOT_SHIFT,sma_shift);
   PlotIndexSetInteger(3,PLOT_SHIFT,fma_shift);
   PlotIndexSetInteger(4,PLOT_SHIFT,sma_shift);
   PlotIndexSetInteger(5,PLOT_SHIFT,fma_shift);


// Determine the symbol the indicator is drawn for
   sma_name=symbol;
   fma_name=symbol;
   sma_m30_name=symbol;
   fma_m30_name=symbol;
   sma_h1_name=symbol;
   fma_h1_name=symbol;


// Delete spaces to the right and to the left of the indicator names
   StringTrimRight(sma_name);
   StringTrimLeft(sma_name);
   StringTrimRight(fma_name);
   StringTrimLeft(fma_name);
   StringTrimRight(sma_m30_name);
   StringTrimLeft(sma_m30_name);
   StringTrimRight(fma_m30_name);
   StringTrimLeft(fma_m30_name);
   StringTrimRight(sma_h1_name);
   StringTrimLeft(sma_h1_name);
   StringTrimRight(fma_h1_name);
   StringTrimLeft(fma_h1_name);


// If symbol input is zero, use the current char symbol as the name
   if(StringLen(sma_name)==0)
     {
      sma_name=_Symbol;
     }
   if(StringLen(fma_name)==0)
     {
      fma_name=_Symbol;
     }
   if(StringLen(sma_m30_name)==0)
     {
      sma_m30_name=_Symbol;
     }
   if(StringLen(fma_m30_name)==0)
     {
      fma_m30_name=_Symbol;
     }
   if(StringLen(sma_h1_name)==0)
     {
      sma_h1_name=_Symbol;
     }
   if(StringLen(fma_h1_name)==0)
     {
      fma_h1_name=_Symbol;
     }


// Create indicator handles
   sma_handle=iMA(sma_name,period,sma_period,sma_shift,sma_method,sma_applied_price);
   fma_handle=iMA(fma_name,period,fma_period,fma_shift,fma_method,fma_applied_price);
   sma_m30_handle=iMA(sma_m30_name,periodm30,sma_period,sma_shift,sma_method,sma_applied_price);
   fma_m30_handle=iMA(fma_m30_name,periodm30,fma_period,fma_shift,fma_method,fma_applied_price);
   sma_h1_handle=iMA(sma_h1_name,periodh1,sma_period,sma_shift,sma_method,sma_applied_price);
   fma_h1_handle=iMA(fma_h1_name,periodh1,fma_period,fma_shift,fma_method,fma_applied_price);


// Check that handles were created successfully. If not, send alert and stop indicator
   if(sma_handle==INVALID_HANDLE)
     {
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  sma_name,
                  EnumToString(period),
                  GetLastError());
     }

   if(fma_handle==INVALID_HANDLE)
     {
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  fma_name,
                  EnumToString(period),
                  GetLastError());
     }

   if(sma_m30_handle==INVALID_HANDLE)
     {
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  sma_m30_name,
                  EnumToString(periodm30),
                  GetLastError());
     }

   if(fma_m30_handle==INVALID_HANDLE)
     {
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  fma_m30_name,
                  EnumToString(periodm30),
                  GetLastError());
     }

   if(sma_h1_handle==INVALID_HANDLE)
     {
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  sma_h1_name,
                  EnumToString(periodh1),
                  GetLastError());
     }

   if(fma_h1_handle==INVALID_HANDLE)
     {
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  fma_h1_name,
                  EnumToString(periodh1),
                  GetLastError());
      return(INIT_FAILED);
     }


// Show the symbol & timeframe the Moving Average indicator is calculated for on the chart
   sma_short_name=StringFormat("SMA (%d)",sma_period);
   fma_short_name=StringFormat("FMA (%d)",fma_period);
   sma_m30_short_name=StringFormat("SMA (%d)",sma_period);
   fma_m30_short_name=StringFormat("FMA (%d)",fma_period);
   sma_h1_short_name=StringFormat("SMA (%d)",sma_period);
   fma_h1_short_name=StringFormat("FMA (%d)",fma_period);


// Name of each individual plot line
   PlotIndexSetString(0,PLOT_LABEL,sma_short_name);
   PlotIndexSetString(1,PLOT_LABEL,fma_short_name);
   PlotIndexSetString(2,PLOT_LABEL,sma_m30_short_name);
   PlotIndexSetString(3,PLOT_LABEL,fma_m30_short_name);
   PlotIndexSetString(4,PLOT_LABEL,sma_h1_short_name);
   PlotIndexSetString(5,PLOT_LABEL,fma_h1_short_name);


// Main name of the indicator on the all the plot lines
   IndicatorSetString(INDICATOR_SHORTNAME,"Crossing MA Check");


// Set the Plot Empty Values to 0.0
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(4,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(5,PLOT_EMPTY_VALUE,0.0);


// Confirm normal initialization of the indicator if it has reached this point with no errors
   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[])
  {

// iMA indicator number of values to copy
   int sma_values_to_copy;
   int fma_values_to_copy;
   int sma_m30_values_to_copy;
   int fma_m30_values_to_copy;
   int sma_h1_values_to_copy;
   int fma_h1_values_to_copy;


// Determine the number of values calculated in the iMA indicator
   int sma_calculated=BarsCalculated(sma_handle);
   int fma_calculated=BarsCalculated(fma_handle);
   int sma_m30_calculated=BarsCalculated(sma_m30_handle);
   int fma_m30_calculated=BarsCalculated(fma_m30_handle);
   int sma_h1_calculated=BarsCalculated(sma_h1_handle);
   int fma_h1_calculated=BarsCalculated(fma_h1_handle);

   if(sma_calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",sma_calculated,GetLastError());
      return(0);
     }

   if(fma_calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",fma_calculated,GetLastError());
      return(0);
     }

   if(sma_m30_calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",sma_m30_calculated,GetLastError());
      return(0);
     }

   if(fma_m30_calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",fma_m30_calculated,GetLastError());
      return(0);
     }

   if(sma_h1_calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",sma_h1_calculated,GetLastError());
      return(0);
     }

   if(fma_h1_calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",fma_h1_calculated,GetLastError());
      return(0);
     }


// Is this the first start of the calculation of the indicator or have the number of values in the iMA indicator changed?
// Is it necessary to re-calculate the indicator values because the price history has changed?
   if(prev_calculated==0 ||
      sma_calculated!=sma_bars_calculated ||
      fma_calculated!=fma_bars_calculated ||
      sma_m30_calculated!=sma_m30_bars_calculated ||
      fma_m30_calculated!=fma_m30_bars_calculated ||
      sma_h1_calculated!=sma_h1_bars_calculated ||
      fma_h1_calculated!=fma_h1_bars_calculated ||
      rates_total>prev_calculated+1)
     {

      // Does the iMABuffer array contain more values than the number of values in the iMA indicator for the symbol/period?
      // If so, we only copy the values we need
      if(sma_calculated>rates_total)
         sma_values_to_copy=rates_total;
      else
         sma_values_to_copy=sma_calculated;
      if(fma_calculated>rates_total)
         fma_values_to_copy=rates_total;
      else
         fma_values_to_copy=fma_calculated;
      if(sma_m30_calculated>rates_total)
         sma_m30_values_to_copy=rates_total;
      else
         sma_m30_values_to_copy=sma_m30_calculated;
      if(fma_m30_calculated>rates_total)
         fma_m30_values_to_copy=rates_total;
      else
         fma_m30_values_to_copy=fma_m30_calculated;
      if(sma_h1_calculated>rates_total)
         sma_h1_values_to_copy=rates_total;
      else
         sma_h1_values_to_copy=sma_h1_calculated;
      if(fma_h1_calculated>rates_total)
         fma_h1_values_to_copy=rates_total;
      else
         fma_h1_values_to_copy=fma_h1_calculated;
     }

   else
     {
      // If it is not the first time the indicator has calculated values since the last OnCalculate() call, no more than one candle has been added
      sma_values_to_copy=(rates_total-prev_calculated)+1;
      fma_values_to_copy=(rates_total-prev_calculated)+1;
      sma_m30_values_to_copy=(rates_total-prev_calculated)+1;
      fma_m30_values_to_copy=(rates_total-prev_calculated)+1;
      sma_h1_values_to_copy=(rates_total-prev_calculated)+1;
      fma_h1_values_to_copy=(rates_total-prev_calculated)+1;
     }


// Fill the iMABuffer array with values of the Moving Average indicator
// If FillArrayFromBuffer returns false, it means the information is not ready yet so cancel operation
   if(!FillArrayFromBuffer(sma_buffer,sma_shift,sma_handle,sma_values_to_copy))
      return(0);
   if(!FillArrayFromBuffer(fma_buffer,fma_shift,fma_handle,fma_values_to_copy))
      return(0);
   if(!FillArrayFromBuffer(sma_m30_buffer,sma_shift,sma_handle,sma_m30_values_to_copy))
      return(0);
   if(!FillArrayFromBuffer(fma_m30_buffer,fma_shift,fma_handle,fma_m30_values_to_copy))
      return(0);
   if(!FillArrayFromBuffer(sma_h1_buffer,sma_shift,sma_handle,sma_h1_values_to_copy))
      return(0);
   if(!FillArrayFromBuffer(fma_h1_buffer,fma_shift,fma_handle,fma_h1_values_to_copy))
      return(0);


// Create the service messages to be displayed on the chart
   string sma_comm=StringFormat("%s ---  Updated current SMA value in the indicator %s: %d",
                                TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                                sma_name,
                                sma_values_to_copy);
   string fma_comm=StringFormat("%s ---  Updated current FMA value in the indicator %s: %d",
                                TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                                fma_name,
                                fma_values_to_copy);
   string sma_m30_comm=StringFormat("%s ---  Updated M30 SMA value in the indicator %s: %d",
                                    TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                                    sma_m30_name,
                                    sma_m30_values_to_copy);
   string fma_m30_comm=StringFormat("%s ---  Updated M30 FMA value in the indicator %s: %d",
                                    TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                                    fma_m30_name,
                                    fma_m30_values_to_copy);
   string sma_h1_comm=StringFormat("%s ---  Updated H1 SMA value in the indicator %s: %d",
                                   TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                                   sma_h1_name,
                                   sma_h1_values_to_copy);
   string fma_h1_comm=StringFormat("%s ---  Updated H1 FMA value in the indicator %s: %d",
                                   TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
                                   fma_h1_name,
                                   fma_h1_values_to_copy);


// Display the service message on the chart
   Comment(sma_comm,
           "\n",fma_comm,
           "\n",sma_m30_comm,
           "\n",fma_m30_comm,
           "\n",sma_h1_comm,
           "\n",fma_h1_comm);


// Record the number of values in the Moving Average indicator
   sma_bars_calculated=sma_calculated;
   fma_bars_calculated=fma_calculated;
   sma_m30_bars_calculated=sma_m30_calculated;
   fma_m30_bars_calculated=fma_m30_calculated;
   sma_h1_bars_calculated=sma_h1_calculated;
   fma_h1_bars_calculated=fma_h1_calculated;


// Return the previously calculated value for the next call
   return(rates_total);
  }

//+------------------------------------------------------------------+
//| Filling indicator buffers from the MA indicator                  |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[],   // indicator buffer of Moving Average values
                         int shift,          // shift
                         int ind_handle,     // handle of the iMA indicator
                         int amount          // number of copied values
                        )
  {

// Reset error code
   ResetLastError();

// Fill a part of the iMABuffer array with values from the indicator buffer from the 0 index. Alert if this fails and quit with zero resul (Indicator not calculated)
   if(CopyBuffer(ind_handle,0,-shift,amount,values)<0)
     {
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      return(false);
     }
// Retun true if successful
   return(true);
  }

//+------------------------------------------------------------------+
//| Indicator deinitialization function                              |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

// Release indicator handles
   if(sma_handle!=INVALID_HANDLE)
      IndicatorRelease(sma_handle);

   if(fma_handle!=INVALID_HANDLE)
      IndicatorRelease(fma_handle);

   if(sma_m30_handle!=INVALID_HANDLE)
      IndicatorRelease(sma_m30_handle);

   if(fma_m30_handle!=INVALID_HANDLE)
      IndicatorRelease(fma_m30_handle);

   if(sma_h1_handle!=INVALID_HANDLE)
      IndicatorRelease(sma_h1_handle);

   if(fma_h1_handle!=INVALID_HANDLE)
      IndicatorRelease(fma_h1_handle);

// Clear the chart after deleting the indicator
   Comment("");
  }