MQL5 Наличие открытой позиции

 

Здравствуйте, все! Чего-то я туплю совсем, помогите, друзья!
Задача: написать функцию проверки есть ли открытая позиция по инструменту (паре) и мэджику или позиции нет.
Предполагается, что на одной паре разные советники (с разными мэджиками) могут открывать не больше одной сделки каждый. 
Вот так будет верно?

bool fPositionPresenceCheck()
{bool z=false;
   if(PositionsTotal()==0)
   {z=false;}
   else
   {
   string deal_symbol="";
   long deal_magic=0;
   
   for(int x=PositionsTotal();x>0;x--)
      {
         deal_symbol=PositionGetSymbol(x);
         deal_magic=PositionGetInteger(POSITION_MAGIC);
         
            if(deal_symbol==_Symbol && deal_magic==_Magic)
            {z=true; break;}
      }
   }

return(z);
}
 
kofesutra:

Здравствуйте, все! Чего-то я туплю совсем, помогите, друзья!
Задача: написать функцию проверки есть ли открытая позиция по инструменту (паре) и мэджику или позиции нет.
Предполагается, что на одной паре разные советники (с разными мэджиками) могут открывать не больше одной сделки каждый. 
Вот так будет верно?


Если предположить, что может быть только ОДНА позиция, то практически правильно. Исправил одну строку:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool fPositionPresenceCheck()
  {
   bool z=false;
   if(PositionsTotal()==0)
      z=false;
   else
     {
      string deal_symbol="";
      long deal_magic=0;

      //for(int x=PositionsTotal();x>0;x--)
      for(int x=PositionsTotal()-1;x>=0;x--)
        {
         deal_symbol=PositionGetSymbol(x);
         deal_magic=PositionGetInteger(POSITION_MAGIC);

         if(deal_symbol==_Symbol && deal_magic==_Magic)
           {
           z=true; 
           break;
           }
        }
     }

   return(z);
  }


Так как PositionsTotal() возвращает общее количество позиций, но нумерация в массивах, списках идёт с "0". Поэтому именно x=PositionsTotal()-1

 
Vladimir Karputov:


Если предположить, что может быть только ОДНА позиция, то практически правильно. 


Владимир, спасибо огромное и за исправление и за пояснение!

Уточню условия: на одной паре может быть несколько позиций одновременно, но только от разных советников. Каждый советник на одной паре имеет право держать только одну позицию. Да, верно?

Как Вы думаете, исходя из рекомендации вызывать PositionSelect() непосредственно перед обращением к данным, не лучше сделать так?

bool fPositionPresenceCheck()
{bool z=false;
   if(PositionsTotal()==0)
   {z=false;}
   else
   {
   string deal_symbol="";
   long deal_magic=0;
   
   for(int x=PositionsTotal()-1;x>=0;x--)
      {
         deal_symbol=PositionSelect(PositionGetSymbol(x));
         deal_magic=PositionGetInteger(POSITION_MAGIC);
         
            if(deal_symbol==kSymbol && deal_magic==kMagic)
            {z=true; break;}
      }
   }

return(z);
}
 
kofesutra:


Владимир, спасибо огромное и за исправление и за пояснение!

Уточню условия: на одной паре может быть несколько позиций одновременно, но только от разных советников. Каждый советник на одной паре имеет право держать только одну позицию. Да, верно?

Как Вы думаете, исходя из рекомендации вызывать PositionSelect() непосредственно перед обращением к данным, не лучше сделать так?


Нет, 

PositionGetSymbol

Возвращает символ соответствующей открытой позиции и автоматически выбирает позицию для дальнейшей работы с ней при помощи функций PositionGetDoublePositionGetIntegerPositionGetString. - таким образом PositionSelect не нужна.

 
Vladimir Karputov:

таким образом PositionSelect не нужна.


Ага, понял. Благодарю Вас!
 
kofesutra:

Ага, понял. Благодарю Вас!

Это был совет как делать НЕ НАДО...

На hadge счетах выбирать позиции надо функцией PositionGetTicket и потом проверять соответствие символа и магика.

Документация по MQL5: Торговые функции / PositionGetTicket
Документация по MQL5: Торговые функции / PositionGetTicket
  • www.mql5.com
Торговые функции / PositionGetTicket - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Alexey Viktorov:

Это был совет как делать НЕ НАДО...

На hadge счетах выбирать позиции надо функцией PositionGetTicket и потом проверять соответствие символа и магика.


Здравствуйте, Алексей! Да, действительно, у меня хэдж-счёт.

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

Тогда лучше так? Правильно?

bool fPositionPresenceCheck()
  {
   bool z=false;
   if(PositionsTotal()==0)
      z=false;
   else
     {
      ulong deal_ticket=0;
      string deal_symbol="";
      long deal_magic=0;

      for(int x=PositionsTotal()-1;x>=0;x--)
        {
         deal_ticket=PositionGetTicket(x);
         if(PositionSelectByTicket(deal_ticket)==true)
         {
          deal_symbol=PositionGetString(POSITION_SYMBOL);
          deal_magic=PositionGetInteger(POSITION_MAGIC);

         if(deal_symbol==_Symbol && deal_magic==_Magic)
           {
           z=true; 
           break;
           }
          }
        }
     }
   return(z);
  }
 
kofesutra:


Здравствуйте, Алексей! Да, действительно, у меня хэдж-счёт.

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

Тогда лучше так? Правильно?

Конечно у каждого свой стиль программирования. Я сначала выскажу свой стиль в виде риторических вопросов.

1. Зачем писать условие если позиций нет? Ведь перед этой проверкой переменной z уже присвоено значение false и повторять нет необходимости. Плюс к этому, если позиций нет, то в цикл войти невозможно, соответственно он будет пропущен.

2. Какая необходимость в переменной z если легко обойтись без неё. Достаточно в цикле поставить return(true); вместо break; и в конце функции return(false);

3. Совершенно бесполезные переменные deal_symbol и deal_magic. Я пишу так

if(PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == _Magic)

3. Если в условии проверяется значение типа bool то совсем не обязательно писать == false; достаточно перед переменной или вызываемой функцией поставить восклицательный знак.

И последнее самое важное: функция PositionGetTicket() равно как и PositionGetSymbol() выбирает позицию для дальнейшего обращения к ней функциями PositionGet*** и PositionSet***

Следовательно строка

if(PositionSelectByTicket(deal_ticket)==true)

совершенно лишняя.

 
Alexey Viktorov:

Конечно у каждого свой стиль программирования. Я сначала выскажу свой стиль в виде риторических вопросов.


Здравствуйте, Алексей! Я очень благодарен Вам за ответ и советы в нём содержащиеся!

Мне - ненастоящему сварщику :) и совсем не программисту - такой разбор мегаполезен.

Пойду пересматривать весь остальной свой код. 

Ещё раз спасибо!
 
kofesutra:

Здравствуйте, Алексей! Я очень благодарен Вам за ответ и советы в нём содержащиеся!

Мне - ненастоящему сварщику :) и совсем не программисту - такой разбор мегаполезен.

Пойду пересматривать весь остальной свой код. 

Ещё раз спасибо!

Да незачто. Сварщик сварщика видит дальше чем рыбак рыбака.))
 
Alexey Viktorov:
Да незачто. Сварщик сварщика видит дальше чем рыбак рыбака.))

bool fPositionPresenceCheck()
  {for(int x=PositionsTotal()-1;x>=0;x--)
        {PositionGetTicket(x);
          if(PositionGetString(POSITION_SYMBOL) == kSymbol && PositionGetInteger(POSITION_MAGIC) == kMagic)
           {return(true);}
        }
   return(false);}

Да, код значительно похудел :) :)

Alexey Viktorov:
Совершенно бесполезные переменные deal_symbol и deal_magic.

Этот пункт у меня в голове застрял из рекомендации обнулять переменные перед использованием. Впрочем, я так понимаю, что совет обнулять будет акутальным только для глобальных переменных.

Ещё раз спасибо!

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