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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Evgeniy Zhdan
16150
Evgeniy Zhdan  

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

Код:

      //покупка
      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);
  }


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



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



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

Nikolay Gaylis
16094
Nikolay Gaylis  
Evgeniy Zhdan:

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

Код:

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

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

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

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

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

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

Nikolay Gaylis
16094
Nikolay Gaylis  
Evgeniy Zhdan:

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

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

Evgeniy Zhdan
16150
Evgeniy Zhdan  
Nikolay Gaylis:

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

Но еще нюанс.

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

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

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

Alexey Loginov
176
Alexey Loginov  

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

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

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

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

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

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

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

А это ?

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

А это ?

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

return

возвращает

Evgeniy Zhdan
16150
Evgeniy Zhdan  
Nikolay Gaylis:

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

возращает

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

geratdc
1512
geratdc  

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

Alexey Loginov
176
Alexey Loginov  
Nikolay Gaylis:

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

возвращает

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

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий