How can I trigger the EA start() function from within a DLL?

 

I've read a few articles on the subject of calling the MT4 terminal from an external program, but haven't found anything yet that addresses the issue of triggering the start() function without a tick arriving.


What I am trying to do is to 'wake up' the start() function so that it will invoke one of my dll functions, which can then pass it trading instructions. However, I don't want to wait for a tick to arrive - I have a background thread running in my dll that I want to use to wake up the start() function.


What I have tried so far is the following...


In the init() function, I get the window handle, and the 'special' MT4 message id as follows.


int MT4InternalMsg = RegisterWindowMessageA("MetaTrader4_Internal_Message");
HWND hWnd = WindowHandle(Symbol(),Period());


I then pass these values to an initialisation function in my dll where they get stored, and a background thread is spawned.


From within the background thread, I then try to wake up the start() function every 10 seconds using the following code.


#define CHART_CMD_UPDATE_DATA 33324

while(1) {
    PostMessageA(hWnd, WM_COMMAND, CHART_CMD_UPDATE_DATA, 1);
    Sleep(10000);
}


also tried


PostMessageA(hWnd, MT4InternalMsg, CHART_CMD_UPDATE_DATA, 1);

Neither approach has caused the start() function to be driven.


Anyone got an idea on how to do this?

 
mjbrady:

I've read a few articles on the subject of calling the MT4 terminal from an external program, but haven't found anything yet that addresses the issue of triggering the start() function without a tick arriving.

See 'Execute EA without waiting for a tick?'. Successfully triggers start() even at weekends when the market is closed.

 
jjc:

See 'Execute EA without waiting for a tick?'. Successfully triggers start() even at weekends when the market is closed.


My approach is based on that article. However, it is talking about triggering using a script, run in the window, not from an attached DLL. You will see that the code is very similar to mine, apart from the 3rd parm of the PostMessageA call.


I'll try setting parm 3 to the value 2 and see if this makes any difference.


Edit: Just made this change and all works just fine now!! Excellent, thanks for your help.


#include <WinUser32.mqh>

int start()
{
    int MT4InternalMsg = RegisterWindowMessageA("MetaTrader4_Internal_Message");
    int hWnd = WindowHandle(Symbol(),Period());
    PostMessageA(hWnd,MT4InternalMsg,2,1);
    return(0);
}
 
Does one ever get the impression that one is barking up the wrong tree? CB
 

First tick comes.

EA starts loop

while(IsStopped() == false){

//Loop with a query to DLL for permission to continue

while( SimonSays() == false ) Sleep(128);

when true perform your task...

} // while end

.

.

if you can't even wait for one tick to kick things off then write it as a script (which has the disadvantage of not being firmly attached to a chart)

 
phy:

First tick comes.

EA starts loop

while(IsStopped() == false){

//Loop with a query to DLL for permission to continue

while( SimonSays() == false ) Sleep(128);

when true perform your task...

} // while end

.

.

if you can't even wait for one tick to kick things off then write it as a script (which has the disadvantage of not being firmly attached to a chart)

Thanks for the suggestion, but I now have it working as I initially wanted. The basic problem I was trying to solve was where external code (not running within the MQL4 processor) is making trading decisions based on tick information from elsewhere. So, what I wanted to do was trigger (wake up) the start() function when my external component had decided it needed to trade, not when a tick had arrived at start() or a timer had elapsed. In effect, what I am using the terminal for is just to place and close trades, nothing more. I've now got it working, including setting a bool indicator that can be checked in the start() routine to decide whether it has been triggered by a tick, or by the DLL. It all looks just sweet now :-)

 

good deal

 
mjbrady:

My approach is based on that article. However, it is talking about triggering using a script, run in the window, not from an attached DLL. You will see that the code is very similar to mine, apart from the 3rd parm of the PostMessageA call.


I'll try setting parm 3 to the value 2 and see if this makes any difference.


Edit: Just made this change and all works just fine now!! Excellent, thanks for your help.



Hi

i am currently struggling with the same problem, but i don't fully understand how did u manage to do it

do you call the script from withing the dll?


how do u specify within the dll which instance of MT will it wake up?


so far i am forced to use this program here:


http://www.mistigrifx.com/tools/mt4-msfx-tick-sender


but it send ticks to all the instances of MT4 and all the EAs on all the charts

so when u set it to do too often the pc becomes unusable

 
I don't see how this calls an MT function from a DLL. Is it possible to have the DLL call an MT (EA) function? Please show code.
 
mqlPadawan:
I don't see how this calls an MT function from a DLL [...]

It doesn't. The mechanism basically goes as follows: (a) the DLL decides that it wants to be called by MT4, and stores some appropriate state for future handling; (b) the DLL sends the MT4 chart a message telling it to wake up; and (c) the EA on the MT4 chart then polls the DLL, asking for any state which it should be aware of, and acts accordingly. 


In other words: you can't call an MT4 function from a DLL. You can only tell MT4 that it's time to wake up and poll the DLL.  

 

Thanks jjc. It is becoming clearer.

Is there a step by step tutorial for a noob? In fact, I just noticed that https://www.mql5.com/en/forum/108921 nickbilak's IncomingTick.mq4 is actually a Script and not an EA -- "save this code to script". Otherwise, I thought it redundant to register a message on every tick (had it been an EA). Now I'm thinking all I need is a Script because I just need MT to get account info and open and close trades. Similar to mjbrady " In effect, what I am using the terminal for is just to place and close trades, nothing more."

This is what I interpret you to mean (assuming this applies to Scripts as well as EA's):

1) The DLL and/or the Script registers a message that will be used to cooperate. http://msdn.microsoft.com/en-us/library/ms644947(VS.85).aspx RegisterWindowMessage

2) Your (a)

3) Your (b) The DLL sends this message http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx PostMessage

Question 1) What's with the "A" after the above two messages in this thread (RegisterWindowMessageA and PostMessageA)?

Question 2) How does the Script get notified that this message was sent?

4) Your (c) The Script calls a function that was exported from the DLL.

Yes, dumb it down for me please. Especially step 1 and Question 2.

Thanks.

Reason: