Impossible to copyrates of D1 timeframe from within an indicator attached to M1 timeframe

 

I've already put this issue in the profile -> service desk for the developers as an instance, but not recieved any reply, just it was closed.

Can anyone create a simple indicator attached to M1 timeframe but copy the D1 of the previous day bar for instance?

 

It keeps giving error 4401.

 

I have just answered you there and let me repeat it here:

Have you read section Organizing Data Access yet? If we try to get other symbol/timeframe price data (quotes) we have to be ready that requested data are not built at that moment.

We can try to copy by functions CopyXXX() and should check how many bars were copied. If copied bars less than zero it means those data are not ready. In this case the best what we can and should do is waiting for preparing requested data.

We can't use Sleep() into an indicator because an indicator works into terminal thread (and Sleep() is allowed into a script or Expert Advisor) so we should exit from OnCalculate() and try to get data at the next incoming tick. Don't forget to return zero with return, because this value will be set to variable prev_calculation with next OnCalculate() triggering. See also articles  MQL5: Create Your Own Indicator and Applying One Indicator to Another

//+------------------------------------------------------------------+
//|                                                  amir_avatar.mq5 |
//|              Copyright Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"

//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_plots   7
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_label1  "S3"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Red
#property indicator_label2  "S2"
#property indicator_type3   DRAW_LINE
#property indicator_color3  Red
#property indicator_label3  "S1"
#property indicator_type4   DRAW_LINE
#property indicator_color4  Yellow
#property indicator_label4  "PP"
#property indicator_type5   DRAW_LINE
#property indicator_color5  Green
#property indicator_label5  "R1"
#property indicator_type6   DRAW_LINE
#property indicator_color6  Green
#property indicator_label6  "R2"
#property indicator_type7   DRAW_LINE
#property indicator_color7  Green
#property indicator_label7  "R3"

//--- input parameters
input ENUM_TIMEFRAMES   InpPeriod=PERIOD_D1;         // Period

//--- indicator buffers

double               ExtS3LineBuffer[];
double               ExtS2LineBuffer[];
double               ExtS1LineBuffer[];
double               ExtPPLineBuffer[];
double               ExtR1LineBuffer[];
double               ExtR2LineBuffer[];
double               ExtR3LineBuffer[];

double Low[],High[],Close[];
datetime Time[];
MqlDateTime BarTime;
datetime NextBarTime;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//---
   Print("In indicator");
//--- indicator buffers mapping

   SetIndexBuffer(0,ExtS3LineBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtS2LineBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,ExtS1LineBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,ExtPPLineBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,ExtR1LineBuffer,INDICATOR_DATA);
   SetIndexBuffer(5,ExtR2LineBuffer,INDICATOR_DATA);
   SetIndexBuffer(6,ExtR3LineBuffer,INDICATOR_DATA);

//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- sets first bar from what index will be drawn
//PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod);
//---- line shifts when drawing
//PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift);
//--- name for DataWindow
   string short_name="pivots";

   IndicatorSetString(INDICATOR_SHORTNAME,short_name+"("+string(InpPeriod)+")");

//--- Set the line drawing
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(5,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(6,PLOT_DRAW_TYPE,DRAW_LINE);

//---- initialization done
  }
//+------------------------------------------------------------------+
//|  Moving Average                                                  |
//+------------------------------------------------------------------+
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[])
  {

   MqlRates Rate[1],Days[];
   int day_t,DayInChart;
   int first_hist_bar_parm_tf=time[0]/PeriodSeconds(InpPeriod);

//Print("now entered indicator, parm period in seconds = ",PeriodSeconds(InpPeriod));
   int copied=CopyRates(_Symbol,InpPeriod,0,100,Days);
   if(copied<0)
     {
      Print("Daily timeframe is not prepared yet, we will try next time. Now we should exit");
      return(0);
     }
   for(int i=prev_calculated+1;i<rates_total;i++)
     {
      day_t=time[i]/PeriodSeconds(InpPeriod);
      DayInChart=day_t-first_hist_bar_parm_tf;
      //Print("going to copy bar =",DayInChart);
      copied=CopyRates(_Symbol,InpPeriod,DayInChart,1,Rate);
      if(copied>0) Print("i = ",i,"   High["+DayInChart+"] =",Rate[0].high,"   Time =",Rate[0].time);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


 

Rosh, please take a look at that slight modification I made (only in print,see attached) for the indicator you've published.

I put the Print command like this (change in green):

   if(copied>0) Print("i = ",i,"DayInChart= ",DayInChart,"   High["+DayInChart+"] =",Rate[0].high,"   Time[i] =",

    TimeToString(time [i],TIME_DATE|TIME_MINUTES|TIME_SECONDS),"time of copy=",TimeToString(Rate[0].time,TIME_DATE|TIME_MINUTES|TIME_SECONDS));

In order to see both times - the time that should be advanced forward (time[i]) which counts the M1 bars, and the time of the copyrates that should also advance forward based on day calculations. but you can see that it prints - time[i] is moving forward, and Rate[0].time is moving back in time.  None of the vectors is set to ArraySetAsSeries = true (all are false).

 

see - Time[i] is moving in one direction, and time of copy, which should copy the same bars (you can see DayInChart also increases), moves in second direction (from 01.04 back to 04.03) while time[i] is moving in another year, and up from 17.12 to 06.01 - take a look at the greens, in ascending order, and the reds, in descending. Should be that the Copyrates(DayInChart) in same proportion to the time of copy.

2010.04.21 21:44:21 testind (EURUSD,M1) i=28894 DayInChart=34  High[34] = 1.37117  Time[i]=2009.01.06 16:25:00 time of copy=2010.03.04 00:00:00
2010.04.21 21:44:21 testind (EURUSD,M1) i=28878 DayInChart=34  High[34] = 1.37117  Time[i]=2009.01.06 16:09:00 time of copy=2010.03.04 00:00:00
2010.04.21 21:44:21 testind (EURUSD,M1) i=28846 DayInChart=34  High[34] = 1.37117  Time[i]=2009.01.06 15:37:00 time of copy=2010.03.04 00:00:00
2010.04.21 21:44:20 testind (EURUSD,M1) i=13102 DayInChart=14  High[14] = 1.35904  Time[i]=2008.12.17 07:52:00 time of copy=2010.04.01 00:00:00
2010.04.21 21:44:20 testind (EURUSD,M1) i=13086 DayInChart=14  High[14] = 1.35904  Time[i]=2008.12.17 07:36:00 time of copy=2010.04.01 00:00:00
2010.04.21 21:44:20 testind (EURUSD,M1) i=13070 DayInChart=14  High[14] = 1.35904  Time[i]=2008.12.17 07:20:00 time of copy=2010.04.01 00:00:00

 

Files:
testind.mq5  6 kb
 

Actually I think that this is the real reason for me getting 4401 sometimes, and not the absence of bars in history.

I think that the real reason is that it tries to copy the wrong day bars.  

Reason: