Умножается лот при открытии позиции

 

Здравствуйте. Советник торгует на МТ5 и каким-то образом умудряется открывать позицию с 2-м и даже 3-м лотом. То есть на графике вместо 0.1 лота позиции стоит позиция с 0.1-0.3 лота. 

Бывает, что на рынке позиция открыта 0.1 лотом, а в журнале отображается как 0.2, но это переоткрытие. А здесь именно открытые позиции с неправильным лотом открываются.

В коде стоит проверка, чтобы не открывалось, если на рынке есть открытые позиции:

if (PositionSelect (Symbol ()))
{
   if (PositionGetInteger (POSITION_TYPE) == POSITION_TYPE_BUY)
   {
      Trade.PositionClose (Symbol ());
   }
}

if (!PositionSelect (Symbol ()))
{
   Trade.Sell (Lot ());
}

В функции Lot всегда передается значение 0.1.

Подскажите, что делается не так?

 
if (!PositionSelect (Symbol ()))
{
   if(Trade.Sell(Lot()) == true && Trade.ResultOrder() > 0)
   {
      // дождёмся отображения открытой позиции в терминале,
      // чтобы на следующем тике не открыться вновь
      while(!IsStopped())
      {
         if(PositionSelect(Symbol()) == true)
            break;
            
         Sleep(10);
      }
   }
}

Прямо в таком виде код лучше не использовать: ордер может быть и отклонён биржей, тогда получите бесконечный цикл. Но причина вашей проблемы, думаю, понятна.

 
Sergei Vladimirov:

Прямо в таком виде код лучше не использовать: ордер может быть и отклонён биржей, тогда получите бесконечный цикл. Но причина вашей проблемы, думаю, понятна.

Попробую так. Спасибо.

То есть позиция может открыться, но не до конца? :) 

 
Roman Starinskij:

Попробую так. Спасибо.

То есть позиция может открыться, но не до конца? :) 

Позиция-то открывается, но нужно какое-то время, чтобы она отобразилась в торговом окружении. Небольшое, всего несколько миллисекунд. Если до истечения этого времени придёт новый тик, и советник снова запустится на выполнение (или если вы запускаете этот код по короткому таймеру), то функция PositionSelect() вернёт false. Соответственно, тут же отошлётся ещё один ордер. Вы посмотрите в журнале, как были открыты удвоенные позиции - увидите, что это не одно открытие двойным лотом, а два последовательных ордера. Чтобы этого не было, нужно дождаться, когда последняя сделка добавится в историю, и терминал увидит открытую позицию. Можно в цикле, как в моём примере, а можно в OnTrade() отслеживать.
 
Sergei Vladimirov:
Позиция-то открывается, но нужно какое-то время, чтобы она отобразилась в торговом окружении. Небольшое, всего несколько миллисекунд. Если до истечения этого времени придёт новый тик, и советник снова запустится на выполнение (или если вы запускаете этот код по короткому таймеру), то функция PositionSelect() вернёт false. Соответственно, тут же отошлётся ещё один ордер. Вы посмотрите в журнале, как были открыты удвоенные позиции - увидите, что это не одно открытие двойным лотом, а два последовательных ордера. Чтобы этого не было, нужно дождаться, когда последняя сделка добавится в историю, и терминал увидит открытую позицию. Можно в цикле, как в моём примере, а можно в OnTrade() отслеживать.
Спачибо за объяснение. Стало понятно как работают приказы открытий. В МТ4 такого не встречал, такие правила ответов только в МТ5?
 
Да, только в МТ5. В чётвёрке при выходе из функции OrderSend() всё уже синхронизировано. В пятёрке всё иначе.
 
Лучше дождаться, пока Trade.ResultOrder() появится в истории, на PositionSelect(Symbol()) полагаться не стоит (да и мало ли какая в рынке совокупная позиция, если работает не один советник!).
 

Ну, в исходном примере автора перед отправкой маркет-ордера проверяется отсутствие позиции, так что совокупной позиции нет. Но в общем случае - да, верно: позиция может и не открыться (ордер может вернуться со статусом rejected) - я тоже об этом выше упоминал. Этот пример - просто для пояснения, из-за чего, собственно, проблема.

ЗЫ. Вообще не понимаю, как в МТ5 можно торговать двумя и более советниками на одном символе. Даст второй советник противоположный сигнал после того, как позиция уже открыта первым советником, она закроется, и попробуй потом разрули, как этим советникам сопровождать свои теперь уже виртуальные позици... Давно плюнул на это дело. Один символ - один советник. Даже мэджики не использую за ненадобностью.

 
Sergei Vladimirov:

ЗЫ. Вообще не понимаю, как в МТ5 можно торговать двумя и более советниками на одном символе. Даст второй советник противоположный сигнал после того, как позиция уже открыта первым советником, она закроется, и попробуй потом разрули, как этим советникам сопровождать свои теперь уже виртуальные позици... Давно плюнул на это дело. Один символ - один советник. Даже мэджики не использую за ненадобностью.

Да, учет не самый простой. Но сделать можно.
 
Andrey Khatimlianskii:
Да, учет не самый простой. Но сделать можно.

Может я просто не люблю МТ5, но в нем все как для людей под землей. Все ни так. Comment() не сбиваются, объекты чтобы увидеть все нужно выбирать "все", трассировка графика на макс. скорости как-то "едет", double переменные по дефолту имеют какие-то "2.627267821" значения и еще с ордерами свой принцип. То ли все так не доработанно, то ли просто другой и ужасно не привычны/не_понятный принцип.

За ответы всем спасибо, со всем разобрался, кажется все работает. :)