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

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--)
      {
         deal_symbol=PositionGetSymbol(x);
         deal_magic=PositionGetInteger(POSITION_MAGIC);
         
            if(deal_symbol==_Symbol && deal_magic==_Magic)
            {z=true; break;}
      }
   }

return(z);
}
Vladimir Karputov  
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

kofesutra  
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);
}
Vladimir Karputov  
kofesutra:


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

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

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


Нет, 

PositionGetSymbol

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

kofesutra  
Vladimir Karputov:

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


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

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

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

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

Документация по MQL5: Торговые функции / PositionGetTicket
Документация по MQL5: Торговые функции / PositionGetTicket
  • www.mql5.com
Торговые функции / PositionGetTicket - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
kofesutra  
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);
  }
Alexey Viktorov  
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)

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

kofesutra  
Alexey Viktorov:

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


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

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

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

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

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

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

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

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

Да незачто. Сварщик сварщика видит дальше чем рыбак рыбака.))
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.

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

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

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