unable to copy the values

samjesse

Active Trader
Aug 30, 2011
118
0
27
Hi
I often get

Unable to copy the values of the indicator. Error 4806
in the M1 chart and not on other charts.

MQL5:
void SOMECLASS::populate(void)
{
      int copied=CopyRates(_symbol, _period, 0, bars, myRates); 
      if(copied<=0) Print("Error copying price data ",GetLastError());
      stoHandle = iStochastic(_symbol, _period, 34, 3, 9, MODE_SMA, STO_CLOSECLOSE);
      copied=CopyBuffer(stoHandle, 0, 0, bars, stochBuffer);
      if(copied<=0) 
      {
         Alert("Unable to copy the values of the indicator. Error = ", GetLastError(),",  copied =",copied);
      }
}
 
Last edited by a moderator:

Enivid

Administrator
Staff member
Nov 30, 2008
18,532
1,355
144
Odesa
www.earnforex.com
If the CopyBuffer() function is called too early after initialization it may copy no data because indicator data is not yet ready. Try calling it in the second occurrence of the OnCalculate(), not the first, if this is an indicator.
 

samjesse

Active Trader
Aug 30, 2011
118
0
27
would this create a side effect problem?
i.e. what are the cases when this would result in infinite loop?

MQL5:
   //--- Change this vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
   copied=CopyBuffer(stoHandle, 0, 0, bars, stochBuffer);
   if(copied<=0)
   {
      Alert("Unable to copy the values of the indicator. Error = ", GetLastError(),",  copied =",copied);
   }
 
   //--- To this  vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
   int copied;
   while(copied<=0) copied=CopyBuffer(stoHandle, 0, 0, bars, stochBuffer);
 
Last edited by a moderator:

samjesse

Active Trader
Aug 30, 2011
118
0
27
I noticed from the this code that Sleep(1000) does not really wait 1 second. before the next loop.

Am I doing something wrong?

thx


MQL5:
 for(uchar i=0; i<10; i++)
   {
      int copied=CopyBuffer(stoHandle, 0, 0, bars, stochBuffer);
      if(copied<=0) 
      {
         Sleep(1000);
         Print("sleeping "+i);
      } 
      else 
      {
         i=10;
         Print("copied");
      }
 
Last edited by a moderator:

Enivid

Administrator
Staff member
Nov 30, 2008
18,532
1,355
144
Odesa
www.earnforex.com
If that's an indicator, just don't alert the error. I do it like this:

MQL5:
myMA = iMA(NULL, 0, 1, 0, MODE_SMA, AppliedPrice);
if  (CopyBuffer(myMA, 0, rates_total - shift - 1, Len, MAB) != Len) return(0);

You'll know about the error - the indicator just won't draw.
 
Last edited:

samjesse

Active Trader
Aug 30, 2011
118
0
27
If that's an indicator, just don't alert the error. I do it like this:

MQL5:
myMA = iMA(NULL, 0, 1, 0, MODE_SMA, AppliedPrice);
if  (CopyBuffer(myMA, 0, rates_total - shift - 1, Len, MAB) != Len) return(0);

You'll know about the error - the indicator just won't draw.

no. I need its value for further coding.
 
Last edited by a moderator:

samjesse

Active Trader
Aug 30, 2011
118
0
27
If the CopyBuffer() function is called too early after initialization it may copy no data because indicator data is not yet ready. Try calling it in the second occurrence of the OnCalculate(), not the first, if this is an indicator.

Is there a way to Sleep(); after OnInit() and before OnCalculate? in order to fix this problem?

The reason is, it is not that simple to do CopyBuffer() after one tick given the logic of my code. why?

I have a class object as a Global variable where the constructor calls the populate() for a myRates array and creates iStochastic and does the CopyBuffer() we are dealing with.
OnInit() does nothing with the code except deal with house keeping for plotting and the like.
OnCalculate() recalls the populate() conditionally based on chart bars behavior.

so withing for the "second" tick to CopyBuffer() will need a bit of work, specially when I have to deal with "at the beginning of OnCalculate().

last_bar_time = SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
if(new_bar_time == last_bar_time) return(rates_total); else new_bar_time = last_bar_time;

since the above 2 lines will never let me have the second tick to do CopyBuffer().
 
Last edited:

Enivid

Administrator
Staff member
Nov 30, 2008
18,532
1,355
144
Odesa
www.earnforex.com
Don't do such things in a constructor if you declare the objects in global scope. It will never work properly. Do the parameters of iStochastic() change during your code execution? If not, it's better to call it only once on the initialization phase. CopyBuffer() for that indicator should be called after initialization (in OnCalculate(), OnTick() or OnEvent()).
 

samjesse

Active Trader
Aug 30, 2011
118
0
27
Do the parameters of iStochastic() change during your code execution?

It depends.
The new bars received may set off a condition which requires re-calculation of the iStochastic.

so what do you suggest?

leave the object in a global scope and call the iStochastic and CopyBuffer if condition met?
or place the object in the OnCalculate() scope and let the constructor do the iStochastic and CopyBuffer, and recreate the object when condition met?
 
Last edited:

Enivid

Administrator
Staff member
Nov 30, 2008
18,532
1,355
144
Odesa
www.earnforex.com
I'd leave the object in global scope, iStochastic() call in method that's called inside OnInit() and whenever a change in input parameters is required, CopyBuffer() call in method that's called in OnCalculate() (or a similar function).
 

samjesse

Active Trader
Aug 30, 2011
118
0
27
iStochastic() call in method that's called inside OnInit() and whenever a change in input parameters is required,.

But the the conditions change as new bars are in, so a new iStochastic needs to be re-calculated, how can that be done when iStochastic() is called from OnInit()?
 

Enivid

Administrator
Staff member
Nov 30, 2008
18,532
1,355
144
Odesa
www.earnforex.com
But the the conditions change as new bars are in, so a new iStochastic needs to be re-calculated, how can that be done when iStochastic() is called from OnInit()?
No, you should have some class method that calls iStochastic() and call that method first from OnInit(). Then you can call this method again from any other place when the parameters need to be changed.