Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXVI): Работа с отложенными торговыми запросами - первая реализация"

 

Опубликована статья Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXVI): Работа с отложенными торговыми запросами - первая реализация:

В статье организуем хранение некоторых данных в значении магического номера ордеров и позиций и приступим к реализации отложенных запросов. Для проверки концепции создадим первый тестовый отложенный запрос на открытие рыночных позиций при получении от сервера ошибки, требующей ожидания и отправки повторного запроса.

Скомпилируем и запустим советник. Отключим любым способом интернет и дождёмся такого значка в правом нижнем углу терминала:



После отключения интернета и нажатия на кнопку Sell, нам торговый сервер возвращает ошибку, и в журнал выводятся записи:

2019.11.26 15:34:48.661 CTrading::OpenPosition<uint,uint>: Invalid request:
2019.11.26 15:34:48.661 No connection with the trade server
2019.11.26 15:34:48.661 Correction of trade request parameters ...
2019.11.26 15:34:48.661 Trading attempt #1. Error: No connection with the trade server

При получении этой ошибки библиотека создаёт отложенный запрос с параметрами, которые были при неудачной попытке открыть короткую позицию.
В отложенном запросе также прописаны количество попыток и время ожидания в 20 секунд.

Затем подключаем интернет, тем самым восстанавливая связь с торговым сервером:


Как только связь восстанавливается, библиотека начинает обрабатывать отложенный запрос, отсылая его на сервер. В результате мы имеем открытую позицию с записями в журнале:

2019.11.26 15:35:00.853 CTrading::OpenPosition<double,double>: Invalid request:
2019.11.26 15:35:00.853 Trading is prohibited for the current account
2019.11.26 15:35:00.853 Correction of trade request parameters ...
2019.11.26 15:35:00.853 Trading operation aborted
2019.11.26 15:35:01.192 CTrading::OpenPosition<double,double>: Invalid request:
2019.11.26 15:35:01.192 Trading is prohibited for the current account
2019.11.26 15:35:01.192 Correction of trade request parameters ...
2019.11.26 15:35:01.192 Trading operation aborted
2019.11.26 15:35:01.942 - Position is open: 2019.11.26 10:35:01.660 -
2019.11.26 15:35:01.942 EURUSD Opened 0.10 Sell #486405595 [0.10 Market-order Sell #486405595] at price 1.10126, sl 1.10285, tp 1.09985, Magic number 17629307 (123), G1: 13
2019.11.26 15:35:01.942 OnDoEasyEvent: Position is open

Как видим из журнала, после восстановления связи с торговым сервером, не сразу включилось разрешение на торговлю для текущего счёта.
Но отложенный запрос-таки сделал своё дело
...

Также в журнале видим реальный магический номер 17629307, за ним в скобочках видим установленный магик в настройках советника (123), плюс видим одну запись G1: 13, которая сообщает нам, что идентификатор первой группы равен 13, а идентификатора второй группы нет — его значение оказалось равным нулю, поэтому не было выведено второй записи с идентификаторм второй группы G2: XX

Автор: Artyom Trishkin

 
  Здравствуйте! Скачал последнюю версию библиотеки и Експерт Part_26, поставил на тестер визуальный режим и рыночные

ордера открываются, а все отложенные нет.

Биржевые символы, брокер Открытие, version 5.00 build 2190.

 
Alexander:
  Здравствуйте! Скачал последнюю версию библиотеки и Експерт Part_26, поставил на тестер визуальный режим и рыночные

ордера открываются, а все отложенные нет.

Биржевые символы, брокер Открытие, version 5.00 build 2190.

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

Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXV): Обработка ошибок, возвращаемых торговым сервером"

Artyom Trishkin, 2019.11.28 09:39

В этой версии библиотеки, равно как и в следующей, я пропустил проверку типов заливки ордеров и типов их экспирации. В следующей (27) статье будут исправления.

Пока могу предложить при отсылке торгового запроса явно указывать тип экспирации. Например, для выставления отложенного ордера Sell Limit, нужно дописать в тестовом советнике:

//--- Если нажата кнопка BUTT_SELL_LIMIT: Выставить SellLimit
else if(button==EnumToString(BUTT_SELL_LIMIT))
  {
   //--- Устанавливаем ордер SellLimit
   engine.PlaceSellLimit(lot,Symbol(),distance_pending,stoploss,takeprofit,magic,TextByLanguage("Отложенный SellLimit","Pending order SellLimit"),0,ORDER_TIME_DAY);
  }

И так сделать во всех строках, в которых есть вызов методов установки отложенных ордеров.


 
Да, спасибо, так заработало.
 

Скажите, пожаулуйста, где конкретно, в каком методе, вы декодируете закодированный magic в отложенном запросе?

У меня после ошибки при открытии позиции (недостаточно средств) и последующему срабатыванию отложенного запроса создается позиция совершенно с другим маджиком (видимо, с тем, что закодирован).

Где вы его декодируете-то? Я хочу родной маджик, а не новый.

 
void CTradingControl::OnPReqByErrCodeHandler()

Вот по идее где-то здесь вы должны вызывать метод, возвращающий первоначальный маджик. И какой метод? GetMagicID()?

 
//+------------------------------------------------------------------+
//| Возвращает профит ордера в пунктах                               |
//+------------------------------------------------------------------+
int COrder::ProfitInPoints(void) const
  {
   MqlTick tick={0};
   string symbol=this.Symbol();
   if(!::SymbolInfoTick(symbol,tick))
      return 0;
   ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)this.TypeOrder();
   double point=::SymbolInfoDouble(symbol,SYMBOL_POINT);
   if(type==ORDER_TYPE_CLOSE_BY || point==0) return 0;
   if(this.Status()==ORDER_STATUS_HISTORY_ORDER)
      return int(type==ORDER_TYPE_BUY ? (this.PriceClose()-this.PriceOpen())/point : type==ORDER_TYPE_SELL ? (this.PriceOpen()-this.PriceClose())/point : 0);
   else if(this.Status()==ORDER_STATUS_MARKET_POSITION)
     {
      if(type==ORDER_TYPE_BUY)
         return int((tick.bid-this.PriceOpen())/point);
      else if(type==ORDER_TYPE_SELL)
         return int((this.PriceOpen()-tick.ask)/point);
     }
   else if(this.Status()==ORDER_STATUS_MARKET_PENDING)
     {
      if(type==ORDER_TYPE_BUY_LIMIT || type==ORDER_TYPE_BUY_STOP || type==ORDER_TYPE_BUY_STOP_LIMIT)
         return (int)fabs((tick.bid-this.PriceOpen())/point);
      else if(type==ORDER_TYPE_SELL_LIMIT || type==ORDER_TYPE_SELL_STOP || type==ORDER_TYPE_SELL_STOP_LIMIT)
         return (int)fabs((this.PriceOpen()-tick.ask)/point);
     }
   return 0;
  }

Здесь почему нет расчета для типа ORDER_STATUS_DEAL ?

В общем, непонятно, как получить профит в пунктах закрытой сделки или позиции...
И это всегда 0:

deal_profit_pts=(int)deal.GetProperty(ORDER_PROP_PROFIT_PT)