Множественное открытие ордеров одновременно MQL5

 

Всем привет. Появилась проблема. Возникает не часто, но бывает. Советник открывает  множество позиций, тогда как должа быть только одна.

Код:

      //покупка
      if(time()==true)
        {
         if(_price[candle]>_upperBand[candle] && _price[candle+1]<_upperBand[candle+1])
           {
            double sl = lastAsk - _atr[0]*2;
            double tp = + lastAsk + _atr[0]*2;

            sl = NormalizeDouble(sl,_Digits);
            tp = NormalizeDouble(tp,_Digits);

            if(!trade.Buy(Lot,_Symbol,lastAsk,sl,tp,"") && CalculatePositions()==0)
              {
               Print("Метод Buy() потерпел неудачу. Код возврата=",trade.ResultRetcode(),
                     // if(!trade.Buy(Lot,_Symbol,lastAsk,0,0,"")) Print("Метод Buy() потерпел неудачу. Код возврата=",trade.ResultRetcode(),
                     ". Описание кода: ",trade.ResultRetcodeDescription(),"; sl: ",sl,"; tp: ",tp);
                     return;
              }
            else
              {
               Print("Метод Buy() выполнен успешно. Код возврата=",trade.ResultRetcode(),
                     " (",trade.ResultRetcodeDescription(),")");
                     return;
              }
           }
         //продажа
         if(_price[candle]<_loverBand[candle] && _price[candle+1]>_loverBand[candle+1])
           {
            double sl =  lastBid + _atr[0]*2;
            double tp =  lastBid - _atr[0]*2;
            sl = NormalizeDouble(sl,_Digits);
            tp = NormalizeDouble(tp,_Digits);

            if(!trade.Sell(Lot,_Symbol,lastBid,sl,tp,"") && CalculatePositions()==0)
              {
               Print("Метод Sell() потерпел неудачу. Код возврата=",trade.ResultRetcode(),
                     //if(!trade.Sell(Lot,_Symbol,lastBid,0,0,"")) Print("Метод Sell() потерпел неудачу. Код возврата=",trade.ResultRetcode(),
                     ". Описание кода: ",trade.ResultRetcodeDescription(),"; sl: ",sl,"; tp: ",tp);
                     return;
              }
            else
              {
               Print("Метод Sell() выполнен успешно. Код возврата=",trade.ResultRetcode(),
                     " (",trade.ResultRetcodeDescription(),")");
                     return;
              }
           }
        }

Функция подсчета позиций:

int CalculatePositions()
  {
   int count=0;

   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==_Symbol && m_position.Magic()==MagicNumber)
           {
            if(m_position.PositionType()==POSITION_TYPE_BUY || m_position.PositionType()==POSITION_TYPE_SELL)
               count++;
           }
   return(count);
  }


Скрин открытий ордеров:



Скрин вкладки Эксперты:



Помогите разобраться пожалуйста. Спасибо.

 
Evgeniy Zhdan:

Всем привет. Появилась проблема. Возникает не часто, но бывает. Советник открывает  множество позиций, тогда как должа быть только одна.

Код:

Функция подсчета позиций:

Помогите разобраться пожалуйста. Спасибо.

Поменяйте местами!

if(CalculatePositions()==0&&!trade.Sell(Lot,_Symbol,lastBid,sl,tp,"")) -верно!
if(!trade.Sell(Lot,_Symbol,lastBid,sl,tp,"") && CalculatePositions()==0)-неверно!
 
Nikolay Gaylis:

Поменяйте местами!

А разве это имеет значение?

 
Evgeniy Zhdan:

А разве это имеет значение?

вы сначала пытаетесь открыть-затем считаете позиции

 
Nikolay Gaylis:

вы сначала пытаетесь открыть-затем считаете позиции

Но еще нюанс.

весь торговый код еще заключен вот в это:

   if(CalculatePositions()==0)
     {
тут код который выше указан
}

После открытия одной позиции следует return. Следовательно, раз позиция есть в рынке, код внутри if не должен выполняться. А тут получается, что выполяется...

 

@Evgeniy Zhdan, разумеется, имеет. Это типичное логическое "И", которое проходится в курсе информатики в школе. Смотрите ка, что пишут об этом операторе коллеги из Microsoft: https://msdn.microsoft.com/ru-ru/library/c6s3h5a7.asp 

Ниже я выделил ключевую цитату, которая должна развеять все ваши сомнения.

Перед продолжением вычисления выражения логического И полностью вычисляется первый операнд и учитываются все побочные эффекты. Второй операнд вычисляется только в том случае, если результат вычисления первого операнда — значение true (не нуль). Такое вычисление исключает необязательное вычисление второго операнда, если выражение логического И имеет значение false.

Оператор логического И: &&
Оператор логического И: &&
  • msdn.microsoft.com
Оператор логического И (&&) возвращает логическое значение true, если оба операнда имеют значение true; в противном случае он возвращает значение false. Перед вычислением оба операнда неявно преобразуются в тип ; результат также имеет тип . Логическое И имеет ассоциативность в направлении слева направо. Операнды оператора логического И не...
 
Alexey Loginov:

@Evgeniy Zhdan, разумеется, имеет. Это типичное логическое "И", которое проходится в курсе информатики в школе. Смотрите ка, что пишут об этом операторе коллеги из Microsoft: https://msdn.microsoft.com/ru-ru/library/c6s3h5a7.asp 

Ниже я выделил ключевую цитату, которая должна развеять все ваши сомнения.

Перед продолжением вычисления выражения логического И полностью вычисляется первый операнд и учитываются все побочные эффекты. Второй операнд вычисляется только в том случае, если результат вычисления первого операнда — значение true (не нуль). Такое вычисление исключает необязательное вычисление второго операнда, если выражение логического И имеет значение false.

А это ?

   if(CalculatePositions()==0)
     {
тут код который выше указан
}
 
Evgeniy Zhdan:

А это ?

нужно смотреть куда 

return

возвращает

 
Nikolay Gaylis:

нужно смотреть куда 

возращает

Как я понимаю, в начало OnTick()

 

А что в MQL5 счётчик позиций актуален? Там же вроде неттинг счета.

 
Nikolay Gaylis:

нужно смотреть куда 

возвращает

Это оператор, завершающий выполнение метода, в котором он присутствует, и возвращающий некое типизированное значение; в данном случае return пустой, а значит возвращает только инфу о том, что метод должен прекратить работу. Так что нет разницы, куда будет возвращено значение.

@Evgeniy Zhdan, возможно, косяк только в том, что вы ошиблись с определением условий в конструкциях if. Попробуйте через Print() выводить все действия в лог, чтобы задетектить ошибку. Потом лог зальете сюда, и там посмотрим. 

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