Получение истории по OrderCloseBy через MQL - страница 4

 

Меня заклинило...  

Открыто два ордера 0,1 лот, бай и селл.

Выполняю код

   Print("-----------------------------");
   
   Print("orsel 0 = ", OrderSelect(0 , SELECT_BY_POS) );
   
   OrderPrint();
   
   int nBuyTicket = OrderTicket();
   
   Print("nBuyTicket= ", nBuyTicket);
   
   
   
   Print("orsel 1 = ", OrderSelect(1 , SELECT_BY_POS) );
   
   OrderPrint();
      
   int nSellTicket = OrderTicket();
   
   Print("nSellTicket= ", nSellTicket);
   
   
   ResetLastError();
   
   Print("closeby= ", OrderCloseBy(nSellTicket, nBuyTicket) );
   
   Print("err= ", GetLastError() );

получаю

0 16:14:56.132 _CloseBy_Open EURUSD,M1: -----------------------------

0 16:14:56.132 _CloseBy_Open EURUSD,M1: orsel 0 = true

0 16:14:56.132 _CloseBy_Open EURUSD,M1: #1504306555 2018.03.15 16:02:19 buy 0.10 EURUSD 1.23353 0.00000 0.00000 1.23292 0.00 0.00 -6.10   23458

0 16:14:56.132 _CloseBy_Open EURUSD,M1: nBuyTicket= 1504306555

0 16:14:56.132 _CloseBy_Open EURUSD,M1: orsel 1 = true

0 16:14:56.132 _CloseBy_Open EURUSD,M1: #1504306574 2018.03.15 16:02:24 sell 0.10 EURUSD 1.23335 0.00000 0.00000 1.23299 0.00 0.00 3.60   23461

0 16:14:56.132 _CloseBy_Open EURUSD,M1: nSellTicket= 1504306574

0 16:14:56.132 _CloseBy_Open EURUSD,M1: closeby= false

0 16:14:56.132 _CloseBy_Open EURUSD,M1: err= 3

0 16:14:56.132 _CloseBy_Open EURUSD,M1: initialized


3

ERR_INVALID_TRADE_PARAMETERS

Неправильные параметры


Какие неправильные параметры ???

 
Dmytro Zelenskyy:

Меня заклинило...  

Открыто два ордера 0,1 лот, бай и селл.

Выполняю код

получаю

0 16:14:56.132 _CloseBy_Open EURUSD,M1: -----------------------------

0 16:14:56.132 _CloseBy_Open EURUSD,M1: orsel 0 = true

0 16:14:56.132 _CloseBy_Open EURUSD,M1: #1504306555 2018.03.15 16:02:19 buy 0.10 EURUSD 1.23353 0.00000 0.00000 1.23292 0.00 0.00 -6.10   23458

0 16:14:56.132 _CloseBy_Open EURUSD,M1: nBuyTicket= 1504306555

0 16:14:56.132 _CloseBy_Open EURUSD,M1: orsel 1 = true

0 16:14:56.132 _CloseBy_Open EURUSD,M1: #1504306574 2018.03.15 16:02:24 sell 0.10 EURUSD 1.23335 0.00000 0.00000 1.23299 0.00 0.00 3.60   23461

0 16:14:56.132 _CloseBy_Open EURUSD,M1: nSellTicket= 1504306574

0 16:14:56.132 _CloseBy_Open EURUSD,M1: closeby= false

0 16:14:56.132 _CloseBy_Open EURUSD,M1: err= 3

0 16:14:56.132 _CloseBy_Open EURUSD,M1: initialized


3

ERR_INVALID_TRADE_PARAMETERS

Неправильные параметры


Какие неправильные параметры ???

Как ни странно, но требует обязательно метку

bool  OrderCloseBy( 
   int        ticket,      // номер ордера для закрытия 
   int        opposite,    // номер противоположного ордера 
   color      arrow_color  // цвет 
   );
 
Alexey Viktorov:

Как ни странно, но требует обязательно метку


Print("closeby= ", OrderCloseBy(nSellTicket, nBuyTicket, clrAqua) );


Все также ошибка  - 3

 

Брокер    а...и  - ошибка  - 3


Брокер    иксэм  -   нет ошибок.


Значит на стороне брокера запрет.


OrderCloseBy  Плохая ф-ция  надо избегать.

 
Dmytro Zelenskyy:

Брокер    а...и  - ошибка  - 3

Брокер    иксэм  -   нет ошибок.

Значит на стороне брокера запрет.

OrderCloseBy  Плохая ф-ция  надо избегать.

Функция сама по себе хорошая, а вот некоторые ДЦ нужно избегать.

Делайте проверку OrderCloseBy,и если дала ошибку, то дальше по коду закрываем обычным способом.

 
Ihor Herasko:

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

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Определение наличия родительского ордера для текущего ордера (по итогам встречного или частичного закрытия)                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetSignOfPartialOrCloseByClose()
{
   string comment = OrderComment();
   if (comment == "")
      return 0;
  
   // Ордер образовался вследствии частичного закрытия
   int fromStart = StringFind(comment, "from #");
   if (fromStart >= 0)
      return GetTicketByPartialClose(comment, fromStart, OrderType(), OrderOpenTime());
  
   // Ордер образовался вследствии встречного закрытия
   if (StringFind(comment, "partial close") >= 0)
   {
      datetime openTime = OrderOpenTime();
      int type = OrderType();
      for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
      {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
            continue;
            
         if (OrderOpenTime() != openTime)
            continue;
            
         if (OrderType() != type)
            continue;
            
         if (StringFind(OrderComment(), "partial close") < 0)
            continue;
            
         return OrderTicket();
      }
   }
  
   return 0;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Получение тикета родительского ордера после частичного закрытия                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetTicketByPartialClose(string comment, int fromStart, int orderType, datetime openTime)
{
   string sTicket = StringSubstr(comment, fromStart + 6);
   int iTicket = (int)StringToInteger(sTicket);
   int type = OrderType();
   if (!OrderSelect(iTicket, SELECT_BY_TICKET))
      return 0;
      
   if (OrderType() == type)                                                                        // Дочерний ордер указывает на родителя - уходим
      return iTicket;
      
   // Дочерний ордер указывает на противоположный ордер. Необходимо искать родительский
   for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
         continue;
        
      if (OrderType() != orderType || OrderOpenTime() != openTime)
         continue;
        
      int iFind = StringFind(OrderComment(), "close hedge by #");
      if (iFind < 0)
         continue;
        
      sTicket = StringSubstr(OrderComment(), iFind + 16);
      int iNewTicket = (int)StringToInteger(sTicket);
      if (iNewTicket != iTicket)
         continue;
        
      return OrderTicket();
   }
  
   return 0;
}


 

Не рабочая функция. После ряда тестов убедился, что при встречном закрытия ордеров разного объёма, комментарий к оставшемуся ордеру может быть разный и не зависящий от выбранной последовательности в OrderCloseBy, разные результаты не только в разных ДС, но и в тестере, логики не прослеживается. Кроме того, комментарии к другим ордерам, в теории, могут также содержать искомую ключевую фразу.  Определять остаточный ордер только по второстепенным характеристикам - объём, время открытия и пр. - опасно, с деньгами работаем, мало ли какая ситуация на счете возникнет и закроем лишние 100 лотов в минус ради того, чтобы сэкономить на спреде. Так что в МТ4 в автоматическом режиме из советника только встречное закрытие равных объёмов, при неудаче - классическое закрытие (в любом случае, даже если функция OrderCloseBy вернет true, после лучше проверить наличие закрываемых ордеров в рынке).

В МТ5 (hedge), например, проще, там остаточная позиция имеет тикет родительской, проблем её закрыть без ошибок нет.

 
Konstantin Efremov:

После ряда тестов убедился, что при встречном закрытия ордеров разного объёма, комментарий к оставшемуся ордеру может быть разный и не зависящий от выбранной последовательности в OrderCloseBy, разные результаты не только в разных ДС, но и в тестере, логики не прослеживается. 

Можете указать, в каких ДЦ тестировали и функции не сработали? Можно в личку, чтобы не посчитали за рекламу.

Причина обращения: