Подсчет профита в пунктах за сутки по тикету

 

Не могу понять как на mql5 реализовать подсчет профита в пунктах по каждому из инструментов по истории?

Кто сталкивался с этом, прошу подсказать как считать, т.к. сделок много по разным инструментам, хочу посчитать за нужный мне интервал времени (например сутки) суммарный профит в ПУНКТАХ по каждому инструменту (FORTS). 

 
DKeN:

Не могу понять как на mql5 реализовать подсчет профита в пунктах по каждому из инструментов по истории?

Кто сталкивался с этом, прошу подсказать как считать, т.к. сделок много по разным инструментам, хочу посчитать за нужный мне интервал времени (например сутки) суммарный профит в ПУНКТАХ по каждому инструменту (FORTS). 

Сумма каждой сделки по истории:

MathRound(Pr/TickValue)*TickSize
 

Если поможет, то вот:

Пункты считаются после частичного и полного закрытия. Я их считаю как количество пунктов первой частичной сделки + второй + третьей и т.д. Тут на ваше усмотрение.

//+------------------------------------------------------------------+
//| Расчет торговой статистики                                       |
//+------------------------------------------------------------------+
CTrade::GetTradeResult(strTradeResult &TradeResult)
{
   SetClearTradeResult(TradeResult); //Очищаем результат
   datetime LastDate,DayBegin,WeekBegin,MonthBegin,YearBegin,OperDate;
   MqlDateTime mqlLastDate, mqlDayBegin, mqlWeekBegin, mqlMonthBegin, mqlYearBegin, mqlO={0};
   //Текущее время
   TimeCurrent(mqlLastDate);
   LastDate=StructToTime(mqlLastDate)+D'1970.1.1 00:01:00';

   mqlDayBegin=mqlLastDate; mqlDayBegin.hour=0; mqlDayBegin.min=0; mqlDayBegin.sec=0; //Начало дня
   //Начало Недели
   mqlWeekBegin=mqlLastDate; mqlO.day=mqlWeekBegin.day_of_week; mqlO.mon=1; mqlO.year=1970; OperDate=StructToTime(mqlO);
   WeekBegin=LastDate-OperDate; TimeToStruct(WeekBegin,mqlWeekBegin); mqlWeekBegin.hour=0; mqlWeekBegin.min=0; mqlWeekBegin.sec=0;
   //Начало Месяца
   mqlMonthBegin=mqlLastDate; mqlMonthBegin.day=1; mqlMonthBegin.hour=0; mqlMonthBegin.min=0; mqlMonthBegin.sec=0; //Начало месяца
   mqlYearBegin=mqlLastDate; mqlYearBegin.mon=1; mqlYearBegin.day=1; mqlYearBegin.hour=0; mqlYearBegin.min=0; mqlYearBegin.sec=0; //Начало года
   
   DayBegin=StructToTime(mqlDayBegin);
   WeekBegin=StructToTime(mqlWeekBegin); 
   MonthBegin=StructToTime(mqlMonthBegin);
   YearBegin=StructToTime(mqlYearBegin);
   
   double cTotal=0.0;
   double pIn=0.0;
   double VolumeIn=0.0;
   
   if (HistorySelect(D'1970.1.1 00:01:00',LastDate))
   {
      long Deals=HistoryDealsTotal();
      uint i;
      ulong Ticket;
      for (i=0;i<Deals;i++)
      {
         Ticket=HistoryDealGetTicket(i);
         if (Ticket>0)
         {
            if (HistoryDealGetInteger(Ticket,DEAL_TYPE)==DEAL_TYPE_BALANCE)
            {
               cTotal+=HistoryDealGetDouble(Ticket,DEAL_PROFIT);
            }
            
            //ВХОД (НОВЫЙ ИЛИ НАРАЩИВАНИЕ)
            if (HistoryDealGetInteger(Ticket,DEAL_ENTRY)==DEAL_ENTRY_IN)
            {
               //НОВЫЙ
               if (pIn==0.0)
               { 
                  pIn=HistoryDealGetDouble(Ticket,DEAL_PRICE);
                  VolumeIn=HistoryDealGetDouble(Ticket,DEAL_VOLUME);
                  //Print("Вход:",pIn," ",VolumeIn);
               }
               //НАРАЩИВАНИЕ
               else 
               {  
                  pIn=Math.NormSys(pIn*VolumeIn+HistoryDealGetDouble(Ticket,DEAL_PRICE)*HistoryDealGetDouble(Ticket,DEAL_VOLUME))/(VolumeIn+HistoryDealGetDouble(Ticket,DEAL_VOLUME));
                  VolumeIn=NormalizeDouble(VolumeIn+HistoryDealGetDouble(Ticket,DEAL_VOLUME),_DigitsVolume);
               }
            }
            
            //ВЫХОД (ПОЛНОЕ ИЛИ ЧАСТИЧНОЕ ЗАКРЫТИЕ)
            if (HistoryDealGetInteger(Ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT) //&& HistoryDealGetString(Ticket,DEAL_SYMBOL)==_Symbol //Для сортировки по символу
            {
               TradeResult.cLast=HistoryDealGetDouble(Ticket,DEAL_PROFIT);
               //ПОЛНОЕ ЗАКРЫТИЕ
               if (Math.Equal(HistoryDealGetDouble(Ticket,DEAL_VOLUME),VolumeIn) && VolumeIn!=0.0)
               {
                  TradeResult.pLast=Math.SubAbsSys(pIn,HistoryDealGetDouble(Ticket,DEAL_PRICE));
                  if (HistoryDealGetDouble(Ticket,DEAL_PROFIT)<0) TradeResult.pLast*=-1;
                  //Print("Полное Закрытие:",pIn," ",HistoryDealGetDouble(Ticket,DEAL_PRICE),"=",DoubleToString(TradeResult.pLast,_Digits));
                  pIn=0.0; VolumeIn=0.0;
               }
               //ЧАСТИЧНОЕ ЗАКРЫТИЕ
               if (HistoryDealGetDouble(Ticket,DEAL_VOLUME)<VolumeIn && VolumeIn!=0.0)
               {
                  TradeResult.pLast=Math.SubAbsSys(pIn,HistoryDealGetDouble(Ticket,DEAL_PRICE));
                  //Print("Частичное Закрытие:",pIn," ",HistoryDealGetDouble(Ticket,DEAL_PRICE),"=",DoubleToString(TradeResult.pLast,_Digits));
                  VolumeIn-=HistoryDealGetDouble(Ticket,DEAL_VOLUME);
               }
               cTotal+=TradeResult.cLast;
               //День
               if (HistoryDealGetInteger(Ticket,DEAL_TIME)>=DayBegin)
               {
                  TradeResult.cDay+=TradeResult.cLast;
                  TradeResult.nDay++;
                  TradeResult.pDay=Math.NormSys(TradeResult.pDay+TradeResult.pLast);
               }
               //Неделя
               if (HistoryDealGetInteger(Ticket,DEAL_TIME)>=WeekBegin)
               {
                  TradeResult.cWeek+=TradeResult.cLast;
                  TradeResult.nWeek++;
                  TradeResult.pWeek=Math.NormSys(TradeResult.pWeek+TradeResult.pLast);
               }
               //Месяц
               if (HistoryDealGetInteger(Ticket,DEAL_TIME)>=MonthBegin)
               {
                  if (TradeResult.cMonthBalance==0.0) TradeResult.cMonthBalance=cTotal;
                  TradeResult.cMonth+=HistoryDealGetDouble(Ticket,DEAL_PROFIT);
                  TradeResult.nMonth++;
                  TradeResult.pMonth=Math.NormSys(TradeResult.pMonth+TradeResult.pLast);               
               }
               //Год
               if (HistoryDealGetInteger(Ticket,DEAL_TIME)>=YearBegin)
               {
                  if (TradeResult.cYearBalance==0.0) TradeResult.cYearBalance=cTotal;
                  TradeResult.cYear+=HistoryDealGetDouble(Ticket,DEAL_PROFIT);
                  TradeResult.pYear=Math.NormSys(TradeResult.pYear+TradeResult.pLast);               
               }
            }
         }
      }
   }
   if (TradeResult.cYearBalance>0) TradeResult.ProfitPerYear=NormalizeDouble(TradeResult.cYear/TradeResult.cYearBalance*100,2); else TradeResult.ProfitPerYear=0.0;
   if (TradeResult.cMonthBalance>0) TradeResult.ProfitPerMonth=NormalizeDouble(TradeResult.cMonth/TradeResult.cMonthBalance*100,2); else TradeResult.ProfitPerMonth=0.0;
}
 

Собственно структура:

struct strTradeResult
{
   //с-Валюта депозита, n-Количество сделок, p-Количество пунктов
   double   cLast;         //Последний результат сделки в Валюте
   double   pLast;         //Последний результат сделки в Пунктах
   double   cDay;          //Результат по инструменту за день в Валюте
   uint     nDay;          //Количество сделок
   double   pDay;          //Результат по инструменту за день в Пунктах
   double   cWeek;         //Результат по инструменту за неделю в Валюте
   double   pWeek;         //Результат по инструменту за неделю в Пунктах
   uint     nWeek;         //Количество сделок за неделю
   double   cMonth;        //Результат за месяц
   double   pMonth;        //Пунктов за месяц
   uint     nMonth;        //Количество сделок за Месяц
   double   cYear;         //Результат по инструменту за год в валюте депозита
   double   pYear;         //Результат по инструменту за год в пунктах
   double   cYearBalance;  //Сальдо на начало года
   double   cMonthBalance; //Сальдо на начало месяца
   double   ProfitPerYear; //Процент доходности за год
   double   ProfitPerMonth;//Процент доходности за месяц
};
 
papaklass:

 Честно говоря, выделенное в Вашем посте, меня поставило в тупик. Думаю элементарное вычитание из цены открытия цены закрытия дает количество пунктов. Но, т.к. давно не использовал МТ5, решил посмотреть справку. И о чудо в сделках нет прямого указания цены открытия/закрытия сделки. Маразм крепчает.

Для кого эта платформа? Наверно для пионеров из анекдота:"....., только в гамаке и стоя!" 

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

 Я путаю?

А не подскажите, как может быть посчитана прибыль сделки (DEAL_PROFIT) без цен открытия и закрытия сделки?

Посмотрите код выше, там все видно! Я так понимаю, что сделкой вы называете полное закрытие позиции?
 
papaklass:

 Я путаю?

А не подскажите, как может быть посчитана прибыль сделки (DEAL_PROFIT) без цен открытия и закрытия сделки?

Маразм крепчает с вашей стороны. Разберитесь с системой ордер-сделка-позиция, а потом делайте такие заявления.
 
papaklass:
 А могли бы просто ответить на вопрос, который Вы так мило прокомментировали.... :)

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

Получить точно можно только цену открытия ордера, а где взять цену закрытия?

Документация по MQL5: Стандартные константы, перечисления и структуры / Константы объектов / Уровни волн Эллиотта
Документация по MQL5: Стандартные константы, перечисления и структуры / Константы объектов / Уровни волн Эллиотта
  • www.mql5.com
Стандартные константы, перечисления и структуры / Константы объектов / Уровни волн Эллиотта - Документация по MQL5
 
DKeN:

Не могу понять как на mql5 реализовать подсчет профита в пунктах по каждому из инструментов по истории?

Кто сталкивался с этом, прошу подсказать как считать, т.к. сделок много по разным инструментам, хочу посчитать за нужный мне интервал времени (например сутки) суммарный профит в ПУНКТАХ по каждому инструменту (FORTS). 

Посчитать можно только по изменению состояния позиции.
 

Сделка в MQL5 - факт исполнения ордера . Сделка имеет свойства ордера.

Цена открытия, добавления (наращивания) - это свойство сделки (HistoryDealGetDouble(Ticket,DEAL_PRICE)) с отобранным по свойству (HistoryDealGetInteger(Ticket,DEAL_ENTRY)==DEAL_ENTRY_IN).

Цена закрытия (частичного закрытия) - это свойство сделки (HistoryDealGetDouble(Ticket,DEAL_PRICE)) только отобранное по свойству (HistoryDealGetInteger(Ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT).

Цена позиции после двух входов: ([Цена сделки 1]*[Объем сделки 1]+ [Цена сделки 2]*[Объем сделки 2])/([Объем сделки 1]+[Объем сделки 2]) и т.д.

Позиция закрыта, если сумма объемов входа, равна сумме объемов выхода (VolIn1+VolIn2+VolIn3-VolOut1-VolOut2==0), т.е. их разница равна 0.

А вот как вы будете считать разницу в пунктах, все зависит от вашей фантазии.

Допустим. Вы открыли позицию, затем нарастили ее, потом частично закрыли, потом опять нарастили, потом частично закрыли и закрыли окончательно. Тут как вы будете считать количество пунктов? Для себя я считаю (код выше) количество пунктов по частичному закрытию.

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства сделок
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства сделок
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства сделок - Документация по MQL5
 
papaklass:

 <Сделка в MQL5 - факт исполнения ордера . Сделка имеет свойства ордера.>

Сделка - это расшифровка исполнения Вашего торгового приказа (ордера). Например, Вы отдали торговый приказ "купить EURUSD 10.0 Lots по цене 1.38234". Ваш ордер был наполнен 4-мя сделками:

- 2.0 лота по цене 1.38234,

- 1.5 лота по цене 1.38237,

- 3.5 лота по цене 1.38239,

- 3.0 лота по цене 1.38240.

----------------------------------------------------------- 

<

Цена открытия, добавления (наращивания) - это свойство сделки (HistoryDealGetDouble(Ticket,DEAL_PRICE)) с отобранным по свойству (HistoryDealGetInteger(Ticket,DEAL_ENTRY)==DEAL_ENTRY_IN).

Цена закрытия (частичного закрытия) - это свойство сделки (HistoryDealGetDouble(Ticket,DEAL_PRICE)) только отобранное по свойству (HistoryDealGetInteger(Ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT).

>

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

---------------------------------------------------------

<А вот как вы будете считать разницу в пунктах, все зависит от вашей фантазии.>

Прибыль в пунктах вычисляется по формуле:                                     количество пунктов = цена закрытия - цена открытия.                         Фантазии здесь неуместны. :)

И последнее. Не трудно догадаться, что вычислить прибыль можно только у той категории (позиция, трейд), которая обладает ценами открытия и закрытия. У сделки этих цен нет, тогда что возвращает свойство сделки DEAL_PROFIT ?

DEAL_PROFIT возвращает прибыль в валюте депозита при выходе из сделки. Вы же все знаете )))))))))
Причина обращения: