ФОРТС Установка, удаление и модификация ордера

 

Добрый день.

Хочу понять как происходит установка и отмена отложенного ордера в режиме биржевого исполнения на ФОРТС.

В документации на OrderSend речь идёт про "торговый сервер", а не про биржу.


Вопрос №1 про отмену лимитного ордера.

Отправляю запрос типа TRADE_ACTION_REMOVE (удалить). Функция OrderSend передаёт в result код возврата TRADE_RETCODE_DONE (выполнено).

Означает ли это, что лимитный ордер 100% удалён с биржи?

Или смысл ответа трактуется примерно так "запрос выполнен, идёт процесс удаления заявки с биржи"?


Вопрос №2 про выставление лимитного ордера. Собственно такой же.

Если OrderSend в result сообщила TRADE_RETCODE_PLACED.

Отложенный ордер 100% уже на бирже?

Не на промежуточном сервере, а именно на бирже!

Или, например, даже после такого реткода у ордера может быть состояние типа статуса ORDER_STATE_STARTED или ещё что.


Сильно не пинайте, из документации мне действительно не очевидно.

Пытался выяснить экспериментально - запутался ещё больше.

Решил что в коде буду ждать 100% подтверждение. Когда в списке истории ордер появится с отметкой "отменён".

Стараюсь продумать архитектуру кода так, чтобы не долбить лишними запросами сервер. У меня идёт учёт ордеров и есть метод Is(), который отвечает на вопрос "есть ли ордер в объекте?" без опроса сервера (удобно из сигнальной части эксперта задавать подобные вопросы на каждый тик). Переучёт ордеров и позиции происходит на события OnTrade(). То есть на тиках стараюсь не вызывать ничего типа OrderSelect.

Если ждать ордер в списке истории, то у меня возникает конфликт. Сразу после TRADE_RETCODE_DONE ордера больше нет (а я не уверен, что наверняка), но до подтверждения ордер учитывается как "есть". Тогда возникают повторные попытки удалить "не существующее" на новых тиках. Это не круто.

Спасибо.

 

Добрый день!

Давайте, сначала, проясним, что Вы имеете ввиду Отложенный ордер

И хорошо бы посмотреть код, которым Вы устанавливаете ордер 

 
Михаил:

Добрый день!

Давайте, сначала, проясним, что Вы имеете ввиду Отложенный ордер

Приказ оформляю примерно так:

   req.action      =TRADE_ACTION_PENDING;         // Тип выполняемого действия (Установить отложенный ордер)
   req.type_filling=ORDER_FILLING_RETURN;         // Тип исполнения (исполниять до полного набора позиции)
   req.type_time   =ORDER_TIME_DAY;               // Время действия ордера (до конца дня)
   req.type        =ORDER_TYPE_SELL_LIMIT;        // лимитник на продажу
или
   req.type        =ORDER_TYPE_BUY_LIMIT;         // лимитник на покупку
Кстати, ещё один вопрос: почему-то у меня всегда отвергается ордер до отмены (ORDER_TIME_GTC). На ФОРТС это норма? Или только на демо-счёте так?
 
Fry:

Приказ оформляю примерно так:

Кстати, ещё один вопрос: почему-то у меня всегда отвергается ордер до отмены (ORDER_TIME_GTC). На ФОРТС это норма? Или только на демо-счёте так?

Не поддерживается брокером.

 

Вот так правильно устанавливать отложенный ордер:

//+------------------------------------------------------------------+
//| Place order                                                      |
//+------------------------------------------------------------------+
void PlaceOrder( const double price, const double volume, const bool buy_sell )
{
  MqlTradeRequest request = {0};
  MqlTradeResult  result  = {0};
  ticket = 0;
    
//--- Fill structure
  request.action = TRADE_ACTION_PENDING;
  request.magic  = 123456789;
  request.symbol = _Symbol;
  request.volume = volume;
  request.price  = price;
    
  if ( buy_sell )
  {
    request.type = ORDER_TYPE_BUY_LIMIT;
  }
  else
  {
    request.type = ORDER_TYPE_SELL_LIMIT;
  } 
  request.comment = "Отложенный ордер...";      
  request.type_filling = ORDER_FILLING_RETURN;
  request.type_time = ORDER_TIME_DAY;
  
//--- Send order
  if ( OrderSend( request, result ) )
  {
    if ( result.retcode == TRADE_RETCODE_PLACED ) 
    {
      ticket= result.order;
    }
  }
  else
  {
    Print( "Ордер не установлен! " + _Symbol );
  }
}
 
Пожалуста, удалите Ваше сообщение из темы Вопросы по исполнению
 
Михаил:

Добрый день!

Давайте, сначала, проясним, что Вы имеете ввиду Отложенный ордер

И хорошо бы посмотреть код, которым Вы устанавливаете ордер 

Я бы показал код, но у меня его очень много (в разных файлах куча производных методов).

В конечном итоге всё сводится к базовому методу такого вида:

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Отправляет торговый запрос на сервер
 Предварительно нужна полная инициализация структуры торгового запроса req.

 false означает критическую ошибку действий бота и, метод выставит try=-1 для немедленного стопаута.
 (далее надо искать ошибку в коде)
 

 А вот true на выходе вовсе не означает успешный результат!
 Однозначно успешный результат, можно определить последующим вызовом IsSuccessRetcode()
 Но если всё-таки IsSuccessRetcode()=false, значит ордер откланён сервером и 
 для дальнейшего анализа результата целесообразно использовать следующие методы:
               IsRepeatRetcode  () - реткоды допускающие цикличный повтор запроса
               IsChangeRetcode  () - неактуальные действия (что-то изменилось. Например, ордер мог исполнится, позиция могла закрыться...)
               IsNoTradeRetcode () - внешние запреты (по разным причинам именно сейчас нельзя торговать)
               IsNoChangeRetcode() - бесполезное действие

 
 !!! (следующее утверждение надо проверить) !!!
 Даже при IsSuccessRetcode() ордер может быть ещё не принят к исполнению 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
bool CTradeBase::OSend(MqlTradeResult &result)
{
  
   if(req.action!=TRADE_ACTION_REMOVE)
   {
      MqlTradeCheckResult checkres; ZeroMemory(checkres);
      bool check=OrderCheck(req,checkres);
      b.retcode=checkres.retcode;                                    // результат проверки запроса
      if(!check)
      {
         b.try=-1;
         Alert(__FUNCTION__+": критическая ошибка! Структура торгового запроса не прошла проверку. (",checkres.comment,")");
         return(false);
      }
      // если совсем плохой реткод после проверки
      if(IsFatalRetcode())
      {
         b.try=-1;
         Alert(__FUNCTION__+": критическая ошибка торгового запроса. OrderCheck() сообщила плохой реткод - (",RetCodeToString(checkres.retcode),")");
         return(false);
      }
   }
      
   // отправляем брокеру запрос
   bool noneed=OrderSend(req,result);
   b.retcode=result.retcode;                                     // результат отправки запроса
   Print("Cервер сообщил (",RetCodeToString(),").");


   // возможно запрос отвергнут, надо анализировать реткод
   // если совсем плохой реткод после отправки
   if(IsFatalRetcode())
   {
      b.try=-1;
      Alert(__FUNCTION__+": ошибка в торговом запросе. OrderSend() сообщила плохой реткод - (",b.retcode,")");
      return(false);
   }
   return(true);

И ещё один момент. Я вообще не анализирую переменную "noneed" (возврат из OrderSend).

Она здесь только чтобы компилятор не ругался. Весь анализ возврата построен на реткодах. Это правильно?

 
Михаил:

Не поддерживается брокером.

Спасибо. Теперь ясно.
 
Fry:

Я бы показал код, но у меня его очень много (в разных файлах куча производных методов).

В конечном итоге всё сводится к базовому методу такого вида:

И ещё один момент. Я вообще не анализирую переменную "noneed" (возврат из OrderSend).

Она здесь только чтобы компилятор не ругался. Весь анализ возврата построен на реткодах. Это правильно?

Да, на реткодах.

Кстати, Вы не первый, кто "наступает на грабли", используя Стандартную библиотеку на ФОРТС.

Настоятельно рекомендую не делать этого, не поленитесь, напишите всё сами. 

 
Михаил:

Да, на реткодах.

Кстати, Вы не первый, кто "наступает на грабли", используя Стандартную библиотеку на ФОРТС.

Настоятельно рекомендую не делать этого, не поленитесь, напишите всё сами. 

Спасибо. Пишу всё сам. Эти грабли уже давно позади.

 
Fry:

Спасибо. Пишу всё сам. Эти грабли уже давно позади.

Спрашивайте здесь, что будет не понятно...
Причина обращения: