How do i ...

 

Hi, i'm a developer looking for goods keywords/code sample/help to be able to :

Each time an order is taken, push the information on a remote server using http. I already have the http stuff, but i didn't find exactly how to catch order management events (open or close a position).

Any help will be appreciated, thanks a lot !

 

Here is an EA that I wote to capture trade events and email them.

Settings are as follows :-

Show_Screen_FeedBack.....comments on the chart showing EA activity & settings.
Show_Account_Detail......places broker, account number and account name in the email subject line. Helps if you trade multiple accounts.
Show_Equity......will provide balance and equity info whenever a trade is closed.

The following 5 settings allow you to select which types of trades you recieve an email about(should be pretty self-explanatory) :-
Show_Market
Show_Pending
Show_Executed_Pend
Show_Closed
Show_Deleted

Expanded_Order_Info......provide some extra data like ticket number and datetime stamp.
Show_Trade_Result......shows number of pips on trade close.
Show_Profit......shows the profit/loss in account currency. Is forced to false if Show_Trade_Result is false.
Mail_Retry......if there is an error sending the email, it will try this many times before giving up. This one may be subject to future revision as I am uncertain how MT4 treats failed email, whether it 'stores' them for future sending, or just ignores it.

Files:
 

Thanks a lot kenny.

Really thanks a lot i just read your script which is very clear.


I'm just a little surprised. Are callbacks not existing in mt4/5 ?

Im' very new in the API, just discovering it.

So there is no callback likes :

* onOrderAsked(what,lots,price)

* onOrderExecuted(what,lots,price)

* onExitTrade(what,lots,price_in,price_out)


I mean, when your script is executed ? every second ? minute ? is there a way to setup frequency ?

Depending on the UT perhaps ?


Michel

 

I'm really surprise that callback events are not implemented in mt4.

It's like a 90's program. Old school loops. Another world lol

 
michel34:

So there is no callback likes : [...] I mean, when your script is executed ?

The start() function of an EA is called on every tick. In effect, it's an onTick() event. Trade placement in MT4 is synchronous, so there is no (need for) something along the lines of onOrderExecuted(). People usually detect trade closure simply by scanning the list of open orders on every tick.

Other key aspects of the MT4 platform which you may also be unaware of: (a) no partial fills; (b) each order is treated as a separate position; (c) each order/position can have a stop-loss and profit-target, as attributes of the order/position rather than as separate orders; (d) order history is held on the broker's server, not in a local database.

The combination of these is a very simple but clever design which has been a major contributing factor to MT4's enormous popularity for building automated systems. The platform trades off relatively small amounts of flexibility in favour of very substantial ease of development.

 

Hi jjc


You said :

"The start() function of an EA is called on every tick. In effect, it's an onTick() event. Trade placement in MT4 is synchronous, so there is no (need for) something along the lines of onOrderExecuted(). People usually detect trade closure simply by scanning the list of open orders on every tick."

Ok. I'll do with that ... It's completely crazy. Why check orders every ticks if nothing append in orders ? From a pure developer point of view it's a CPU consumption for nothing. Does your TV ask your telecommand if you type a particular channel every micro second ? No, the telecommand tell to the TV to change channel when you press a button.

Little question, what mean a tick ? it's seem's that an EA is depending on a chart, this chart is depending on the unit time choosen. If i choose a 5mn graph on eur/usd by example, i'll have one tick every 5 minutes isn't it ?

If it's the case, if i make a trade at 10h01, my script will know it at 10h05 ? i'm right or wrong on this ?


You said :

"Other key aspects of the MT4 platform which you may also be unaware of: (a) no partial fills; (b) each order is treated as a separate position; (c) each order/position can have a stop-loss and profit-target, as attributes of the order/position rather than as separate orders; (d) order history is held on the broker's server, not in a local database."

Ok thanks a lot for all theses informations. Just a question, you said "(d) order history is held on the broker's server". Is there a way to play with messages received/send by/to the broker ? i.e rathern than having a tick loop, perhaps this time there is an event for that, something like "onBrokerMessageReceived/onBrokerMessageSent". So i should be able to intercept messages to check if an order has been really executed by the broker or something like that.


You said :

"The combination of these is a very simple but clever design which has been a major contributing factor to MT4's enormous popularity for building automated systems. The platform trades off relatively small amounts of flexibility in favour of very substantial ease of development."

I know that. In fact i'm a little bit frustrated because MT4 is the leader for that. Strictly from a developer point of view, when things start with "we don't have events handling management", it's like going back programming in quick basic or turbo pascal 10 years ago. Of course, 95% of developments around MT4 is trading strategy based on tick event. 5% not (the script i'm doing don't need to be checked per tick, but only when positions are changing). I'm really surprised and a little bit disapointed. But you know what ? I'm a developer. Developers are never happy ! so don't take it wrong ;)

Thanks for all

 
michel34:

Little question, what mean a tick ? it's seem's that an EA is depending on a chart, this chart is depending on the unit time choosen. If i choose a 5mn graph on eur/usd by example, i'll have one tick every 5 minutes isn't it ?

That's a big question, but one I thought it wasn't necessary to cover. The definition of a tick in MT4 is basically a change in the bid or ask. Therefore, an EA's start() function gets called many times per minute, irrespective of the timeframe of the chart on which it is running. It may help if you think of start() as onBarUpdate(), not as onNewBar().

Ok. I'll do with that ... It's completely crazy. Why check orders every ticks if nothing append in orders ? From a pure developer point of view it's a CPU consumption for nothing.

Not exactly. It means that processing which would otherwise have to happen within the platform, in order to decide whether/when to fire something like an onOrderClose() event, instead gets done in user-side code. It's not the case that MT4 leads to consumption of CPU cycles which don't happen at all on other platforms.

You're arguably not wrong about the broad profile of CPU consumption in this sense, but the bottom line is that there are loads of people on this forum running 10+ instances of MT4 on a single-processor VPS with 512MB of RAM. I have not personally seen any other trading platforms which can approach this level of light footprint. Any inefficiency in checking orders every tick instead of having a platform-driven event model only means a "waste" of a few microseconds per tick, i.e. a couple of times per second. That's vastly outweighed by the efficiency and low resource usage of the MT4 platform, which must partly be a function of its simplicity.

Is there a way to play with messages received/send by/to the broker ?

No.

Incidentally, the key point about order history being held on the broker's server is the implications for disaster-recovery. Unless your EA is fairly unusual in needing to store its own additional state data on disk, this means that you can get up and running on a new computer just by re-downloading MT4 from the broker and installing the .ex4 file(s) for any EA(s) which you use.


Strictly from a developer point of view, when things start with "we don't have events handling management", it's like going back programming in quick basic or turbo pascal 10 years ago.

MT4 does have event handling: start() is effectively an onTick()/onBarUpdate() event. It's just that the platform only has one event. You can then use this to check for other events by writing EA code which, in context, is trivially fast. It may help if you think in terms of an analogy with CISC vs RISC processors. It's not an antiquated design; it's a different design.

MT5 changes almost all of this, by the way. But largely as a knock-on effect of trade placement having to become asynchronous in order to deal with futures and equities, not because the design of MT4 was a mistake.

 
jjc:

The definition of a tick in MT4 is basically a change in the bid or ask.

More accurately - a Tick is a change in any one of the 28 market information identifiers (available via MarketInfo() function). In practice more than 99% of the ticks are due to changes in MODE_BID and MODE_ASK...


[...] Any inefficiency in checking orders every tick instead of having a platform-driven event model only means a "waste" of a few microseconds per tick, i.e. a couple of times per second. That's vastly outweighed by the efficiency and low resource usage of the MT4 platform, which must partly be a function of its simplicity.

I second this when it comes to live/demo trading. But when it comes to back-testing, some of the overhead involved with the need to manually scan the order pools for changes can be a real problem.

 

Thanks a lot for all theses answers.

 

gordon wrote >>

But when it comes to back-testing, some of the overhead involved with the need to manually scan the order pools for changes can be a real problem.

Here's how I sped things up, only process new ticks if needed.
//+------------------------------------------------------------------+
//| Skip useless ticks                                               |
//+------------------------------------------------------------------+
double  modify.below,   modify.above;                       // Start only
void CallAgain(double when) {
    if (when>Bid)   modify.above = MathMin(modify.above, when);
    else            modify.below = MathMax(modify.below, when);
    return;
}
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
bool    newBar;                                                         // ModifyStops
int start() {                   static datetime Time0;
    newBar = Time[0] > Time0;   if (newBar) {   Time0 = Time[0];
    // update ema's etc here.
    }
    if (newBar || Bid < modify.below || Bid > modify.above) {
        modify.below        = 0;        // Don't call me again until next
        modify.above        = 99999;    // bar except in special cases.
        // Check for open orders, trailing stops, etc, open new order...
    }
}
void modifyStops() {
    //...
    for(int index = OrdersTotal() - 1; index >= 0; index--) if (
        OrderSelect(index, SELECT_BY_POS)     // Only my orders w/
    &&  OrderMagicNumber()  == MagicNumber    // my magic number
    &&  OrderSymbol()       == Symbol() ) {   // and period and symbol
        //...
        orderModify( ... TP.new, SL.new ...)
        CallAgain(TP.new); CallAgain(SL.new);
        
For example if you want to open or close orders on an ema cross, you compute the price where they will cross:
    double  EMAfast.now = EMAfast + EMAfast.Alpha * (Bid - EMAfast),
            EMAslow.now = EMAslow + EMAslow.Alpha * (Bid - EMAslow),
            EMAsCross   =((EMAslow.Alpha-1)*EMAslow     // Where EMAs cross.
                         -(EMAfast.Alpha-1)*EMAfast
                         )/(EMAslow.Alpha-EMAfast.Alpha);
    CallAgain(EMAsCross);
 
WHRoeder:
Here's how I sped things up, only process new ticks if needed.
For example if you want to open or close orders on an ema cross, you compute the price where they will cross:

Have I get it right,  WHRoeder...

From what I can tell, this 'method' is not modular. Does this have more advantage(s) ? Thanks...

Reason: