Mean price of open position

 

Hello.

Can the a mean price to be obtained by a function, when I open more positions (without closing previous ones)?

Example: I Make 1 BUY position. Then I have the green position line in the graph in the points location that the operation took place.

Now I make another 3 BUY positions. I have an arrow in the graph showing this position, and the (now 4) BUY positions green line goes

to the resulting mean points value and position on the screen.

Is there a function that will return this new mean position or it can only be calculated by knowing all previous positions?

 
mad_b:

Hello.

Can the a mean price to be obtained by a function, when I open more positions (without closing previous ones)?

Example: I Make 1 BUY position. Then I have the green position line in the graph in the points location that the operation took place.

Now I make another 3 BUY positions. I have an arrow in the graph showing this position, and the (now 4) BUY positions green line goes

to the resulting mean points value and position on the screen.

Is there a function that will return this new mean position or it can only be calculated by knowing all previous positions?

void OnStart()
{
   double price,size;
   if(getNetPriceAndPosition(price,size))
   {
      printf("The net position size is %s and the volume adjusted net entry price is %s",
         DoubleToString(size,2),
         DoubleToString(price,_Digits)
      );
   }
}




#include <Arrays\ArrayObj.mqh>

class Position : public CObject
{
 protected:
   const int   m_ticket;
 public:
   Position(int ticket): m_ticket(ticket) {}
   virtual int Compare(const CObject *node, const int mode = 0)const override
   {
      const Position *other = node;
      if(this.OpenTime() > other.OpenTime()) return 1;
      if(this.OpenTime() < other.OpenTime()) return -1;
      return 0;
   }
   int OpenTime()const
   {
      if(Select())
         return (int)OrderOpenTime();
      return -1;
   }
   bool Select()const {return OrderSelect(m_ticket, SELECT_BY_TICKET);}
};

bool getNetPriceAndPosition(double &result_net_price,
                            double &result_net_position_size,  
                            const int magic_number=0)
{
   CArrayObj m_list;

   for(int i = 0; i < OrdersTotal(); i++)
      if(OrderSelect(i, SELECT_BY_POS)
            && OrderSymbol() == _Symbol
            && OrderType() < 2
            && (magic_number == 0 || OrderMagicNumber() == magic_number)
      )
         m_list.Add(new Position(OrderTicket()));
   m_list.Sort();
   double net_position = 0.0;
   double net_price = 0.0;
   Position *pos = dynamic_cast<Position*>(m_list.At(0));
   if(!CheckPointer(pos))
      return false;
   for(int i = 0; pos != NULL; pos = m_list.At(++i))
   {
      if(pos.Select())
      {
         int    type  = OrderType();
         double lots  = type == OP_BUY ? OrderLots() : -OrderLots();
         double price = OrderOpenPrice();
         if(net_position == 0.0 && lots != 0.0)
         {
            net_position = lots;
            net_price    = price;
         }
         else if(net_position + lots == 0.0)
         {
            net_position = 0.0;
            net_price    = 0.0;
         }
         else if(net_position > 0.0 && net_position + lots > 0.0 && net_position + lots > net_position)
         {
            double total = (net_position * net_price) + (lots * price);
            net_position += lots;
            net_position = NormalizeDouble(net_position, 2);
            net_price = total / net_position;
         }
         else if(net_position > 0.0 && net_position + lots > 0.0 && net_position + lots < net_position)
         {
            net_position += lots;
            net_position = NormalizeDouble(net_position, 2);
         }
         else if(net_position < 0.0 && net_position + lots < 0.0 && net_position + lots < net_position)
         {
            double total = (fabs(net_position) * net_price) + (fabs(lots) * price);
            net_position += lots;
            net_position = NormalizeDouble(net_position, 2);
            net_price = total / fabs(net_position);
         }
         else if(net_position < 0.0 && net_position + lots < 0.0 && net_position + lots > net_position)
         {
            net_position += lots;
            net_position = NormalizeDouble(net_position, 2);
         }
         else if((net_position > 0.0 && net_position + lots < 0.0)
                 || (net_position < 0.0 && net_position + lots > 0.0))
         {
            net_position += lots;
            net_position = NormalizeDouble(net_position, 2);
            net_price = price;
         }
      }
   }
   result_net_price = NormalizeDouble(net_price, _Digits);
   result_net_position_size = net_position;
   return true;
}
Reason: