Закрытие советником ЧУЖОЙ позиции

 

Один советник MQL5 запущен на разных парах. Фрагмент кода (некоторые функции переделаны из MQL4, например, RefreshRates) 

input int ErrAnz = 10;
input int SleepZeit = 3000;

int cnt = 0, i = 0, k = 0;

   for (cnt = PositionsTotal() - 1; cnt >= 0; cnt--)
   {
      RefreshRates();
      
      for (k = 0; k < ErrAnz; k++)
      {
         string s = PositionGetSymbol(cnt);
         if (s == "")
         {
            Print(DoubleToString(k + 1, 0) + ". Versuch: OrderSelect (Schliessen der Order bei TP - " + DoubleToString(cnt, 0) + ") failed with error #",GetLastError());
         }
         else
         {
            break;
         }
         Sleep(SleepZeit);
         RefreshRates();
      }
      
      if (k >= ErrAnz)
      {
         Print("OrderSelect (Schliessen der Order bei TP - " + DoubleToString(cnt, 0) + ") failed with error");
         continue;
      }
      
      if (CompareDoubles(PositionGetDouble(POSITION_TP), TPBuy) || CompareDoubles(PositionGetDouble(POSITION_TP), TPSell)) // Kennzeichen fuer MTC
      {
              if (PositionGetInteger(POSITION_TYPE) <= ORDER_TYPE_SELL &&   //  ORDER_TYPE_BUY oder ORDER_TYPE_SELL 
                       PositionGetString(POSITION_SYMBOL) == Symbol())  // Order fuer die richtige Waerung
              {
            if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && isCloseBUY) //Bid() - NormalizeDouble( PositionGetDouble(POSITION_PRICE_OPEN), Digits()) >= TP * Points)
            {
               Print("OrderClose TP BUY #" + DoubleToString(PositionGetInteger(POSITION_TICKET), 0) + " Bid()(" + DoubleToString(Bid(), Digits())  + " OrderOpenPrice(" + DoubleToString(NormalizeDouble( PositionGetDouble(POSITION_PRICE_OPEN), Digits()), Digits())); 
               
               orderBUYSTOP = 888;
               Print("**** TP: orderBUYSTOP = 888");
               
               for (k = 0; k < ErrAnz; k++)
               {
                  ZeroMemory(request); 
                  request.action   =TRADE_ACTION_DEAL;        // Typ der Transaktion
                  request.position =PositionGetTicket(cnt);          // das Ticket der Position
                  request.symbol   =PositionGetString(POSITION_SYMBOL);          // Symbol 
                  request.volume   =PositionGetDouble(POSITION_VOLUME);                   // das Volumem der Position
                  request.deviation=5;                        // zulässige Abweichung vom Preis
                  request.magic    =PositionGetInteger(POSITION_MAGIC);             // MagicNumber der Position
                  request.price=SymbolInfoDouble(PositionGetString(POSITION_SYMBOL),SYMBOL_BID);
                  request.type =ORDER_TYPE_SELL;
                  ZeroMemory(result); 
                  isKorrekt = OrderSend(request,result); 
               
                  //isKorrekt = m_trade.PositionClose( m_position.Ticket(), 50);
                  if (!isKorrekt)
                  {
                     Print((string)(j + 1) + ". Versuch: OrderClose TP BUY #" + DoubleToString(PositionGetInteger(POSITION_TICKET), 0) + " failed with error #",GetLastError());
                  }
                  else
                  {
                     break;
                  }
                  Sleep(SleepZeit);
                  RefreshRates();
               }
               
               if (k >= ErrAnz)
               {
                  Print("OrderClose TP BUY #" + DoubleToString(PositionGetInteger(POSITION_TICKET), 0) + " failed with error");
                  continue;
               }
            }

К моменту проблемы открыты две позиции на покупку по NZDCAD и EURUSD. Советник на паре NZDCAD выдает ДВА раза подряд приказ на закрытие ОДНОЙ и той же позиции.

MI      0       14:40:23.714    ase_StableIncome (NZDCAD,D1)    OrderClose TP BUY #1045223519 Bid()(0.88693 OrderOpenPrice(0.88638
KI      0       14:40:23.714    ase_StableIncome (NZDCAD,D1)    **** TP: orderBUYSTOP = 888
KR      0       14:40:23.834    ase_StableIncome (NZDCAD,D1)    OrderClose TP BUY #1045223519 Bid()(0.88692 OrderOpenPrice(0.88638
JQ      0       14:40:23.834    ase_StableIncome (NZDCAD,D1)    **** TP: orderBUYSTOP = 888
GF      0       14:40:23.892    ase_StableIncome (NZDCAD,D1)    9. Versuch: OrderClose TP BUY #1045223519 failed with error #4756

Закрываются ОБЕ позиции и по  NZDCAD и по  EURUSD.

NG      0       14:40:23.835    Trades  '': market sell 0.02 NZDCAD, close #1045223519 buy 0.02 NZDCAD 0.88638
GK      0       14:40:23.873    Trades  '': deal #1034479237 sell 0.02 NZDCAD at 0.88692 done (based on order #1045253488)
JF      2       14:40:23.892    Trades  '': failed market sell 0.02 NZDCAD [Position doesn't exist]
DQ      0       14:40:24.244    Notifications   notification 'added order #1045253488 sell 0.02 NZDCAD at market' sent to '7B70F742'
NQ      0       14:40:24.359    Notifications   notification 'deal #1034479237 sell 0.02 NZDCAD at 0.88692 done, profit: 0.73 EUR, based on order #1045253488 sell 0.02 NZDCAD at market' sent to '7B70F742'
PG      0       14:40:24.514    Notifications   notification 'request failed market sell 0.02 NZDCAD [Position doesn't exist]' sent to '7B70F742'
OH      0       14:40:26.887    Trades  '': market sell 0.02 EURUSD, close #1045223811 buy 0.02 EURUSD 1.17196
GI      0       14:40:26.927    Trades  '': accepted market sell 0.02 EURUSD, close #1045223811 buy 0.02 EURUSD 1.17196
DN      0       14:40:26.947    Trades  '': market sell 0.02 EURUSD, close #1045223811 buy 0.02 EURUSD 1.17196 placed for execution
HS      0       14:40:26.973    Trades  '': order #1045253505 sell 0.02 / 0.02 EURUSD at market done in 86.110 ms
EP      0       14:40:26.978    Trades  '': deal #1034479254 sell 0.02 EURUSD at 1.17064 done (based on order #1045253505)
NN      0       14:40:27.168    Notifications   notification 'added order #1045253505 sell 0.02 EURUSD at market' sent to '7B70F742'
LP      0       14:40:27.237    Notifications   notification 'deal #1034479254 sell 0.02 EURUSD at 1.17064 done, profit: -2.26 EUR, based on order #1045253505 sell 0.02 EURUSD at market' sent to '7B70F742'

Вопросы.

1. Почему советник выдает ДВА приказа на закрытие подряд (ведь в цикле идет проверка на имя пары)?

PositionGetString(POSITION_SYMBOL) == Symbol()

2. Почему не отрабатывается Sleep()?

3. Почему закрывается позиция по EURUSD?

Заранее спасибо.

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением...
 

1. За Sleep нужно бить по рукам. Бить очень сильно.

2. ...

 

2. Вы смешиваете мух и котлеты:

    if(PositionGetInteger(POSITION_TYPE) <= ORDER_TYPE_SELL &&  

ПОЗИЦИЯ - НЕ ЕСТЬ ОРДЕР!!!


И вот ещё - тоже самое: попали в кучи кони, люди ...

 if(PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY 
 
Vladimir Karputov #:

2. Вы смешиваете мух и котлеты:

ПОЗИЦИЯ - НЕ ЕСТЬ ОРДЕР!!!


И вот ещё - тоже самое: попали в кучи кони, люди ...

А что не так со Sleep? Советник переделан из mql4. Там нужен был...

Спасибо за "мух и котлеты" за "коней и людей". Исправил. Посмотрим...

 
Sergej Ahlert:

1. Почему советник выдает ДВА приказа на закрытие подряд (ведь в цикле идет проверка на имя пары)?

Задвоение разбиралось подробно на форуме. После MT4 нужно сломать голову, чтобы въехать, почему так происходит. Это не ошибка.

3. Почему закрывается позиция по EURUSD?

Нет выбора позиции ДО сверки с символом.

Советник переделан из mql4.

Низкие шансы, что будет работать, как в MT4. Не работает подход "замени названия функций".

 
fxsaber #:

Задвоение разбиралось подробно на форуме. После MT4 нужно сломать голову, чтобы въехать, почему так происходит. Это не ошибка.

Нет выбора позиции ДО сверки с символом.

Низкие шансы, что будет работать, как в MT4. Не работает подход "замени названия функций".

Ссылочку, пожалуйста, на разбор задвоения.

Выбор позиции происходит здесь:

string s = PositionGetSymbol(cnt)

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

 

Sleep убрали? По рукам надавали?

Сторонние циклы выкинули?

 
Vladimir Karputov #:
Sleep убрали? По рукам надавали?
Объясните, что плохого в Sleep...

 

Простейший цикл перебора позиций (взято из кода подсчёта количества позиций):

   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
     {
      ulong ticket=PositionGetTicket(index);
      if(ticket>0);
        {
         if(PositionGetString(POSITION_SYMBOL)==Symbol() && PositionGetInteger(POSITION_MAGIC)==InpMagic)
           {
            total++
           }
        }
     

Вместо 

           {
            total++
           }

поставьте закрытие позиции.

Только не вздумайте засовывать сюда Sleep.

 
Sergej Ahlert #:

Ссылочку, пожалуйста, на разбор задвоения.

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

Выбор позиции происходит здесь:

Комментировать не буду.

Проверка на наличие дублей ордеров/позиций в MT5
Проверка на наличие дублей ордеров/позиций в MT5
  • 2021.09.12
  • www.mql5.com
Появление дублей ордеров/позиций в MT5 - архитектурная особенность платформы, с которой многие сталкиваются. Данная неприятность вызывает серьезные перекосы в торговых рисках, ломает логику, усложняет
 
Sergej Ahlert #:
Объясните, что плохого в Sleep...

Прочитав команду Sleep всё засыпает и ни одна функция не работает, есть другие способы отсрочки исполнения