Detecting the begin and end of optimizer in MT4 (code dll inside)

 

I want to share my code for detect the events like MT5 OnTesterInit() or OnTesterDeInit().

Code in MQL4

#import "optimizerControl.dll"
   bool OnTesterInit_MT4();
   void activateOptimizerEnd(string parameters);
#import

int init()
  {
        if (isOptimizerStart())
        {
           // is TRUE only the first pass
        }
      return(0);
   }

int deinit()
  {
    if(IsOptimization())
    {
       activateOptimizerEnd(parameters); // here I send the best results at the moment to the DLL.
    }
    return(0);
  }

The Tester of MT4 only use one thread for the optimizer, when the thread is created, this is the moment for the first pass, and when the current thread finished the optimizer ended.

Code of the dll in asm (compiled with fasm).

format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32ax.inc'

hMutex           dd ?
hEvent           dd ?
hThread          dd ?
hOptimizerThread dd ?

section '.text' code readable executable

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
        mov eax, TRUE
        ret
endp

proc OnTesterInit_MT4
 locals
    mutexID dd ?
    stringID rb  5
 endl
      invoke GetCurrentProcessId
      mov [mutexID], eax
      cinvoke wsprintf, addr stringID, '%i', [mutexID]
      invoke OpenMutex, SYNCHRONIZE, FALSE, addr stringID
      .if eax = 0
         mov eax, 1 ; TRUE ; only the first pass
         ret
      .endif
      invoke CloseHandle, eax
      xor eax, eax ; FALSE
      ret
endp

proc activateOptimizerEnd, parameters
 locals
    stringID rb  5
    mutexID dd ?
 endl

      invoke GetCurrentProcessId
      mov [mutexID], eax
      cinvoke wsprintf, addr stringID, '%i', [mutexID]
      invoke OpenMutex, SYNCHRONIZE, FALSE, addr stringID
      .if eax = 0
         invoke CreateMutex, NULL, FALSE, addr stringID
         mov [hMutex], eax
         invoke GetCurrentThreadId
         mov [hOptimizerThread], eax
         invoke CreateThread, 0, 0, newThread, [parameters], 0, 0
         mov [hThread], eax
         ret
      .endif
      invoke CloseHandle, eax
      ret
endp

proc newThread, parameters
 locals
    hOpenThread dd ?
 endl
; you must save the parameters here for the new information(incomplete)
   invoke OpenThread, SYNCHRONIZE, FALSE, [hOptimizerThread]
   .if eax <> 0
      mov [hOpenThread], eax
      invoke WaitForSingleObject, [hOpenThread], INFINITE; this is waiting for the optimizer finished
      invoke CloseHandle, [hOpenThread]
      invoke CloseHandle, [hMutex]
      stdcall OnTesterDeinit_MT4, [parameters]
   .endif
   invoke CloseHandle, [hThread]
   invoke ExitThread, 0
endp

proc OnTesterDeinit_MT4, parameters

   invoke MessageBox, 0, 'End tester', 'End tester', 0; you must complete the code you want do with the information sended from MQL4
   ret

endp


section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL'

  import kernel,\
         CreateThread, 'CreateThread',\
         CreateMutex, 'CreateMutexA',\
         OpenMutex, 'OpenMutexA',\
         ExitThread, 'ExitThread',\
         CloseHandle, 'CloseHandle',\
         WaitForSingleObject, 'WaitForSingleObject',\
         GetCurrentProcessId, 'GetCurrentProcessId',\
         GetCurrentThreadId, 'GetCurrentThreadId',\
         OpenThread, 'OpenThread'

  import user,\
         MessageBox,'MessageBoxA',\
         wsprintf, 'wsprintfA'

section '.edata' export data readable

  export 'optimizerControl.dll',\
          OnTesterInit_MT4,'OnTesterInit_MT4',\
          activateOptimizerEnd, 'activateOptimizerEnd'

section '.reloc' fixups data readable discardable

The code is incomplete, only is an idea... you must complete.

 

This code is great but i was wondering if you could share the source of isOptimizerStart


Ive never used assembler before, Ive managed to compile and get it running. Just trying to work out how to determ the first pass of the optimisation


Thanks,


BTW this is a really cool way of implementing this, im impressed ;)

 

OK I think i worked it out


In MT4's OnInit call OnTesterInit_MT4 and save the retern value, that will tell you iff its the first pass or not

Reason: