which one is called first OnTick or OnTradeTransaction?

 

Hi,

I want to ask which one of the OnTick() vs OnTradeTransaction() function is called first?

On OnTick() function there's a trailing stop code that will return error if EA can't select the position ticket. On OnTradeTransaction() I will reset the position ticket to 0 if the position is closed. But when I print the result it came out that OnTick() function is called first and OnTradeTransaction() second resulting in printing error message that EA failed to select the closed position number. Here's the log of it:

CS      0       21:15:19.441    Trade   2018.01.02 08:03:40   position modified [#2 buy 0.01 EURUSD 1.20255 sl: 1.20270 tp: 1.20455]
CS      0       21:15:19.443    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:40   CTrade::OrderSend: modify position #2 EURUSD (sl: 1.20270, tp: 1.20455) [done]
CS      0       21:15:19.443    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:40   transaction_type: TRADE_TRANSACTION_REQUEST index #10
CS      0       21:15:19.443    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:40   order ticket: 0, order type: ORDER_TYPE_BUY index #0, order state: ORDER_STATE_STARTED, index #0
CS      0       21:15:19.443    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:40   deal ticket: 0, deal type: 0, deal entry: 0
CS      0       21:15:19.443    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:40   position affected: 0
CS      0       21:15:19.444    Trade   2018.01.02 08:03:59   stop loss triggered #2 buy 0.01 EURUSD 1.20255 sl: 1.20270 tp: 1.20455 [#4 sell 0.01 EURUSD at 1.20270]
CS      0       21:15:19.444    Trades  2018.01.02 08:03:59   deal #3 sell 0.01 EURUSD at 1.20270 done (based on order #4)
CS      0       21:15:19.444    Trade   2018.01.02 08:03:59   deal performed [#3 sell 0.01 EURUSD at 1.20270]
CS      0       21:15:19.444    Trade   2018.01.02 08:03:59   order performed sell 0.01 at 1.20270 [#4 sell 0.01 EURUSD at 1.20270]
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   ERROR - failed to SELECT POSITION to TRAIL STOP  with ticket #2, with error code 4753
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   transaction_type: TRADE_TRANSACTION_DEAL_ADD index #6
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   order ticket: 4, order type: ORDER_TYPE_BUY index #0, order state: ORDER_STATE_STARTED, index #0
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   deal ticket: 3, deal type: 1, deal entry: 0
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   position affected: 2
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   transaction_type: TRADE_TRANSACTION_ORDER_DELETE index #2
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   order ticket: 4, order type: ORDER_TYPE_SELL index #1, order state: ORDER_STATE_FILLED, index #4
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   deal ticket: 0, deal type: 0, deal entry: 0
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   position affected: 2
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   transaction_type: TRADE_TRANSACTION_HISTORY_ADD index #3
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   order ticket: 4, order type: ORDER_TYPE_SELL index #1, order state: ORDER_STATE_FILLED, index #4
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   deal ticket: 0, deal type: 0, deal entry: 0
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   position affected: 2
CS      0       21:15:19.444    Super Scalper EA Master - multi currency (EURUSD,H1)      2018.01.02 08:03:59   ===== BUY POSITION has been closed. Buy ticket # is reset =====

and here's my code for OnTradeTransaction

void OnTradeTransaction(
   const MqlTradeTransaction& trans,
   const MqlTradeRequest&     request,
   const MqlTradeResult&      result) {
   for(int SymbolLoop = 0; SymbolLoop < NumberOfTradeableSymbols; SymbolLoop++) {
      string CurrentSymbol = SymbolArray[SymbolLoop];

      //--- result of trade request execution
      //ulong            lastOrderID   =trans.order;
      //ENUM_ORDER_TYPE  lastOrderType =trans.order_type;
      //ENUM_ORDER_STATE lastOrderState=trans.order_state;

      ENUM_TRADE_TRANSACTION_TYPE trans_type = trans.type;
      //--- type of transaction

      Print("transaction_type: ", EnumToString(trans_type), " index #", trans_type);
      Print("order ticket: ", trans.order, ", order type: ", EnumToString(trans.order_type), " index #", trans.order_type, ", order state: ", EnumToString(trans.order_state), ", index #", trans.order_state);
      Print("deal ticket: ", trans.deal, ", deal type: ", trans.deal_type, ", deal entry: ", HistoryDealGetInteger(trans.deal, DEAL_ENTRY));
      Print("position affected: ", trans.position);


      switch(trans_type) {

      //... when pending order is placed
      case TRADE_TRANSACTION_ORDER_ADD: {

         ENUM_ORDER_TYPE order_type = trans.order_type;
         switch (order_type) {

         //... when order type is buy stop
         case 4:

            switch (trans.order_state) {

            case 1:  // ORDER STATE PLACED
               Print("===== BUY STOP order is placed =====");
               BuyTicket[SymbolLoop] = trans.order;
               break;
            }
         break;

         //... when order type is sell stop
         case 5:

            switch (trans.order_state) {

            case 1:  // ORDER STATE PLACED
               Print("===== SELL STOP order is placed =====");
               SellTicket[SymbolLoop] = trans.order;
               break;
            }
         break;
         }
      }

      case TRADE_TRANSACTION_HISTORY_ADD:

         switch(trans.order_type) {

         case ORDER_TYPE_BUY :
            if(trans.order != trans.position)
               Print("===== SELL POSITION has been closed. Sell ticket # is reset =====");
            SellTicket[SymbolLoop] = 0;
            break;

         case ORDER_TYPE_SELL :
            if(trans.order != trans.position)
               Print("===== BUY POSITION has been closed. Buy ticket # is reset =====");
            BuyTicket[SymbolLoop] = 0;
            break;

         case ORDER_TYPE_BUY_STOP :

            switch(trans.order_state) {

            case ORDER_STATE_FILLED:
               Print("===== BUY STOP IS FILLED =====");
               break;
            }
         break;

         case ORDER_TYPE_SELL_STOP :

            switch(trans.order_state) {

            case ORDER_STATE_FILLED :

               Print("===== SELL STOP IS FILLED =====");
               break;
            }
         break;
         }
      }
   }
}

Is there's a way for the OnTradeTransaction to be called first so that the error could be resolve?

And I also notice there's an error in OnTradeTransaction() documentation in this part. In the documentation index #3 is TRADE_TRANSACTION_DEAL_ADD while when I print it, it return TRADE_TRANSACTION_HISTORY_ADD. Is there a way to fix the documentation?

 ENUM_TRADE_TRANSACTION_TYPE

Identifier

Description

TRADE_TRANSACTION_ORDER_ADD

Adding a new open order.

TRADE_TRANSACTION_ORDER_UPDATE

Updating an open order. The updates include not only evident changes from the client terminal or a trade server sides but also changes of an order state when setting it (for example, transition from ORDER_STATE_STARTED to ORDER_STATE_PLACED or from ORDER_STATE_PLACED to ORDER_STATE_PARTIAL, etc.).

TRADE_TRANSACTION_ORDER_DELETE

Removing an order from the list of the open ones. An order can be deleted from the open ones as a result of setting an appropriate request or execution (filling) and moving to the history.

TRADE_TRANSACTION_DEAL_ADD

Adding a deal to the history. The action is performed as a result of an order execution or performing operations with an account balance.

TRADE_TRANSACTION_DEAL_UPDATE

Updating a deal in the history. There may be cases when a previously executed deal is changed on a server. For example, a deal has been changed in an external trading system (exchange) where it was previously transferred by a broker.

TRADE_TRANSACTION_DEAL_DELETE

Deleting a deal from the history. There may be cases when a previously executed deal is deleted from a server. For example, a deal has been deleted in an external trading system (exchange) where it was previously transferred by a broker.

TRADE_TRANSACTION_HISTORY_ADD

Adding an order to the history as a result of execution or cancellation.

TRADE_TRANSACTION_HISTORY_UPDATE

Changing an order located in the orders history. This type is provided for enhancing functionality on a trade server side.

TRADE_TRANSACTION_HISTORY_DELETE

Deleting an order from the orders history. This type is provided for enhancing functionality on a trade server side.

TRADE_TRANSACTION_POSITION

Changing a position not related to a deal execution. This type of transaction shows that a position has been changed on a trade server side. Position volume, open price, Stop Loss and Take Profit levels can be changed. Data on changes are submitted in MqlTradeTransaction structure via OnTradeTransaction handler. Position change (adding, changing or closing), as a result of a deal execution, does not lead to the occurrence of TRADE_TRANSACTION_POSITION transaction.

TRADE_TRANSACTION_REQUEST

Notification of the fact that a trade request has been processed by a server and processing result has been received. Only type field (trade transaction type) must be analyzed for such transactions in MqlTradeTransaction structure. The second and third parameters of OnTradeTransaction (request and result) must be analyzed for additional data.

Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Transaction Structure
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Transaction Structure
  • www.mql5.com
Trade Transaction Structure - Data Structures - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Luandre Ezra:

Hi,

I want to ask which one of the OnTick() vs OnTradeTransaction() function is called first?

On OnTick() function there's a trailing stop code that will return error if EA can't select the position ticket. On OnTradeTransaction() I will reset the position ticket to 0 if the position is closed. But when I print the result it came out that OnTick() function is called first and OnTradeTransaction() second resulting in printing error message that EA failed to select the closed position number. Here's the log of it:

and here's my code for OnTradeTransaction

Is there's a way for the OnTradeTransaction to be called first so that the error could be resolve?

These are events, your code should not rely on one being executed before the other, you can't never know that. Adjust your logic.

And I also notice there's an error in OnTradeTransaction() documentation in this part. In the documentation index #3 is TRADE_TRANSACTION_DEAL_ADD while when I print it, it return TRADE_TRANSACTION_HISTORY_ADD. Is there a way to fix the documentation?

What error ? There is no index in the documentation.

 
Alain Verleyen #:
These are events, your code should not rely on one being executed before the other, you can't never know that. Adjust your logic.

What error ? There is no index in the documentation.

When I print trade transaction type of a trade it return 3. According to documentation 3 means TRADE_TRANSACTION_DEAL_ADD. I tried to select it but my code never executed. But when I print it #3 means TRADE_TRANSACTION_HISTORY_ADD not DEAL_ADD
 

These are 2 non-related events.

Which ever event is triggered first will be called.

 
I think the question itself is valid, because each executed order should also produce a tick on the market.

So which comes first? Well, I would say the first to take place is the tick, and then the order update event. But this takes place on the server, and should be (most probably) be atomic in it's execution.

But, despite the fact, this would be the actual execution order on the server, has nothing to do with the event backlog of your EA. In an ideal world, it would probably be in exactly this order, but in reality, these processes are asynchronous, and therefore one or the other will come first. And it might not even be consistent over all.

The client terminal will skip tick calls, if the EA is busy and only call the event handlers if the EA is waiting. So maybe you get the transaction event first, and it gets called, while processing, the tick event comes in, and will never call the corresponding handler, because the EA is busy.

In the end, it shouldn't matter, because, you can query the ticks and find "your tick" by the price matching. From there you can do what you want to do...


 
Dominik Egert #:
I think the question itself is valid, because each executed order should also produce a tick on the market.

...

Why is that ?

This is not exact at all.

 
Alain Verleyen #:

Why is that ?

This is not exact at all.

... on the market for assets with real volume. To feed your need for precision.

I was pointing to the fact that execution of the event handlers is not related to the happening sequence on the trade server.

But, Jap, for markets with real volume updates, every deal should be represented with a tick update.
 
Dominik Egert #:
I think the question itself is valid, because each executed order should also produce a tick on the market.

So which comes first? Well, I would say the first to take place is the tick, and then the order update event. But this takes place on the server, and should be (most probably) be atomic in it's execution.

But, despite the fact, this would be the actual execution order on the server, has nothing to do with the event backlog of your EA. In an ideal world, it would probably be in exactly this order, but in reality, these processes are asynchronous, and therefore one or the other will come first. And it might not even be consistent over all.

The client terminal will skip tick calls, if the EA is busy and only call the event handlers if the EA is waiting. So maybe you get the transaction event first, and it gets called, while processing, the tick event comes in, and will never call the corresponding handler, because the EA is busy.

In the end, it shouldn't matter, because, you can query the ticks and find "your tick" by the price matching. From there you can do what you want to do...


So there's really nothing I could do about the error message that comes from OnTick being called first before then the OnTradeTransaction?
 
Never mind, I just create a condition to ignore the first error message. If it's still persist on the next tick then a problem is occurred. If not then it is not an error
 
Luandre Ezra #:
So there's really nothing I could do about the error message that comes from OnTick being called first before then the OnTradeTransaction?
As Alain stated, and I tried to give explanation, these events are independent. You need to deal with it on your side. There is no other consistent way.
Reason: