Обсуждение статьи "Рецепты MQL5 - обработка события TradeTransaction"

 

Опубликована статья Рецепты MQL5 - обработка события TradeTransaction:

В своей статье я хотел бы познакомить читателя с одним из способов контролировать торговые события средствами MQL5. Сразу хочу сказать, что данной теме были посвящены статьи, например «Обработка торговых событий в эксперте при помощи функции OnTrade()». Но в отличие от упомянутого материала я буду использовать другой обработчик – OnTradeTransaction().

Хотелось бы отметить вот какой момент. В текущей версии языка MQL5 формально есть 14 обработчиков событий клиентского терминала. Причём, у программиста есть возможность создавать свои пользовательские события посредством EventChartCustom() и обрабатывать их с помощью OnChartEvent(). Но нигде в Документации нет упоминания такого термина, как «Событийно-ориентированное программирование» (СОП). Ведь именно с учётом принципов СОП создаётся любая программа в MQL5. Возьмите хотя бы любой шаблон будущего советника, когда на шаге «Обработчики событий для советника» пользователю предлагается сделать свой выбор.

Очевидно, что в MQL5 так или иначе используется механизм событийно-ориентированного программирования. В языке могут присутствовать блоки программы, состоящие из двух частей: выборки события и обработки события. Причём, если речь идёт о событиях клиентского терминала, то программисту доступна только вторая часть - обработчик события. Правда, для некоторых событий есть исключения. К ним относятся таймер и пользовательское событие. Контроль данных событий полностью отдан в руки программиста.

Рис.6. Первый шаблон связок транзакционных типов

Рис.6. Первый шаблон связок транзакционных типов

Автор: Dennis Kirichenko

 

По своему опыту могу сказать что реальная необходимость использовать TradeTransaction возникает при программировании в асинхронном режиме. Жаль что в статье не сказано об этом режиме ни слова.

з.ы. А еще думал "Что рецепты MQL" - фирменное название статей Анатолия. А теперь получается что это не так( 

 

С-4, спасибо за мнение.

C-4:

По своему опыту могу сказать что реальная необходимость использовать TradeTransaction возникает при программировании в асинхронном режиме. Жаль что в статье не сказано об этом режиме ни слова...

Есть разные необходимости и потребности, которые могут быть причиной использования обработчика TradeTransaction. Это тема интересная, надеюсь, что опытные коллеги тоже выскажутся по этому вопросу...

з.ы. А еще думал "Что рецепты MQL" - фирменное название статей Анатолия. А теперь получается что это не так(

Да, признаюсь, что Анатолий  является изобретателем этого цикла статей. Мне он понравился, и я скромно приобщился к циклу :-))

Надеюсь, что Анатолий не против...

 
В статье ещё не успел осветить вопрос частичного выполнения ордера (ORDER_STATE_PARTIAL). Вопрос на засыпку, сколько раз произойдёт вызов обработчика TradeTransaction?
 
denkir:
В статье ещё не успел осветить вопрос частичного выполнения ордера (ORDER_STATE_PARTIAL). Вопрос на засыпку, сколько раз произойдёт вызов обработчика TradeTransaction?

Х.з. По логике обработчик должен сработать столько же раз как и при полном исполнении. Потому что исполнение ордера не дискретное событие, и МТ в процессе исполнения ордера не знает будет он исполнен частично или полностью.

з.ы. К сожалению доставка событий не гарантирована, а сами события работают только в режиме реального времени, что делает их применение ограниченным. Но они крайне полезны для систем основанных на отслеживании состояний, например асинхронных систем или копировщиков торговли. Благодаря событиям можно построить алгоритм без зацикливаний и дополнительных тормозов связанных с ожиданиями события OnTimer.

 
denkir:

...

Надеюсь, что Анатолий не против...

Нет конечно, не против. ) Тем более, что...

C-4:

...

з.ы. А еще думал "Что рецепты MQL" - фирменное название статей Анатолия. А теперь получается что это не так( 

 ...ярлык "Рецепты MQL5" был предложен редакцией MQ, поэтому его может использовать кто-угодно. Главное, чтобы статей в принципе было больше и разных.

 
В справочном руководстве четко говорится, что последовательность НЕ гарантировата!  Если смотреть на исторических данных, то и там последовательность совсем другая. 
 
Спасибо за эту статью. Она очень полезна.
 
Как заставить систему работать?
 
Отличный текст! Я узнал здесь много нового, поздравляю.
 
VikMorroHun #:
Спасибо за эту статью. Она очень полезна.

Привет,

Моя ситуация кажется довольно простой: Я размещаю отложенный ордер (Sell_Stop) и хочу иметь возможность реагировать в случае, если а) отложенный ордер будет исполнен и, наконец, б) открытая позиция будет закрыта либо по стоп-лоссу, либо по цели по прибыли.

Правильно ли я понимаю, что:

  1. когда отложенный ордер был исполнен, я могу получить магическое число , только запросив его из списка позиций, несмотря на то, что параметр "request" функции OnTradeTransaction() содержит поле "magic", например:
    .
             if(!PositionSelectByTicket(trans.position)) {Print(__LINE__," PositionSelectByTicket FAILED ",err());}
             else {      
                OpnPos[sz].mag  = PositionGetInteger(POSITION_MAGIC);
             }   
    

  2. различные типы транзакций таким образом, что я не могу узнать, была ли открыта или закрыта позиция на продажу:
    .
    void OnTradeTransaction(const MqlTradeTransaction& trans,
                            const MqlTradeRequest& request,
                            const MqlTradeResult& result)
      {
    //---
    
    //--- 
       static int counter=0;   // счетчик вызовов OnTradeTransaction() 
       static uint lasttime=0; // время последнего вызова OnTradeTransaction() 
    //--- 
       uint time=GetTickCount(); 
    //--- если последняя транзакция была выполнена более 1 секунды назад, 
       if(time-lasttime>1000) 
         { 
          counter=0; // тогда это новая торговая операция, и счетчик может быть сброшен 
          if(IS_DEBUG_MODE) 
             Print(__LINE__," "," New trade operation dTime",time-lasttime); 
         } 
       Print(__LINE__," ",counter," ",DoubleToString((double(lasttime=time)/1000.0,2)
                ," Tr.Type: ",EnumToString(trans.type)," DL.Type: ",EnumToString(trans.deal_type)
                ," RQ.Type: ",EnumToString(request.type)," RQ.Fill: ",EnumToString(request.type_filling)
             ); 
    Этот Print выдает результат в случае открытия позиции в 01:00:40 и закрытия этой позиции в 10:04:40:
    01:00:40   322 0 81952.76 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_SELL RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81970.73 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_BUY  RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81955.30 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81980.91 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81965.14 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81982.69 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY DL.Type: ORDER_FILLING_FOK // close sell position
    
    01:00:59   322 0 81968.50 Tr.Type: TRADE_TRANSACTION_REQUEST     DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_SELL RQ.Fill: ORDER_FILLING_FOK // open sell position
    
    Звонки выглядят практически одинаково - как так? В 1:00 была открыта продажа - почему здесь 12 ..TYPE_BUY и только 2 TYPE_SELL?
    Почему и что означает request.type = ORDER_TYPE_BUY в случае, если срабатывает sell stop и становится sell (позицией)? Откуда берется _BUY?
Знаете ли вы элегантный способ определить, что позиция была закрыта по стоп-лоссу или цели по прибыли средствами (параметрами) OnTradeTransaction(), не зная, была ли это позиция на продажу или на покупку?