Неожиданный результат в PositionGetDouble(POSITION_VOLUME)

 

В эксперте при выполнении условия на открытие сделки BUY/SELL одним из шагов получаю значение текущего объема открытой позиции.


if(выполняется ли условие для открытия сделки BUY?)
{
  SymbolInfoTick(Symbol(),Tick);
  ...
  PositionSelect(Symbol());
  while(PositionGetDouble(POSITION_VOLUME)<Сколько всего хочется навалить в позицию) /// <-- И вот здесь меня ждёт сюрприз, результат гарантированно закрытой предыдущей позиции
  {
    ...
    if(OrderCheck(Request,Check)==true) OrderSend(Request,Result);
  }
}
...
if(выполняется ли условие для открытия сделки SELL?)
{
  SymbolInfoTick(Symbol(),Tick);
  ...
  PositionSelect(Symbol());
  while(PositionGetDouble(POSITION_VOLUME)<Сколько всего хочется навалить в позицию) /// <-- И вот здесь меня ждёт сюрприз, результат гарантированно закрытой предыдущей позиции
  {
    ...
    if(OrderCheck(Request,Check)==true) OrderSend(Request,Result);
  }
}
...

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

PositionGetDouble(POSITION_VOLUME)

остается значение объема предыдущей позиции, которая уже гарантированно закрыта!

Так должно быть? 

 
Rich:

В эксперте при выполнении условия на открытие сделки BUY/SELL одним из шагов получаю значение текущего объема открытой позиции.


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

остается значение объема предыдущей позиции, которая уже гарантированно закрыта!

Так должно быть? 

Предполагаю, что PositionGetDouble(POSITION_VOLUME) возвращает нечто осмысленное только при наличии предварительно выбранной позиции. А посольку выбранная позиция была закрыта, то возвращаемое значение не обусловлено.
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций - Документация по MQL5
 

В коде осмысленный выбор позиции непосредственно перед обращением к PositionGetDouble(POSITION_VOLUME)

   PositionSelect(Symbol()); <-- Вот

while(PositionGetDouble(POSITION_VOLUME)<Сколько всего хочется навалить в позицию) 

Должна вернуть 0,0

Ещё версии или варианты решения? 

 
Rich:

В эксперте при выполнении условия на открытие сделки BUY/SELL одним из шагов получаю значение текущего объема открытой позиции.


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

остается значение объема предыдущей позиции, которая уже гарантированно закрыта!

Так должно быть? 

Так и должно быть..

PositionSelect

 
Swan:

Так и должно быть..

PositionSelect

С этим разобрался, спасибо. 

Но таки интересно, а что же всё таки в таком случае возвращает PositionGetDouble(POSITION_VOLUME)?

 
Rich:

С этим разобрался, спасибо. 

Но таки интересно, а что же всё таки в таком случае возвращает PositionGetDouble(POSITION_VOLUME)?

наверно таки не совсем разобрались

Возвращает обьём позиции на момент вызова PositionSelect.

Функция PositionSelect() копирует данные о позиции в программное окружение, и последующие вызовы PositionGetDouble(), PositionGetInteger() и PositionGetString() возвращают ранее скопированные данные. Это означает, что самой позиции может уже и не быть (или же она изменилась по объему, направлению и т.д.), а данные этой позиции можно еще получать. Для гарантированного получения свежих данных о позиции рекомендуется вызывать функцию PositionSelect() непосредственно перед обращением за ними.

 
Rich:

С этим разобрался, спасибо. 

Но таки интересно, а что же всё таки в таком случае возвращает PositionGetDouble(POSITION_VOLUME)?

Предположительно - То, что осталось в области памяти скрытой от наших глаз.

---добавлено---
не успел)

 

Понятно.

Перед тем, как улучшиться, ситуация ухудшилась... :) 

 
Rich:

В коде осмысленный выбор позиции непосредственно перед обращением к PositionGetDouble(POSITION_VOLUME)

   PositionSelect(Symbol()); <-- Вот

while(PositionGetDouble(POSITION_VOLUME)<Сколько всего хочется навалить в позицию) 

Должна вернуть 0,0

Ещё версии или варианты решения? 

Из описания ситуации следует, что причиной возникновения проблемы является совокупность двух обстоятельств:

1)  функция PositionSelect() обращается к позиции, которой на момент обращения уже не существует (закрыта);

2) при обращении функции PositionSelect() к отсутствующей (закрытой) позиции прежние данные об этой позиции в программном окружении не обнуляются.

Конечно, было бы удобно, чтобы в указанной ситуации прежние данные обнулялись. Почему этого не сделано - вопрос к разработчикам. Для разрешения же возникшей ситуации при имеющихся условиях предлагаю учесть, что функция PositionSelect() возвращает значение типа bool. В частности, если предположить, что обращение  функции PositionSelect() к отсутствующей (закрытой) позиции приводит к "неудачному завершению функции" (цитата из Справочника), то эта функция должна вернуть false.

Иными словами, выбор позиции в коде нельзя признать полностью "осмысленным", так как не анализируется результат вызова функции PositionSelect(). В частности, "чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError()". 

Расскажите о результатах. 

 
Yedelkin:

Из описания ситуации следует, что причиной возникновения проблемы является совокупность двух обстоятельств:

1)  функция PositionSelect() обращается к позиции, которой на момент обращения уже не существует (закрыта);

2) при обращении функции PositionSelect() к отсутствующей (закрытой) позиции прежние данные об этой позиции в программном окружении не обнуляются.

Конечно, было бы удобно, чтобы в указанной ситуации прежние данные обнулялись. Почему этого не сделано - вопрос к разработчикам. Для разрешения же возникшей ситуации при имеющихся условиях предлагаю учесть, что функция PositionSelect() возвращает значение типа bool. В частности, если предположить, что обращение  функции PositionSelect() к отсутствующей (закрытой) позиции приводит к "неудачному завершению функции" (цитата из Справочника), то эта функция должна вернуть false.

Иными словами, выбор позиции в коде нельзя признать полностью "осмысленным", так как не анализируется результат вызова функции PositionSelect(). В частности, "чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError()". 

Расскажите о результатах. 

Разработчики и предполагали, что будет анализироваться результат PositionSelect(), противное приведет к возникновению грубой ошибки...
 
Yedelkin:

Расскажите о результатах. 

Можно делать так:

 

if(выполняется ли условие для открытия сделки BUY?)
{
  double CurPosVolume=0;
  double ReqPosVolume=Сколько всего хочется навалить в позицию;
  ...
  while(CurPosVolume<ReqPosVolume)
  {
    ...
    if(OrderCheck(Request,Check)==true) bool Succes=OrderSend(Request,Result);
    if(Succes==true)
    {
      PositionSelect(Symbol());
      CurPosVolume=CurPosVolume+PositionGetDouble(POSITION_VOLUME);
    }
  }
}
...