Как получить усредненную цену позиции по двум (или более) лотам с разными ценами?

 

Добрый день!

Прошу совета как можно получить необходимую усредненную цену. Известно, что по запросу ObjectGetDouble(0,"PRICE",OBJPROP_PRICE,0) мы получаем цену открытия позиции, не зависимо от перехода через ночь.

В случае с двумя (или более) лотами в одном направлении, но по разной цене (доливка), по запросу ObjectGetDouble(0,"PRICE",OBJPROP_PRICE,0) мы получаем цену открытия последнего лота, а не усредненную цену всей позиции.

Внимание вопрос:

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

 

Заранее спасибо! 

 
basler:

Добрый день!

Прошу совета как можно получить необходимую усредненную цену. Известно, что по запросу ObjectGetDouble(0,"PRICE",OBJPROP_PRICE,0) мы получаем цену открытия позиции, не зависимо от перехода через ночь.

В случае с двумя (или более) лотами в одном направлении, но по разной цене (доливка), по запросу ObjectGetDouble(0,"PRICE",OBJPROP_PRICE,0) мы получаем цену открытия последнего лота, а не усредненную цену всей позиции.

Внимание вопрос:

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

 

Заранее спасибо! 

Думаю что примерно так: цену каждого ордера умножаешь на его лотность и суммируешь. Потом делишь на суммарное количество лотов. 
 
Dmitiry Ananiev:
Думаю что примерно так ....

Даже и думать не надо. Это таки так! )))

А топикстартеру надо было бы подумать. Это ведь так интересно - решить головоломку самому! )))

Кстати, есть продолжение головоломки - как рассчитать эту точку Безубытка, если есть несколько разнонаправленных ордеров с разными лотами? ТопикСтартер, слабо самому решить? )))

 
Andrei Fandeev:

Даже и думать не надо. Это таки так! )))

А топикстартеру надо было бы подумать. Это ведь так интересно - решить головоломку самому! )))

Кстати, есть продолжение головоломки - как рассчитать эту точку Безубытка, если есть несколько разнонаправленных ордеров с разными лотами? ТопикСтартер, слабо самому решить? )))

Добрый день!

насколько я знаю в MQL5 нельзя создавать разнонаправленные ордера... у меня случай как раз про MQL5. 

 
basler:

насколько я знаю в MQL5 нельзя создавать разнонаправленные ордера... у меня случай как раз про MQL5. 

Я же не про практическое применение. Я про интересную головоломку.

Большинство головоломок не имеют практического применения.

 
basler:

Добрый день!

насколько я знаю в MQL5 нельзя создавать разнонаправленные ордера... у меня случай как раз про MQL5. 

Если MQL5 тогда цена открытия совокупной позы и есть точка безубытка.
 
basler:

Добрый день!

Прошу совета как можно получить необходимую усредненную цену. Известно, что по запросу ObjectGetDouble(0,"PRICE",OBJPROP_PRICE,0) мы получаем цену открытия позиции, не зависимо от перехода через ночь.

В случае с двумя (или более) лотами в одном направлении, но по разной цене (доливка), по запросу ObjectGetDouble(0,"PRICE",OBJPROP_PRICE,0) мы получаем цену открытия последнего лота, а не усредненную цену всей позиции.

Внимание вопрос:

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

 

Заранее спасибо! 

//+------------------------------------------------------------------+
//| Expert Get Position price function                               |
//+------------------------------------------------------------------+
double GetPositionPrice( const string aSymbol )
{
  double price_in = 0;
  double volume_in = 0;
  
  if ( PositionSelect( aSymbol ) )
  {
    ulong pos_id = ulong( PositionGetInteger( POSITION_IDENTIFIER ) );
    
    if ( pos_id > 0 )
    {
      if ( HistorySelectByPosition( pos_id ) )
      {
        int deals = HistoryDealsTotal();
      
        for( int i = 0; i < deals; i++ )
        {
          ulong deal_ticket = HistoryDealGetTicket( i );
          ulong order_ticket = ulong( HistoryDealGetInteger( deal_ticket, DEAL_ORDER ) );
        
          if ( order_ticket > 0 )
          {
            ENUM_DEAL_ENTRY deal_entry = ENUM_DEAL_ENTRY( HistoryDealGetInteger( deal_ticket, DEAL_ENTRY ) );
              
            if ( deal_entry == DEAL_ENTRY_IN )
            {
              double price = HistoryDealGetDouble( deal_ticket, DEAL_PRICE );
              double volume = HistoryDealGetDouble( deal_ticket, DEAL_VOLUME );
                                
              price_in += price * volume;
              volume_in += volume;  
            }
          }
        }
        if ( volume_in > 0 ) return( NormalizeDouble( price_in / volume_in, _Digits ) );
      }
      else
      {
          Print( "GetPositionPrice: Не возможно получить историю позиции по символу ", aSymbol );
      }
    }
    else
    {
      Print( "GetPositionPrice: Не возможно определить идентификатор позиции по символу ", aSymbol );
    }
  }
  return( 0 );
}
 
Andrei Fandeev:

Я же не про практическое применение. Я про интересную головоломку.

Большинство головоломок не имеют практического применения.

Тоже мне бином Ньютона, как говорил кот Бегемот )) Вычисляем для каждого ордера

double pureProfit = OrderProfit() - OrderCommission() + OrderSwap();

 Потом значения складываем, если плюс - можно усредняться, если минус - пьем пиво дальше ))

 
Alexey Volchanskiy:

Тоже мне бином Ньютона, как говорил кот Бегемот )) Вычисляем для каждого ордера

 Потом значения складываем, если плюс - можно усредняться, если минус - пьем пиво дальше ))

double pureProfit = OrderProfit() - OrderCommission() + OrderSwap();
У вас  опечатка, минус будет не правильно, комиссия как правило отрицательная, а минус на минус дает плюс. И тогда получится, что чистая прибыль будет вычислена неправильно. 
 
Vitalii Ananev:
У вас  опечатка, минус будет не правильно, комиссия как правило отрицательная, а минус на минус дает плюс. И тогда получится, что чистая прибыль будет вычислена неправильно. 

Да, погорячился, вы правы, тогда лучше так

double pureProfit = OrderProfit() - MathAbs(OrderCommission()) + OrderSwap();
 
Alexey Volchanskiy:

Да, погорячился, вы правы, тогда лучше так

Можно и так.

Без MatchAbs(), можно просто минус заменить на плюс. :)  

.... 

Для топик стартера.

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

   int OrderArray[];
   int count=Traders.GetOrder(OrderArray,true);
   double BuyLot=0;double SellLot=0;
   double Profit = 0;
   double SellProfit = 0;
   double BuyProfit  = 0;
   int BuyCount =0;
   int SellCount = 0;
   double TickValue = MarketInfo(Symbol(),MODE_TICKVALUE);
   if (count>0)
   {
      for (int i=0;i<=count-1;i++)
      {
         if (OrderSelect(OrderArray[i], SELECT_BY_TICKET, MODE_TRADES)) 
         {
            if (OrderType()==OP_BUY)
            {
               BuyLot=BuyLot+OrderLots();
               BuyProfit = BuyProfit + OrderProfit()+OrderCommission()+OrderSwap();
               BuyCount++;
            }
            if (OrderType()==OP_SELL)
            {
               SellLot=SellLot+OrderLots();
               SellProfit = SellProfit + OrderProfit()+OrderCommission()+OrderSwap();
               SellCount++;
            }
            
         }
         Profit = Profit + OrderProfit()+OrderCommission()+OrderSwap(); //общий профит всех ордеров
      }
      double UrBezB = 0;
      double UrBezS = 0; 
      if (BuyLot > 0)
      {    
         UrBezB = Bid - (BuyProfit / (TickValue * BuyLot) * Point);     //уровень безубытка для BUY ордеров
         UrBezB = UrBezB + MarketInfo(Symbol(),MODE_SPREAD)*2*Point();
         UrBezB = NormalizeDouble(UrBezB,Digits());
      }
      if (SellLot > 0)   
      {
         UrBezS = Ask + (SellProfit / (TickValue * SellLot) * Point);   //уровень безубытка для SELL ордеров
         UrBezS = UrBezS - MarketInfo(Symbol(),MODE_SPREAD)*2*Point();
         UrBezS = NormalizeDouble(UrBezS,Digits());
      }
      //расчет уровня общего безубытка
      double UrObBez = 0;
      if (BuyLot > 0 && SellLot > 0)
      {
         if (BuyLot > SellLot) 
            UrObBez = Bid - ((BuyProfit + SellProfit) / (TickValue * (BuyLot-SellLot)) * Point);   
         if (BuyLot < SellLot) 
            UrObBez = Ask + ((BuyProfit + SellProfit) / (TickValue * (SellLot-BuyLot)) * Point);
         if (BuyLot == SellLot) UrObBez = 0;
         UrObBez = NormalizeDouble(UrObBez,Digits());   
      }
      //расчет уровня общего безубытка
      if (BuyLot > 0 && SellLot == 0)  bez_label.Text("Level without loss BUY  = "+DoubleToString(UrBezB,Digits));
      if (BuyLot == 0 && SellLot > 0)  bez_label.Text("Level without loss SELL = "+DoubleToString(UrBezS,Digits));
      if (BuyLot > 0 && SellLot > 0)  bez_label.Text("Level without loss SELL and BUY = "+DoubleToString(UrObBez,Digits));      
      if (BuyLot == SellLot) 
         bez_label.Text("Level without loss BUY  = "+DoubleToString(UrBezB,Digits)+"; SELL = "+DoubleToString(UrBezS,Digits) );    
            
   }else bez_label.Text("No open orders"); 
Причина обращения: