Execute an existing EA from a script/ea ?

To add comments, please log in or register
Manu
45
Manu  

Hello,

Is it possible run existing EA from a script/ea ?

If so, is it possible to define the ea settings like Pair, Timeframe and parameters ?

Thanks in advance,

Manu

Brian Dee - Random Trader
1760
Brian Dee - Random Trader  

An EA must already be on a chart to read or 'be aware' of anything

You cant refer to an instance of an EA directly but you can set global variables by other EA or script that would change its operations
Or you could change the externs or recompile the EA with different values

If you are just starting, I would Keep It Super Simple

FWIW
-BB-

JC
1590
JC  
BarrowBoy:

If you are just starting, I would Keep It Super Simple

I'd absolutely stick with this recommendation.


However, for completeness, there is a way for an EA/script to initiate an indicator, EA, custom indicator, or script on another chart. But it comes with very serious caveats:

  • The method is fairly likely to break in MT5, and might break before that in future MT4 builds.
  • The second chart has to be open already. I can't see a way for the initiating script/EA to open a new chart. And there must only be one chart for the combination of symbol and timeframe you want to play about with.
  • You get the usual Common/Inputs configuration dialog for the code you're starting (unless you're initiating a script which doesn't have a #property show_inputs or #property show_confirm). You can accept the default settings for the indicator/EA by simulating keyboard events, but that's even less robust.

Personally I wouldn't use the method I'm talking about here. I'd use global variables or something similar instead, as BarrowBoy recommends. However, it is mildly interesting - and less totally perilous - as a way for an EA to run a script on its own chart, with the potential to have what's effectively (a) multi-threading on the same chart, and (b) a special, limited-duration operation which can be done on a timed loop rather than driven by market ticks.

JC
1590
JC  
jjc:

However, for completeness, there is a way for an EA/script to initiate an indicator, EA, custom indicator, or script on another chart. [...]


I suspect nobody cares, but the method for initiating an indicator etc on the same or another chart goes like this:


// Import of functions from User32. If their purpose isn't pretty much immediately

// clear, then documenting it here frankly isn't going to help much. Requires 

// "Allow DLL imports" to be turned on.

#import "user32.dll"

   int RegisterWindowMessageA(string MessageName);

   int PostMessageA(int hwnd, int msg, int wparam, string Name);

   void keybd_event(int VirtualKey, int ScanCode, int Flags, int ExtraInfo);

#import



// The hWnd parameter for all these functions is obtained using WindowHandle().

// For example, an EA/script can get the handle of its own chart using

// WindowHandle(Symbol(), 0). If the EA/script knows that another chart 

// is open, then its handle can be obtained using the known symbol and

// timeframe. Unpredictable behaviour if there are multiple charts for 

// the same symbol and timeframe. AutomaticallyAcceptDefaults clears

// the configuration window for the new indicator/EA/script by simulating

// a press of the Enter key after a small wait. A longer wait might 

// prove to be more robust. None of this is for the faint-hearted...


void StartStandardIndicator(int hWnd, string IndicatorName, bool AutomaticallyAcceptDefaults = false)

{

   int MessageNumber = RegisterWindowMessageA("MetaTrader4_Internal_Message");

   PostMessageA(hWnd, MessageNumber, 13, IndicatorName);

   if (AutomaticallyAcceptDefaults) ClearConfigDialog();

}


void StartCustomIndicator(int hWnd, string IndicatorName, bool AutomaticallyAcceptDefaults = false)

{

   int MessageNumber = RegisterWindowMessageA("MetaTrader4_Internal_Message");

   PostMessageA(hWnd, MessageNumber, 15, IndicatorName);

   if (AutomaticallyAcceptDefaults) ClearConfigDialog();

}


void StartEA(int hWnd, string EAName, bool AutomaticallyAcceptDefaults = false)

{

   int MessageNumber = RegisterWindowMessageA("MetaTrader4_Internal_Message");

   PostMessageA(hWnd, MessageNumber, 14, EAName);

   if (AutomaticallyAcceptDefaults) ClearConfigDialog();

}


void StartScript(int hWnd, string ScriptName, bool AutomaticallyAcceptDefaults = false)

{

   int MessageNumber = RegisterWindowMessageA("MetaTrader4_Internal_Message");

   PostMessageA(hWnd, MessageNumber, 16, ScriptName);

   if (AutomaticallyAcceptDefaults) ClearConfigDialog();

}


void ClearConfigDialog()

{

   Sleep(100);

   keybd_event(13, 0, 0, 0);

}


pfx
88
pfx  
jjc:


I suspect nobody cares, but the method for initiating an indicator etc on the same or another chart goes like this:




Absolutely brilliant any idea how you can PostMessage to remove an indicator?

Paule Panke
123
Paule Panke  

Ok, this topic is old but just for clarification:

The above code can't work because it uses PostMessage instead of SendMessage. PostMessage will not wait for processing of the posted message. Therefore the memory the pointer in lParam is pointing to will already be freed when the message finally is processed, in effect the code will do nothing. "Sometimes" it might work but in fact this way we are forcing a memory access violation (because the memory pointed to is already out of control and may be occupied by something completely different).

To get this to work properly replace every PostMessageA with SendMessageA. Took me some time to find the bug. Read MSDN.


Next step:

How to launch scripts or eas from another application. In that case SendMessage doesn't help because we can't pass string pointers between processes.

Solution: We can assign hotkeys to the relevant scripts/eas and trigger (simulate) a hotkey via Windows messages sent to another process. This way we don't need pointers.

Dejan
4
Dejan  
paulepanke:

Ok, this topic is old but just for clarification:

The above code can't work because it uses PostMessage instead of SendMessage. PostMessage will not wait for processing of the posted message. Therefore the memory the pointer in lParam is pointing to will already be freed when the message finally is processed, in effect the code will do nothing. "Sometimes" it might work but in fact this way we are forcing a memory access violation (because the memory pointed to is already out of control and may be occupied by something completely different).

To get this to work properly replace every PostMessageA with SendMessageA. Took me some time to find the bug. Read MSDN.


Next step:

How to launch scripts or eas from another application. In that case SendMessage doesn't help because we can't pass string pointers between processes.

Solution: We can assign hotkeys to the relevant scripts/eas and trigger (simulate) a hotkey via Windows messages sent to another process. This way we don't need pointers.


It may be old topic, but there's always someone reading.. :)

I've seen your solution for launching scripts from another application and that is exactly what I need. I'm developing an application that should run in a background when MT4 starts and attach the script that I've made to a pair (it doesn't matter which one). I could use your solution for calling the script once MT4 and my app are running but is there a solution for starting a third party application when MT4 starts?

If it turns out that there is something more to say about this I'll open a new topic and post a link to it here!

Thank you for your time, paulepanke! Keep up the good work...

Paule Panke
123
Paule Panke  

How to launch an external application when MT4 starts?

There are at least two solutions:

1) Launch the external application via any of your indicators in the running MT4 instance:

int error = WinExec("myapp.exe", SW_HIDE);       // SW_SHOWNORMAL|SW_HIDE
if (error < 32) {
   Alert("A Windows error occurred");
}

or you can use

int ShellExecuteA(int hWnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd)

Just make sure you execute the function call only once (use for example a global variable as lock/counter) and double check in myapp.exe for an already running instance of it.


2) The more clever solution is to use MT4 events as program execution trigger. Set in "Options" -> "Events" the connect event to an executable file of your choice. When MetaTrader starts and connects, it will execute your program instead of making some noise. This is also a clever way to detect (and react to) disconnect events, ie. relaunching MT4 when a network error occurres. Of course you need to do the same checking for running of multiple instances in your exe.


Hope that helps

Dejan
4
Dejan  
paulepanke:

How to launch an external application when MT4 starts?

There are at least two solutions:

1) Launch the external application via any of your indicators in the running MT4 instance:

or you can use

Just make sure you execute the function call only once (use for example a global variable as lock/counter) and double check in myapp.exe for an already running instance of it.


2) The more clever solution is to use MT4 events as program execution trigger. Set in "Options" -> "Events" the connect event to an executable file of your choice. When MetaTrader starts and connects, it will execute your program instead of making some noise. This is also a clever way to detect (and react to) disconnect events, ie. relaunching MT4 when a network error occurres. Of course you need to do the same checking for running of multiple instances in your exe.


Hope that helps


Wow! Thank you so much, paulepanke! :)

Better solution for me is a solution #2 'cause if a user deattaches the script at some point, it won't start myapp.exe next time MT4 starts, so I need to avoid that somehow! Otherwise I'll need to start the script when MT4 starts, and that script is going to call myapp.exe. So, it's easier to set up an event regardless of the script. If I use an existing event, like you said, I'll have to manage multiple instances of my app. Is there a way to programmatically set up a new event that is going to do just that? Event that checks for an instance of myapp.exe and execute it if it's not running? The idea is that myapp.exe isntalles MT4 and itself during setup, so I can't rely on a user to set up a new event or change existing one after the installation.

Thank you, again, for your time!

Keep up the good work... :)

Paule Panke
123
Paule Panke  

A third way is to execute a script at startup via "terminal-start.ini" and to launch your executable by this script via the above mentioned functions. Just take care that white space around [key] or [value] strings in "terminal-start.ini" is *NOT* allowed (opposite to the ini-functions of the WinAPI).

See the MT4 user guide (Terminal -> Help -> Help Topics -> Tools -> Configuration at Startup).

pansa
577
pansa  

Hallo,paulepanke!

i tested You code for attach a expert to chart -sorry it work not!

give please a samle for attach expert name "profit" to active chart

with a script.

pansa

123
To add comments, please log in or register