Obtención del "precio medio ponderado" de una posición abierta con varias transacciones

 

Alguien conoce si MQL5 implementa una función que facilite el "precio medio ponderado" que muestra el terminal en la "caja de herramientas" cuando se han ejecutado varias transacciones?

Uso la función adjunta que diseñé al efecto pero no calcula bien cuando hay transacciones DEAL_ENTRY_INOUT

//--------------------------------- PRECIO MEDIO PONDERADO de la posición actual --------------
double precioMedioPosic(string simb)
{
   int      i, total= 0, nTrans= 0;    //, cuenta= 0;
   ulong    ticket= 0;
   bool     exito= _No;
   string   simbPosic= "";
   double   precioTrans= 0.0, volumTrans= 0, resp= 0,
            volTotal= PositionGetDouble(POSITION_VOLUME);
   datetime horaApert= horaApertPosicion(simb);
   ENUM_DEAL_ENTRY tipoTrans= DEAL_ENTRY_IN;
   exito= volTotal>0 && HistorySelect(horaApert, TimeCurrent());
   if(exito)
   {
      nTrans= totalTransPosic(simb);
      total= HistoryDealsTotal();
      for(i=0; i<total; i++)
      {
         ticket= HistoryDealGetTicket(i);
         simbPosic= HistoryDealGetString(ticket, DEAL_SYMBOL);
         tipoTrans= HistoryDealGetInteger(ticket, DEAL_ENTRY);
         if(simbPosic==simb && (tipoTrans==DEAL_ENTRY_IN || tipoTrans==DEAL_ENTRY_INOUT))
         {
            precioTrans= HistoryDealGetDouble(HistoryDealGetTicket(i),DEAL_PRICE);
            volumTrans= HistoryDealGetDouble(ticket, DEAL_VOLUME);
            if(tipoTrans==DEAL_ENTRY_IN) resp= resp + precioTrans*volumTrans;
            else if(tipoTrans==DEAL_ENTRY_INOUT) resp= resp - precioTrans*volumTrans;
         }
         //cuenta++;
         //if(cuenta==nTrans) break;
      }
      resp= NormalizeDouble(resp/volTotal, digitosSimb(simb));
   }
   return(resp);
}


//--------------------------- RETORNA NUMERO DE TRANSACCIONES de la posición actual  --------------------------------
int totalTransPosic(string simb= NULL)
{
   int    i, total= 0, cuenta= 0;
   ulong    ticket;
   string simbPosic= "";
   datetime horaApert= horaApertPosicion(simb);
   ENUM_DEAL_ENTRY tipo= DEAL_ENTRY_IN;
   if(horaApert>0 && HistorySelect(horaApert, TimeCurrent()))
   {
      total=HistoryDealsTotal();
      for(i=0; i<total; i++)
      {
         ticket= HistoryDealGetTicket(i);
         simbPosic= HistoryDealGetString(ticket,DEAL_SYMBOL);
         tipo= HistoryDealGetInteger(ticket, DEAL_ENTRY);
         if(simbPosic==simb && (tipo==DEAL_ENTRY_IN || tipo==DEAL_ENTRY_INOUT)) cuenta++;
      }
   }
   return(cuenta);
}

 

Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Deal Properties
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Deal Properties
  • www.mql5.com
Standard Constants, Enumerations and Structures / Trade Constants / Deal Properties - Documentation on MQL5
 

Si es para la posición actual puede utilizar HistorySelectByPosition (), y luego tienes que tener en cuenta DEAL_OUT también, no sólo IN en INOUT.

De todos modos para la posición actual se puede obtener este valor directamente con PositionGetDouble (), así que por qué calcularlo?
 
angevoyageur:

Si es para la posición actual puede utilizar HistorySelectByPosition (), y luego tienes que tener en cuenta DEAL_OUT también, no sólo IN en INOUT.

De todos modos para la posición actual se puede obtener este valor directamente con PositionGetDouble (), así que por qué calcularlo?

Ruego aclaración: o yo estoy equivocado o...

PositionGetDouble(POSITION_PRICE_OPEN) proporciona el precio de apertura de la posición (en la primera transacción), aunque la traducción diga "precio de posición".

PositionGetDouble(POSITION_PRICE_CURRENT) informa del precio actual de la posición (igual al precio de cotización del símbolo), pero no es el "precio medio ponderado" informado por "caja de herramientas" del terminal, que es el que se aplica para calcular el resultado de la posición actual cuando se han efectuado varias transacciones.

¿Es así o estoy equivocado?.

 
josemiguel1812 :

Ruego aclaración: o yo estoy equivocado o...

PositionGetDouble( POSITION_PRICE_OPEN ) proporciona el precio de apertura de la posición (en la primera transacción), aunque la traducción diga "precio de posición".

PositionGetDouble( POSITION_PRICE_CURRENT ) informa del precio actual de la posición (igual al precio de cotización del símbolo), pero no es el "precio medio ponderado" informado por "caja de herramientas" del terminal, que es el que se aplica para calcular el resultado de la posición actual cuando se han efectuado varias transacciones.

¿Es así o estoy equivocado?.

POSITION_PRICE_OPEN = "precio medio ponderado" a menos que no he entendido bien lo que quieres decir con "precio medio ponderado".
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Position Properties
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Position Properties
  • www.mql5.com
Standard Constants, Enumerations and Structures / Trade Constants / Position Properties - Documentation on MQL5
 
angevoyageur:
POSITION_PRICE_OPEN = "precio medio ponderado" a menos que no he entendido bien lo que quieres decir con "precio medio ponderado".

1ª trans: 0,10 lote, precio 1,37800

2ª trans: 0,20 lote, precio 1,37200 

precio medio ponderado: (0,10x1,37800 + 0,20x1,37200) / (0,10+0,20)= 1,37400 (es el precio que aparece en "toolbox" en la columna entre "volumen" y "S/L")

 
josemiguel1812 :

1ª trans: 0,10 lote, precio 1,37800

2ª trans: 0,20 lote, precio 1,37200 

precio medio ponderado: (0,10x1,37800 + 0,20x1,37200) / (0,10+0,20)= 1,37400 (es el precio que aparece en "toolbox" en la columna entre "volumen" y "S/L")

Ok estamos de acuerdo, y lo que es el valor devuelto por ?

   PositionGetDouble(POSITION_PRICE_OPEN);
 
angevoyageur:

Ok estamos de acuerdo, y lo que es el valor devuelto por ?

Creo que PositionGetDouble(POSITION_PRICE_OPEN) devuelve 1,37800.

La función que yo he diseñado funciona bien con DEAL_ENTRY_IN y devuelve 1,37400, pero falla cuando hay alguna transacción DEAL_ENTRY_INOUT 

 
josemiguel1812 :

Creo que  PositionGetDouble(POSITION_PRICE_OPEN)  devuelve 1,37800.

La función que yo he diseñado funciona bien con  DEAL_ENTRY_IN devuelve 1,37400, pero falla cuando hay alguna transacción  DEAL_ENTRY_INOUT  

PositionGetDouble (POSITION_PRICE_OPEN) debe darle 1,37400.
 
angevoyageur:
PositionGetDouble (POSITION_PRICE_OPEN) debe darle 1,37400.
Gracias, lo compruebo.
 
josemiguel1812:
Gracias, lo compruebo.
josemiguel1812
:

Gracias, lo compruebo.

Tiene usted razón.

Mi error viene de que la explicación de POSITION_PRICE_OPEN que recoge "ayuda" no advierte que devuelve el "precio medio ponderado" cuando la posición tiene varias transacciones.

"Ayuda" de "toolbox" en el terminal si lo advierte.

Deberían tenerlo en cuenta para la próxima actualización. 

Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Position Properties
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Position Properties
  • www.mql5.com
Standard Constants, Enumerations and Structures / Trade Constants / Position Properties - Documentation on MQL5
 
josemiguel1812:

Tiene usted razón.

Mi error viene de que la explicación de POSITION_PRICE_OPEN que recoge "ayuda" no advierte que devuelve el "precio medio ponderado" cuando la posición tiene varias transacciones.

"Ayuda" de "toolbox" en el terminal si lo advierte.

Deberían tenerlo en cuenta para la próxima actualización. 

Me surge la duda siguiente:

Mi algoritmo de colocación de TP pide precio BID (posición BUY) con la estructura MqlTick

//-------------------------------- DATOS ULTIMO TICK  ------------------------------------------
double datoTick(string simb, mis_DATOS_TICK dato= _ASK)
{
   MqlTick ultimoTick;        //define variable tipo estructura MQLTICK
   double resp= -1;
   if (SymbolInfoTick(simb, ultimoTick))
   {
      switch (dato)
      {
         case _ASK: resp= ultimoTick.ask; break; 
         case _BID: resp= ultimoTick.bid; break; 
         case _LAST: resp= ultimoTick.last; break; 
         case _VOL: resp= (double)ultimoTick.volume; break; 
         case _TIME: resp= (double)ultimoTick.time;
      }
   }
   else Print("DatoTick no encontrado; función... ", __FUNCTION__);
   return(resp);
}

y luego suma los puntos de beneficio buscados. Y esto está bien si la posición tiene una sola transacción.

Pero si tiene dos o más transacciones, ese algoritmo me estaría estableciendo TP con respecto al precio de la última transacción. Entiendo que para establecer un TP correcto a partir de la segunda transacción debo obtener el precio con...

PositionGetDouble (POSITION_PRICE_OPEN)

que da precio medio ponderado BID y a ese valor sumar los puntos TP (BUY). Si estoy en SELL, al valor obtenido con POSITION_PRICE_OPEN deberé sumarle el spread para obtener ASK, y a continuación sumar restar puntos TP.

¿Es correcto mi razonamiento? 

Razón de la queja: