Как посчитать профит открытых позиций?

 

Сроки горят, но такой ерунды не могу отправить заказчику. Может я чего-то не понимаю? заработалась?

MQL5, хэдж счет

Есть функция для подсчета профита, но она не работает в составе советника и поэтому был написан тестовый советник, который будет ниже

//+------------------------------------------------------------------+
bool Fn_profit_summ(string &str, double &profit_summ, bool is_buy, ulong magic){
   profit_summ = 0;
   str="";
   //-----------------------------             
   int total = PositionsTotal();          
   for(int i=total-1; i>=0; i--){
      const ulong tic= PositionGetTicket(i); if(tic<=0)     return(false); //--- asinchr
      if(!PositionSelectByTicket(tic)                   )   return(false); //--- asinchr 
      bool is_buy_ = (PositionGetInteger(POSITION_TYPE  )==POSITION_TYPE_BUY); 
      if( is_buy_                             !=  is_buy)   continue; 
      if( PositionGetInteger(POSITION_MAGIC ) !=  magic )   continue;
      if( PositionGetSymbol (POSITION_SYMBOL) != _Symbol)   continue;
      double prof = PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP); 
      profit_summ += prof;
      str+="  ("+IntegerToString(tic)+" | "+DoubleToString(prof, 2)+")  ";
      }
   //-----------------------------
   return(true);}
//+------------------------------------------------------------------+

Собственно, полученные результаты: 



Как посчитать профит ну хоть системой нипель какой-то? второй день бьюсь над этип тип ерундовым заказом... 


(прикрепленный советник рандомным способом открывает ордера, выводит профит на график и по достижению определенного профита - должен закрывать, см. настройки)

Файлы:
 

Что-то не понял сути проблемы.

На первый взгляд, функция все делает правильно - перебирает позиции, и суммирует профит по каждой...  Что не так ?

 
George Merts:

Что-то не понял сути проблемы.

На первый взгляд, функция все делает правильно - перебирает позиции, и суммирует профит по каждой...  Что не так ?

посмотрите на скрин - тикеты позиций не совпадают с профитом

 

Что-то странное, у меня функция получения профита - примерно такая же...

Кроме как обратиться в сервисдеск - ничего не придумывается...

 
Galina Bobro:

Сроки горят, но такой ерунды не могу отправить заказчику. Может я чего-то не понимаю? заработалась?

MQL5, хэдж счет

Есть функция для подсчета профита, но она не работает в составе советника и поэтому был написан тестовый советник, который будет ниже

Собственно, полученные результаты: 



Как посчитать профит ну хоть системой нипель какой-то? второй день бьюсь над этип тип ерундовым заказом... 


(прикрепленный советник рандомным способом открывает ордера, выводит профит на график и по достижению определенного профита - должен закрывать, см. настройки)

Разберитесь в функциях  PositionGetTicket PositionSelectByTicket и PositionGetSymbol. Получается что PositionSelectByTicket совершенно лишняя, а PositionGetSymbol выбирает позицию не ту которую нужно, соответственно отсюда вся беда.
 
Galina Bobro:

PositionGetSymbol() - выбирает позицию для дальнейшей работы с ней. Замените на PositionGetString

 
Alexey Viktorov:
Разберитесь в функциях  PositionGetTicket PositionSelectByTicket и PositionGetSymbol. Получается что PositionSelectByTicket совершенно лишняя, а PositionGetSymbol выбирает позицию не ту которую нужно, соответственно отсюда вся беда.
Aleksey Lebedev:

PositionGetSymbol() - выбирает позицию для дальнейшей работы с ней. Замените на PositionGetString

Cпасибо огромное! Слово "Get" сбило с толку

 
Хм... Точно... Какая хитрая мелочь...  :)
 

А вот так можно лаконично написать на торговых классах CPositionInfo и CSymbolInfo:

//+------------------------------------------------------------------+
//| Calculate profit positions                                       |
//+------------------------------------------------------------------+
void CalculateProfitPositions(double &profit_buys,double &profit_sells)
  {
   profit_buys=0.0;
   profit_sells=0.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()==m_symbol.Name() && m_position.Magic()==m_magic)
           {
            double profit=m_position.Swap()+m_position.Profit();
            if(m_position.PositionType()==POSITION_TYPE_BUY)
               profit_buys+=profit;

            if(m_position.PositionType()==POSITION_TYPE_SELL)
               count_sells+=profit;
           }
//---
   return;
  }

За одно обращение к функции сразу получаем прибыль и по BUY ("profit_buys") и по SELL ("profit_sells") позициям.

 
Vitaly Muzichenko:

Лучше так:

Почему?

При каждой итерации for у вас идёт обращение к функции PositionsTotal(), что замедляет исполнение программы

Для проверки:

Вообще в цикле for 

for(выражение1; выражение2; выражение3) 
   оператор;

Выражение1 описывает инициализацию цикла

то есть один раз инициализируется. Дальше работаю только Выражение2 и Выражение3.
 
Vitaly Muzichenko:

Лучше так:

Почему?

При каждой итерации for у вас идёт обращение к функции PositionsTotal(), что замедляет исполнение программы

Для проверки:

И для контроля:

чуть изменённый код. В момент входа распечатываемся

//+------------------------------------------------------------------+
//| Fn_profit_summ                                                   |
//+------------------------------------------------------------------+
bool Fn_profit_summ(string &str,double &profit_summ,bool is_buy,ulong magic)
  {
   Print(__FUNCTION__);
   profit_summ=0.0;
   str="";
//---           
   for(int i=MyPositionsTotal()-1;i>=0;i--)
     {
      ulong tic=PositionGetTicket(i);
      if(tic<=0)
         return(false); //--- asinchr
      if(PositionGetInteger(POSITION_MAGIC)!=magic)
         continue;
      if(PositionGetString(POSITION_SYMBOL)!=Symbol())
         continue;
      if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && is_buy)
         profit_summ+=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
      if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && !is_buy)
         profit_summ+=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);

      str+="";
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int MyPositionsTotal()
  {
   Print("MyPositionsTotal");
   return(PositionsTotal());
  }

Главное дождаться когда позиций будет больше одной и тогда во вкладке "Эксперты" отчётливо будет видно, что на один вход в "Fn_profit_summ" приходится только один вход в "MyPositionsTotal".

Файлы:
Причина обращения: