Strategy tester

 

Hello,

Bellow function giving always result of 0 in the strategy tester, but is working when loaded on a script.

I do not understand why

Thanks!

double ATR(int index,ENUM_TIMEFRAMES timeframe)
  {

   double atr[];
   double res=0;

   int maxtries = 3;
   int retrycount=0;


   ArraySetAsSeries(atr,true);

   int handle=0;
   while(retrycount <= maxtries)
     {
      handle = iATR(_Symbol,timeframe,14);

      if(handle==INVALID_HANDLE)
        {Sleep(10); retrycount++;}
      else
         break;
     }

   if(handle==INVALID_HANDLE)
     {Print("Handle for ATR failed");  IndicatorRelease(handle); return res=-1;}



   if(CopyBuffer(handle,0,0,3,atr)>0)
      res = atr[index];

IndicatorRelease(handle);
  

   return NormalizeToTickSize(res);
  }
 

What you're trying to do is fundamentally wrong. Even though there's no context of the usage of this function, its design tells us that you're creating a handle to the ATR indicator multiple times inside an EA's OnTick function and then fetching the value at the desired index. There's no need to do that and that may be causing you the error.


1 - the indicator handle should be created only once at the OnInit function. Save this handle in a global variable and work with it - that's why you have the handle.

2 - the same goes to ArraySetAsSeries - create a global variable that will store the values copied by CopyBuffer and call ArraySetAsSeries when handling the Init event. What is better for your EA in terms of performance: calling the same function multiple times when there's no need or calling it only once?

3 - There's also no need to use a while loop and Sleep. If the iATR function returns an invalid handle inside OnInit, the EA should just be removed by returning INIT_FAILED. If you want, however, check why the function failed by calling GetLastError and handle every error case separately - imagine an error that occurs because an invalid parameter was passed to the function. Is it really necessary to try creating the indicator again using the same parameters? It will not work again.

4 - Even though you check if the handle is invalid, you do not print the error code. Call Print with GetLastError, check the error code in the documentation and start to figuring out the problem by this point.

5 - if CopyBuffer returns -1, the error should also be properly handled by printing the last error code and early returning the function. There's (usually) no need to continue the execution flow of that function if no data was copied to the buffer by an error.


If the error persists, show us the error code you're having so we have more information on your issue. 

 

Hi

I agree with what has been said before – handles for indicator should be set in OnInit function. So try something like this:

//declare those variables globally
double atr[];
double res=0;
int handle=0;

//add those functions in OnInit()
ResetLastError();
handle = iATR(_Symbol,timeframe,14);
if(handle==INVALID_HANDLE)
        {Print(„Cannot set ATR handle:”+IntegerToString(GetLastError()));}
      
ArraySetAsSeries(atr,true);

//your new atr function
double ATR(int index,ENUM_TIMEFRAMES timeframe)
  {
        ResetLastError();
if(CopyBuffer(handle,0,index,1,atr)>0) //here you get values from chosen bar (not only from 0-3) 
      res = atr[0];
else Print(“Error getting ATR values: “+IntegerToString(GetLastError()));


   return NormalizeToTickSize(res);
  }

//add this in OnDeinit function

IndicatorRelease(handle);
Best Regards