How is the back testing that can be tested by: IsTesting() implemented and controlled ? - page 2

 

IsTesting() equivalent for indicators, for who it may find useful:


/**
 * If an indicator currently runs in the Tester.
 *
 * @return bool - TRUE, when Indicator::start() is called from within the Tester,
 *                FALSE otherwise
 */
bool IndicatorIsTesting() {
   GetLastError();
   Sleep(0);
   bool isIndicator = GetLastError() != 0;

   if (isIndicator)
      return(GetCurrentThreadId() != GetUIThreadId());
   return(false);
}




// MQL constants
#define MAX_STRING_LITERAL "..............................................................................................................................................................................................................................................................."


// MQL error codes
#define ERR_INCOMPATIBLE_ARRAYS           4056
#define ERR_INVALID_FUNCTION_PARAMVALUE   4051


// GetAncestor() constants
#define GA_PARENT       1
#define GA_ROOT         2
#define GA_ROOTOWNER    3


// GetWindow() constants
#define GW_HWNDFIRST    0
#define GW_HWNDLAST     1
#define GW_HWNDNEXT     2
#define GW_HWNDPREV     3
#define GW_OWNER        4
#define GW_CHILD        5
#define GW_ENABLEDPOPUP 6


#import "kernel32.dll"
   int  GetCurrentProcessId();
   int  GetCurrentThreadId();
#import "user32.dll"
   int  GetAncestor(int hWnd, int cmd);
   int  GetClassNameA(int hWnd, string lpBuffer, int bufferSize);
   int  GetTopWindow(int hWnd);
   int  GetWindow(int hWnd, int cmd);
   int  GetWindowThreadProcessId(int hWnd, int lpProcessId[]);
#import


/**
 * Return the id of the UI thread.
 *
 * @return int - thread id (not to confuse with the thread handle)
 */
int GetUIThreadId() {
   static int threadId;                                              // static vars must not have an initializer
   if (threadId != 0)
      return(threadId);

   int iNull[];
   threadId = GetWindowThreadProcessId(GetTerminalWindow(), iNull);

   return(threadId);
}


/**
 * Return the main terminal window handle.
 *
 * @return int - handle or 0 in case of errors
 */
int GetTerminalWindow() {
   static int hWnd;                                                  // static vars must not have an initializer
   if (hWnd != 0)
      return(hWnd);

   string terminalClassName = "MetaQuotes::MetaTrader::4.00";

   // WindowHandle()
   if (!IsStopped()) {
      if (!IsTesting() || IsVisualMode()) {
         hWnd = WindowHandle(Symbol(), NULL);                           // may fail in many situations (init(), deinit(), IsStopped() ...)
         if (hWnd != 0) {
            hWnd = GetAncestor(hWnd, GA_ROOT);
            if (GetClassName(hWnd) != terminalClassName) {
               Print("GetTerminalWindow(1)   ERR_RUNTIME_ERROR   wrong top-level window found (class \""+ GetClassName(hWnd) +"\"), hChild originates from WindowHandle()");
               hWnd = 0;
            }
            else {
               return(hWnd);
            }
         }
      }
   }

   // iterate through all top-level windows
   int processId[1], hWndNext=GetTopWindow(NULL), myProcessId=GetCurrentProcessId();

   while (hWndNext != 0) {
      GetWindowThreadProcessId(hWndNext, processId);
      if (processId[0]==myProcessId) /*&&*/ if (GetClassName(hWndNext)==terminalClassName)
         break;
      hWndNext = GetWindow(hWndNext, GW_HWNDNEXT);
   }
   if (hWndNext == 0) {
      Print("GetTerminalWindow(2)   ERR_RUNTIME_ERROR   cannot find terminal window");
      hWnd = 0;
   }
   hWnd = hWndNext;

   return(hWnd);
}


/**
 * Return the specified window's class name.
 *
 * @param  int hWnd - window handle
 *
 * @return string - class name or empty string in case of errors
 */
string GetClassName(int hWnd) {
   int    bufferSize = 255;
   string buffer[]; InitializeStringBuffer(buffer, bufferSize);

   int chars = GetClassNameA(hWnd, buffer[0], bufferSize);

   while (chars >= bufferSize-1) {                                   // buffer to small, let's increase it
      bufferSize <<= 1;
      InitializeStringBuffer(buffer, bufferSize);
      chars = GetClassNameA(hWnd, buffer[0], bufferSize);
   }

   if (chars == 0) {
      Print("GetClassName() ->user32::GetClassNameA()   ERR_WIN32_ERROR");
      return("");
   }

   return(buffer[0]);
}


/**
 * Initialize a string array for use as a char buffer.
 *
 * @param  string buffer[] - array to initialize
 * @param  int    length   - required length of buffer (number of chars to store)
 *
 * @return int - error status
 */
int InitializeStringBuffer(string& buffer[], int length) {
   if (ArrayDimension(buffer) > 1) {
      Print("InitializeStringBuffer(1)  ERR_INCOMPATIBLE_ARRAYS   invalid parameter buffer, too many dimensions = "+ ArrayDimension(buffer));
      return(ERR_INCOMPATIBLE_ARRAYS);
   }
   if (length < 0) {
      Print("InitializeStringBuffer(2)  ERR_INVALID_FUNCTION_PARAMVALUE   invalid parameter length: "+ length);
      return(ERR_INVALID_FUNCTION_PARAMVALUE);
   }

   if (ArraySize(buffer) == 0)
      ArrayResize(buffer, 1);

   buffer[0] = CreateString(length);
   return(0);
}


/**
 * Create a string of the given length.
 *
 * @param  int length
 *
 * @return string
 */
string CreateString(int length) {
   if (length < 0) {
      Print("CreateString()   ERR_INVALID_FUNCTION_PARAMVALUE   invalid parameter length: "+ length);
      return("");
   }

   string newStr = StringConcatenate(MAX_STRING_LITERAL, "");     // we must always dereference MQL string literals.
   int strLen = StringLen(newStr);                                // otherwise pointers to string literals internally may get messed up.

   while (strLen < length) {
      newStr = StringConcatenate(newStr, MAX_STRING_LITERAL);
      strLen = StringLen(newStr);
   }

   if (strLen != length)
      newStr = StringSubstr(newStr, 0, length);
   return(newStr);
}

just for information: i have my own "built-in exception handler" and replaced its calls in the above code with Print() statements.

pp

 
RaptorUK:
I use IsTesting() in my EAs to determine what Error reporting methods I should or shouldn't be using, if ( IsTesting() ) I turn off error reporting via email, email isn't sent from the ST . . . I test all my EAs in the Strategy Tester extensively.
You may want a variation
int init(){
    if (IsTesting() && !IsVisualMode()){    Show.Comments   = false;
                                            Show.Objects    = false;    }
:
You DO want error reporting during visual mode.
 
WHRoeder:
You may want a variation You DO want error reporting during visual mode.
I have error reporting during visual and non visual mode, just not via email.
 
RaptorUK:
I think there is only polite or impolite . . . I don't think one can be excessively polite ;-)

I'm not so sure. Do you know that 'nice' was originally an insult. I believe it was akin to being a bit of a simpleton and that one would respond in a 'very nice and kindly' manner even if the joke was on them and at there expenses or even insulting. The person was too dim witted and slow to know that the had been insulted and not complimented. They would perhaps then insult them further by swaying to others saying something like: 'There now, you can just see how nice he really is!" Followed by laughs by all, including the 'nice one'

Both the Wise One and the Fool can see and are aware of many things that others are not and perhaps may even be completely oblivious to.

So what is the difference between them that makes one revered and the other the object of many a (cruel) joke at there expense and perhaps even scorned?

The Wise One knows when to speak and when to be quiet. The fool does not.

'nuf said.

 
FourX:
Is a Thief and Troll

Please do not feed the troll.

Reason: