Duplicate OnTradeTransaction() event??

 

Hello, I have an EA that uses OrderSendAsync() to send multiple orders in batches and I collect the order ticket #s with code similar to the below code. When the EA only sends 1 order, it's always perfect, but if the EA sends 2 or 3 orders, about 9 times out of 10 everything is normal and I get one alert for each order received. But sometimes, one of the 2 or 3 orders will generate two identical alerts, and when I check it seems like there is no difference between the events that triggered the duplicate alerts, as if the same transaction triggered the OnTradeTransaction twice... Does anyone know why this might be happening? ...and why it only happens about 1 out of 10 times? Thanks

void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) {
        if (trans.type == TRADE_TRANSACTION_REQUEST && request.symbol == _Symbol && request.position == NULL) {
                string alert_str;
                if (result.retcode == 10009) {
                        // order completed
                        alert_str = "COMPLETE";
                } else if (result.retcode == 10010) {
                        // order partially completed
                        alert_str = "PARTIAL COMPLETE";
                } else {
                        // order failed
                        alert_str = "FAILED - Error code: " + (string)result.retcode;
                }
                alert_str = request.symbol + " - Volume: " + DoubleToString(result.volume, 2) + " - Ticket # " + (string)result.order + alert_str;
                Alert(alert_str);
        }
}
Documentation on MQL5: Language Basics / Functions / Event Handling Functions
Documentation on MQL5: Language Basics / Functions / Event Handling Functions
  • www.mql5.com
Event Handling Functions - Functions - Language Basics - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Jeepack:

Hello, I have an EA that uses OrderSendAsync() to send multiple orders in batches and I collect the order ticket #s with code similar to the below code. When the EA only sends 1 order, it's always perfect, but if the EA sends 2 or 3 orders, about 9 times out of 10 everything is normal and I get one alert for each order received. But sometimes, one of the 2 or 3 orders will generate two identical alerts, and when I check it seems like there is no difference between the events that triggered the duplicate alerts, as if the same transaction triggered the OnTradeTransaction twice... Does anyone know why this might be happening? ...and why it only happens about 1 out of 10 times? Thanks

OntradeTransaction is perhaps the least understood handler to implement correctly.

Sending a buy trade request leads to a chain of trade transactions on a trading account: 1) request is accepted for processing, 2) an appropriate purchase order is created for the account, 3) the order is then executed, 4) the executed order is removed from the list of active ones, 5) adding to the history of orders, 6) the subsequent transaction is added to history and 7) a new position is created. All these stages are trade transactions. The arrival of each such transaction to the terminal is the TradeTransaction event. Priority of these transactions' arrival at the terminal is not guaranteed. Thus, you should not expect that one group of transactions will arrive after another one when developing your trading algorithm.


https://www.mql5.com/en/docs/event_handlers/ontradetransaction


Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Вопрос о функции OnTradeTransaction

prostotrader, 2023.04.04 00:29

Good afternoon

Very often, when designing an Expert Advisor, a programmer pays attention to deals - this is not correct.

The order is the source of everything!

Follow the order, everything that happens to it, and you will solve all your problems.

I have been working with asynchronous orders through OnTradeTransaction since 2015 and have never had any problems.


The only way to make it work without going bonkers is to implement it with state based logic.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Вопрос о функции OnTradeTransaction

prostotrader, 2023.04.04 10:04

First, create an order state enum

enum ENUM_ORD_STATE
{
  ORD_NO_STATE   = 0, //ордер не установлен
  ORD_DO_SET     = 1, //отдана команда на установку
  ORD_DO_MODIFY  = 2, //отдана команда на модификацию
  ORD_WORK       = 3, //отложенный ордер "стоит" в стакане
  ORD_DO_CANCEL  = 4  //отдана команда на удаление
};

In OnTradeTransaction, you change the state of the order, checking what happened to the order (partially, completely, rejected, canceled)

Here is a nice function to check order status

https://www.mql5.com/ru/forum/67298/page2#comment_2089220



 
Jeepack:

Hello, I have an EA that uses OrderSendAsync() to send multiple orders in batches and I collect the order ticket #s with code similar to the below code. When the EA only sends 1 order, it's always perfect, but if the EA sends 2 or 3 orders, about 9 times out of 10 everything is normal and I get one alert for each order received. But sometimes, one of the 2 or 3 orders will generate two identical alerts, and when I check it seems like there is no difference between the events that triggered the duplicate alerts, as if the same transaction triggered the OnTradeTransaction twice... Does anyone know why this might be happening? ...and why it only happens about 1 out of 10 times? Thanks

I would suggest you to print ALL structures fields (MqlTradeRequest and MqlTradeResult) to check it's really a duplicate event.

Is it happening on a demo or real account ?

 
Alain Verleyen #:

I would suggest you to print ALL structures fields (MqlTradeRequest and MqlTradeResult) to check it's really a duplicate event.

Is it happening on a demo or real account ?

I already did actually, they are completely identical, and although I said it happens about 1/10th of the time, it's more like 1 out of 5 times... below I will post the results from all the variables in all 3 function parameters so you will see they are identical (MqlTradeTransaction, MqlTradeRequest, MqlTradeResult).

It's happening on a demo account, and it's really 100% a duplicate event when it happens, for no apparent reason because the order has nothing special about it compared to all the other times that it doesn't do this. This doesn't happen when sending only 1 order with OrderSendAsync() but will sometimes happen if I'm sending a batch of 2 or more orders in quick succession.

What I did to solve this is I created an array of tickets that gets reset everytime I change symbol, it adds each ticket the function processes to a list and doesn't process duplicate events if the ticket is already on the list.

// check if ticket was already logged and if not, add it to the list of tickets (this avoids duplicate events created on some orders)
int number_of_tickets = ArraySize(new_tickets);
for (int i = number_of_tickets - 1; i >= 0; i--) {
        if (result.order == new_tickets[i]) {
                // ticket is already logged
                Alert("This is a duplicate ticket");
                return;
        }
}

So now at least I'm not logging duplicate events but I still think it's weird that this would happen and was wondering if it's a known issue or if it's something that I can prevent from happening somehow (other than by keeping a list of logged tickets like I'm doing right now with the above code).

See below for the list of values for every possible item in each parameter:

 
Enrique Dangeroux #:

The only way to make it work without going bonkers is to implement it with state based logic.

I'm just trying to log the first event that confirms my broker has received and processed a new order (the goal being to add the new ticket numbers to my log file) and ignore all other types of events used to modify or close these orders so one simple trick I use is to check if request.position == NULL

Because when setting up a new position that field will be equal to zero but every other event that will modify the orders or close them will always have a ticket number in the request.position field (the ticket for the order the event is modifying).

Also of course I check that trans.type == TRADE_TRANSACTION_REQUEST, this works for my intended purpose.

 
Jeepack #:

I already did actually, they are completely identical, and although I said it happens about 1/10th of the time, it's more like 1 out of 5 times... below I will post the results from all the variables in all 3 function parameters so you will see they are identical (MqlTradeTransaction, MqlTradeRequest, MqlTradeResult).

It's happening on a demo account, and it's really 100% a duplicate event when it happens, for no apparent reason because the order has nothing special about it compared to all the other times that it doesn't do this. This doesn't happen when sending only 1 order with OrderSendAsync() but will sometimes happen if I'm sending a batch of 2 or more orders in quick succession.

What I did to solve this is I created an array of tickets that gets reset everytime I change symbol, it adds each ticket the function processes to a list and doesn't process duplicate events if the ticket is already on the list.

So now at least I'm not logging duplicate events but I still think it's weird that this would happen and was wondering if it's a known issue or if it's something that I can prevent from happening somehow (other than by keeping a list of logged tickets like I'm doing right now with the above code).

See below for the list of values for every possible item in each parameter:

I will check to confirm and report it.
 
Alain Verleyen #:
I will check to confirm and report it.

ok thanks, I'll keep an eye on this thread in case you find anything

Reason: