Почему открываются дополнительные ордера?

 

У некоторых брокеров закрывая позицию из советника открывается противоположная позиция.

Сделал небольшой цикл (из 3 подходов) для более надежного закрытия.

Проверяю каждый ответ сервера, но тем не менее, советник не видит ответ брокера.

Подскажите что не так или каким образом это устранить.
Код закрытия позиции такой

bool ClosePosition(string symbol, ulong deviation=10,ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK, double volume=0)

      PositionSelect(symbol);
      if(volume==0)
         volume=PositionGetDouble(POSITION_VOLUME);
      ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)PositionGetInteger(POSITION_TYPE);
      MqlTradeRequest Request;
      MqlTradeResult Results;
      ZeroMemory(Request);
      ZeroMemory(Results);
      Request.action=TRADE_ACTION_DEAL;
      if(type==ORDER_TYPE_BUY)
        {
         Request.type=ORDER_TYPE_SELL;
         Request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
        }
      else if(type==ORDER_TYPE_SELL)
        {
         Request.type=ORDER_TYPE_BUY;
         Request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
        }
      Request.symbol=symbol;
      Request.volume=volume;
      Request.deviation=deviation;
      Request.type_filling=filling;
      bool res=false;
      for(int i=0; i<3 && Results.deal<=0 && !res; i++)
         res=OrderSend(Request,Results);
      if(res)
         return(true);

      return(false);

 

Что это такое:

      if(volume==0)
         volume=PositionGetDouble(POSITION_VOLUME);

?

Зачем проверять условие? И почему "volume" вообще не инициализирована? Откуда Вы знаете, какое в ней значение пришло?
 

 
Vladimir Karputov:

Что это такое:

      if(volume==0)
         volume=PositionGetDouble(POSITION_VOLUME);

?

Зачем проверять условие? И почему "volume" вообще не инициализирована? Откуда Вы знаете, какое в ней значение пришло?
 

Ну здрасте.... это запрос на сервер о том, какой объем имеет позиция....
на момент закрытия он может быть разный, т.к. при одних условиях откроется один ордер, при других еще несколько...
поэтому перед закрытием общей позы надо знать ее объем, вот поэтому я его и запрашиваю.
 
Gennady Mazur:
Ну здрасте.... это запрос на сервер о том, какой объем имеет позиция....
на момент закрытия он может быть разный, т.к. при одних условиях откроется один ордер, при других еще несколько...
поэтому перед закрытием общей позы надо знать ее объем, вот поэтому я его и запрашиваю.
Добавлено: допустим, что "volume" имеет значение (осталось с прошлого захода) 0.5. А закрывать Вы хотите позицию BUY с объёмом 0.1. Как думаете, что произойдёт?
 
Vladimir Karputov:
Добавлено: допустим, что "volume" имеет значение (осталось с прошлого захода) 0.5. А закрывать Вы хотите позицию BUY с объёмом 0.1. Как думаете, что произойдёт?

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

      for(int i=0; i<3 && Results.deal<=0 && !res; i++)
         {

 if(volume==0)

         volume=PositionGetDouble(POSITION_VOLUME);

res=

OrderSend(Request,Results);

}

 

Вот это условие:

   for(int i=0; i<3 && Results.deal<=0 && !res; i++)

неоднозначно. 

Пример:  

OrderSend вернул true, но это ещё не гарантия, так как:

В случае успешной базовой проверки структур (проверка указателей) возвращается true - это не свидетельствует об успешном выполнении торговой операции. Для получения более подробного описания результата выполнения функции следует анализировать поля структуры result.

и Results.deal вернул 0. ТО есть произошла ошибка.

 

Что Вы получите в Вашем условии?  

   for(int i=0; i<3 (здесь true) && Results.deal<=0 (здесь true) && !res (вот здесь false); i++)

Вы вообще не закроете, так как второго захода не будет, Вас просто выкинет из цикла.

 
Gennady Mazur:

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


Как минимум так:

      for(int i=0; i<3 && Results.deal<=0 && !res; i++)
         {
           volume=PositionGetDouble(POSITION_VOLUME);
           res=
           OrderSend(Request,Results);
         }

 Но само условие if - неправильное - я выше написал.

 
Vladimir Karputov:

Вот это условие:

   for(int i=0; i<3 && Results.deal<=0 && !res; i++)

неоднозначно. 

Пример:  

OrderSend вернул true, но это ещё не гарантия, так как:

В случае успешной базовой проверки структур (проверка указателей) возвращается true - это не свидетельствует об успешном выполнении торговой операции. Для получения более подробного описания результата выполнения функции следует анализировать поля структуры result.

и Results.deal вернул 0. ТО есть произошла ошибка.

 

Что Вы получите в Вашем условии?  

   for(int i=0; i<3 (здесь true) && Results.deal<=0 (здесь true) && !res (вот здесь false); i++)

Вы вообще не закроете, так как второго захода не будет, Вас просто выкинет из цикла.

Хорошо, допустим... а как тогда однозначно?
 
Vladimir Karputov:

Как минимум так:

      for(int i=0; i<3 && Results.deal<=0 && !res; i++)
         {
           volume=PositionGetDouble(POSITION_VOLUME);
           res=
           OrderSend(Request,Results);
         }

 Но само условие if - неправильное - я выше написал.

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

Всё приходит, просто Вы ничего не контролируете. Нужно проверять как минимум в два этапа:

  • OrderSend - если вернул true
    • это ещё не гарантия - нужно проверить тикет сделки
      • если тикет не равен нулю (точнее тикет больше нуля) - вот это уже гарантия
 
Vladimir Karputov:

Всё приходит, просто Вы ничего не контролируете. Нужно проверять как минимум в два этапа:

  • OrderSend - если вернул true
    • это ещё не гарантия - нужно проверить тикет сделки
      • если тикет не равен нулю (точнее тикет больше нуля) - вот это уже гарантия
То есть в миницикле если пришел ответ тру, надо проверить тикет, если он меньше 1 то продолжаем, если больше то все....конец
так? Вы уверены что это прогарантирует отсутствие дополнительного запроса?
Просто я ранее проверял тикет, но не помню почему от него решил избавиться.