Асинхронная обработка отсылки ордеров. - страница 2

 
скажу крамольную мысль, может быть даже забанят - нужен callback
 
Aleksandr Dziuba #:

Как сделал бы я. 

В MQLRequest запихал бы флаг ORDER_STATE_REQUEST_MODIFY.
Затем в OntradeTransaction проверял бы что транзакция закончилась.
И сбрасывал этот флаг перед следующим изменением.

2024.03.06 19:31:10.387 BAS_v.1.20 (GLH4,M1) OnTradeTransactionORDER_STATE_REQUEST_MODIFY 0
2024.03.06 19:31:10.390 BAS_v.1.20 (GLH4,M1) OnTradeTransactionORDER_STATE_PLACED 0
2024.03.06 19:31:10.771 BAS_v.1.20 (GLH4,M1) OnTradeTransactionORDER_STATE_PLACED 0

Вот как выглядят сигналы транзакции. Почему интересно два раза Placed?

Лучше реализовывать не через TRADE_RETCODE_PLACED, а через TRADE_RETCODE_DONE. PLACED может отмениться.

По крайней мере для MOEX у меня реализовано так.

 
trampampam #:

Лучше реализовывать не через TRADE_RETCODE_PLACED, а через TRADE_RETCODE_DONE. PLACED может отмениться.

По крайней мере для MOEX у меня реализовано так.

Благодарю. Так лучше получается. (надежнее)

 
trampampam #:

Лучше реализовывать не через TRADE_RETCODE_PLACED, а через TRADE_RETCODE_DONE. PLACED может отмениться.

По крайней мере для MOEX у меня реализовано так.

По протоколу смотрю в Retcode. Не всегда передает request_id.
По каким параметрам Вы сравниваете что это именно Ваш запрос выдал TRADE_RETCODE_DONE?

 
Aleksandr Dziuba #:

По протоколу смотрю в Retcode. Не всегда передает request_id.
По каким параметрам Вы сравниваете что это именно Ваш запрос выдал TRADE_RETCODE_DONE?

Это моя ошибка. В общем. На каждую транзакцию свое событие. На  MqlTradeTransaction свое. На MqlTradeResult свое.
А я считал что это комплексное распределение.  И проверял только через  MqlTradeTransaction. 
Поэтому в данный моменте номер транзакции не передавался.  Если каждое событие обрабатывать индивидуально то все работает. 

 
Aleksandr Dziuba #:

По протоколу смотрю в Retcode. Не всегда передает request_id.
По каким параметрам Вы сравниваете что это именно Ваш запрос выдал TRADE_RETCODE_DONE?

Нет. Все таки при отсылке ордера на модификацию при получении кода 10009 (TRADE_RETCODE_DONE) request_id поставляется как 0. Логику не могу понять.
Но наверное это говорит что если ноль то с ордером можно что то дальше делать. 

 
Aleksandr Dziuba:

Всем привет. Поделитесь пожалуйста порядком и методами как Вы работаете с флагами при обработке асинхронного запроса.

Как проверяете к примеру что ордер на модификацию в работ, отправлен и закончен?

Лучше стандартными функциями. 
А то  я совсем запутался.  Вводить свои флаги или нет. 

Спасибо. 

Может быть это поможет

https://www.mql5.com/ru/blogs/post/557544

Отслеживание ордера, после команды OrderSendAsync
Отслеживание ордера, после команды OrderSendAsync
  • www.mql5.com
Отслеживание ордера, после команды OrderSendAsync Михаил | 23 апреля, 2015 В статье рассказывается принцип отслеживания ордера после команды OrderSendAsync, если нет события TradeTransaction
 
prostotrader #:

Может быть это поможет

https://www.mql5.com/ru/blogs/post/557544Благодао

prostotrader #:

Может быть это поможет

https://www.mql5.com/ru/blogs/post/557544

Благодарю. Это вне транзакции реализовано. Здесь вопрос стоял обработка именно транзакции. И как  получилось что по возврату кода  TRADE_RETCODE_DONE не всегда возвращается  request_id. А если есть  request_id то нет ордера в структуре. 

Вот так проверяю что изменение ордера системой отработано. 
заполняю структуры при изменении лимитных ордеров.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MqlTradeResult PrevLimBuyOrderResult,PrevLimSellOrderResult;

//+------------------------------------------------------------------+
//| асинхронная модификация ордера.  
//! возвращает глобальную структуру которую мы сравниваем при последующих тиках
//+------------------------------------------------------------------+
bool OrderModify(const ulong ticket,const double price,const double sl,const double tp,
                 const ENUM_ORDER_TYPE_TIME type_time,const datetime expiration,const double stoplimit,const string comment,MqlTradeResult&resultcode)
  {
//--- check order existence
   if(!OrderSelect(ticket))
      return(false);
//--- clean
//--- объявление и инициализация запроса и результата
   MqlTradeRequest request= {};
   MqlTradeResult  result= {};

   ZeroMemory(request);
   ZeroMemory(result);
//--- setting request
   request.symbol      =OrderGetString(ORDER_SYMBOL);
   request.action      =TRADE_ACTION_MODIFY;
   request.magic       =Expert_MagicNumber;
   request.order       =ticket;
   request.price       =price;
   request.stoplimit   =stoplimit;
   request.sl          =sl;
   request.tp          =tp;
   request.type_time   =type_time;
   request.expiration  =expiration;
   if(comment != "")
      request.comment     =comment;
//--- action and return the result
//--- отправка запроса
   if(!OrderSendAsync(request,result))
     {
      resultcode=result;
      PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
      PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
      return(false);
     }
//--- информация об операции
//   Print("Изменили ордер ",ticket," r.o",result.order," rid=",result.request_id," retc",result.retcode," retce",result.retcode_external);
   resultcode = result;
   return(true);
  }

И обработка ордера в самой транзакции.

// блок обработки изменения ордера.
   if(result.retcode == TRADE_RETCODE_DONE)
     {
      if(PrevLimBuyOrderTicket !=0)
         if(result.order == PrevLimBuyOrderTicket)
           {
            PrevLimBuyOrderResult.request_id =0;
            return;
           }
      if(PrevLimSellOrderTicket !=0)
         if(result.order == PrevLimSellOrderTicket)
           {
            PrevLimSellOrderResult.request_id =0;
            return;
           }
      if(result.request_id == PrevLimBuyOrderResult.request_id)
        {
         PrevLimBuyOrderResult.request_id =0;
         return;
        }
      if(result.request_id == PrevLimSellOrderResult.request_id)
        {
         PrevLimSellOrderResult.request_id =0;
         return;
        }
     }

Может конечно сумбурно. Но работает. 

 
Aleksandr Dziuba #:

По протоколу смотрю в Retcode. Не всегда передает request_id.
По каким параметрам Вы сравниваете что это именно Ваш запрос выдал TRADE_RETCODE_DONE?

В вашем логе не выведен тип транзакции. Поле request_id заполняется только для TRADE_TRANSACTION_REQUEST.

Понятно, что инфы много (в документации или книге), но иначе технологию не освоить.

Учебник по MQL5: Автоматизация торговли / Создание экспертов / Событие OnTradeTransaction
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Событие OnTradeTransaction
  • www.mql5.com
Автоматизация торговли - Программирование на MQL5 для трейдеров - Учебник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Aleksandr Dziuba #:

Не нужен этот request_id. Подтверждение операции передается в структуре транзакции (MqlTradeTransaction), а не в структуре результата (MqlTradeResult).

Сначала проверяете тип транзакции (trans.type). Как только находите TRADE_TRANSACTION_REQUEST - проверяете действие запроса request.action. Находите TRADE_ACTION_MODIFY (для модификации) - смотрите структуру результата (result.retcode). Если retcode == TRADE_RETCODE_DONE - операция завершена успешно. Как-то так.

Это алгоритм работы именно с ордерами на MOEX. С позициями, возможно, как-то иначе.