CopyRates Error 4401 when fetching data for non chart symbol

 

Hello community,

i know this has been discussed already but not really solved so far.


When i make a CopyRates request in onCalculate for a symbol, which is not the chart symbol,

then CopyRates call SOMETIMES returns 4401.


If i recompile my indictor or change timeframe and then back, then CopyRates works fine

on next try again not.


So the data seem to be available , but for some magic reason CopyRates fails sporadically.

How to fix this?


I have saved myself the trouble of adding a code example,

because the description is quite clear. I will be happy to provide one if required.


Thank you for answers.

Documentation on MQL5: Timeseries and Indicators Access / CopyRates
Documentation on MQL5: Timeseries and Indicators Access / CopyRates
  • www.mql5.com
Gets history data of MqlRates structure of a specified symbol-period in specified quantity into the rates_array array. The elements ordering of the...
 
chinaski:

Hello community,

i know this has been discussed already but not really solved so far.


When i make a CopyRates request in onCalculate for a symbol, which is not the chart symbol,

then CopyRates call SOMETIMES returns 4401.


If i recompile my indictor or change timeframe and then back, then CopyRates works fine

on next try again not.


So the data seem to be available , but for some magic reason CopyRates fails sporadically.

How to fix this?


I have saved myself the trouble of adding a code example,

because the description is quite clear. I will be happy to provide one if required.


Thank you for answers.

try to wait until it loads 

consult the following code 

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot PctDelta
#property indicator_label1  "PctDelta"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
  input string otherSymbol="GBPJPY";//other symbol
  input int minBars=6000;//min bars to load 
//--- indicator buffers
  double PctDeltaBuffer[];

bool nativeLoaded=false,otherLoaded=false;
int OnInit()
  {
//--- indicator buffers mapping
  SetIndexBuffer(0,PctDeltaBuffer,INDICATOR_DATA);
  nativeLoaded=false;
  otherLoaded=false;
//---
   return(INIT_SUCCEEDED);
  }

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[])
  {
  if(nativeLoaded&&otherLoaded){


  return(rates_total);
  }else{
  if(SymbolIsSynchronized(_Symbol)){nativeLoaded=true;
  if(SymbolIsSynchronized(_Symbol)){
    //load the other symbol 
      MqlRates otherBars[];
      int loadedBars=CopyRates(otherSymbol,_Period,0,minBars,otherBars);
      if(loadedBars>0){
        Comment("Loaded bars "+IntegerToString(loadedBars));
        if(loadedBars>=minBars){
          //1st calc 
            int from=rates_total-1-minBars;
            int to=rates_total-2;
            for(int i=from;i<=to;i++){
               //find bar in other symbol
                 int f=findInRatesByTime(otherBars,time[i],false);
                 if(f!=-1){
                   double this_change=(close[i]-open[i])/open[i];
                   double that_change=(otherBars[f].close-otherBars[f].open)/otherBars[f].open;
                   PctDeltaBuffer[i]=this_change-that_change;
                   }
               }  
          otherLoaded=true;
          return(rates_total);        
          }
        }
    }}
  }
  return(0);
  }
  
int findInRatesByTime(MqlRates &rates[],
                      datetime toFind, 
                      bool acceptOldest){
int found=-1;
if(ArraySize(rates)>1){
bool ascending=(bool)(rates[0].time<rates[ArraySize(rates)-1].time);
for(int i=0;i<ArraySize(rates);i++){
if(rates[i].time==toFind){found=i;break;}
if(i>0&&ascending&&acceptOldest&&rates[i].time>toFind&&rates[i-1].time<toFind){found=i;break;}
if(i<(ArraySize(rates)-1)&&!ascending&&acceptOldest&&rates[i].time<toFind&&rates[i+1].time>toFind){found=i;break;}
}
}
return(found);
}

 
Thank you for contribution.