EAs multidivisa: Cálculo del resultado parcial de un símbolo.

Para añadir comentario, por favor Autorícese o regístrese
Jose Miguel Soriano
4906
Jose Miguel Soriano  

Tengo hecha una función que lo resuelve...

//---------------------------------- RESULTADO PARCIAL DE UN SÍMBOLO ---------------------------------------
double resultParcialSimb(string simb, int numSimbs= 1, datetime tmpIni= 0)
{
   string simbT;
   int k, nTransac;
   ulong ticketTrans;
   double resultS= numSimbs==1? benefCuenta(): 0.0;
   if(numSimbs>1)
   {
      HistorySelect(tmpIni, TimeCurrent());
      nTransac= HistoryDealsTotal();
      for(k=0; k<nTransac; k++)        //la transacción 0 sólo informa del balance inicial
      {
         ticketTrans= HistoryDealGetTicket(k);
         simbT= simbTrans(ticketTrans);
         if(simb==simbT && esTransSalida(ticketTrans)) resultS= resultS+resultTrans(ticketTrans);
      }
   }
   return(resultS);
}

Pero ralentiza mucho las optimizaciones si la aplico en cada apertura de vela, y no digamos en cada tick, para comprobar el nivel de beneficio alcanzado por el símbolo en relación al capital inicial y, por ejemplo, ordenar cierre de posición, dado que recorre todo el historial.

¿Alguien conoce otra solución? ¿Existe una función que lo informe directamente? 

Rogerio Figurelli
Moderador
53101
Rogerio Figurelli  
josemiguel1812:

Tengo hecha una función que lo resuelve...

Pero ralentiza mucho las optimizaciones si la aplico en cada apertura de vela, y no digamos en cada tick, para comprobar el nivel de beneficio alcanzado por el símbolo en relación al capital inicial y, por ejemplo, ordenar cierre de posición, dado que recorre todo el historial.

¿Alguien conoce otra solución? ¿Existe una función que lo informe directamente? 

Hola, mi opinión es que el problema no es la función, que parece apropriado, pero el control de tiempo que va a llamar a la función.
Jose Miguel Soriano
4906
Jose Miguel Soriano  
figurelli:
Hola, mi opinión es que el problema no es la función, que parece apropriado, pero el control de tiempo que va a llamar a la función.

Ya encontré la solución, como Juan Palomo... "yo me lo guiso, yo me lo como": lo que sigue está comprobado y funciona.

Si usamos un sólo símbolo el beneficio de la cuenta lo calculo tal que así...

//---------------------------- BENEFICIO DE LA CUENTA ----------------------
double benefCuenta()
{
   double benef= 0;
   ulong nTransac, ticketTrans;
   HistorySelect(0, TimeLocal());
   nTransac= HistoryDealsTotal();
   for(int k=0; k<(int)nTransac; k++)
   {
      ticketTrans= HistoryDealGetTicket(k);
      if(esTransSalida(ticketTrans)) benef= benef+resultTrans(ticketTrans);
   }
   return(benef);
}
//-------------------------------------  SALIDA DEL MERCADO  ------------------------------
bool esTransSalida(ulong ticket)
{           //salida o cierre de una posición
   bool resp= (HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT);
   return(resp);
}
//-------------------------------------- RESULTADO TRANSACCIÓN ----------------------------------
double resultTrans(ulong ticket)
{
   double result= 0;
   result= HistoryDealGetDouble(ticket, DEAL_PROFIT)+
           HistoryDealGetDouble(ticket, DEAL_SWAP)+
           HistoryDealGetDouble(ticket, DEAL_COMMISSION);
   return(result);
}

puesto que AccountInfoDouble(ACCOUNT_PROFIT) informa sólo del resultado acumulado en las posiciones abiertas (la cifra que aparece en "operaciones" de "caja de herramientas" en el terminal MT5).

Si usamos varios símbolos, en la función OnTrade (en la que entraremos sólo si el número de símbolos es mayor que 1) hago lo siguiente 

//------------------------------------------------ ON TRADE() --------------------------------------------------
void OnTrade()
{
   if(nSimbs>1)
   {
      datetime static tmpFinal= -1;
      tmpFinal= resultParcialSimbsTmp(arResultSimb, tmpFinal+1);    //tras cada transacción comprobamos y acumulamos el resultado de cada símbolo
   }

}
Double arResultSimb[];		//variable global
ArrayResize(arResultSimb, nSimbs);
//-------------------------------- CALCULA RESULTADO/SIMBOLO -------------------------------------------
datetime resultParcialSimbsTmp(double &arSimbsResult[], datetime tmpIniCalculo= 0)
{              //devuelve la hora hasta la que se ha hecho el último cálculo
   datetime tmpTrans= tmpIniCalculo, tmpUltCalculo= tmpIniCalculo;
   ENUM_DEAL_ENTRY tipoTrans;
   string simbT= "";
   int i, codS= 0, nTrans=0;
   ulong ticket= 0;
   if( nSimbs>1 && HistorySelect(tmpIniCalculo, TimeCurrent()) )
   {
      nTrans= HistoryDealsTotal();
      for(i=0; i<nTrans; i++)
      {
         ticket= HistoryDealGetTicket(i);
         tipoTrans= (ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket, DEAL_ENTRY);
         if(tipoTrans==DEAL_ENTRY_OUT || tipoTrans==DEAL_ENTRY_INOUT)
         {
            tmpTrans= (datetime)HistoryDealGetInteger(ticket, DEAL_TIME);
            simbT= HistoryDealGetString(ticket, DEAL_SYMBOL);
            codS= buscaCadArray(simbT, arNombreParesFX);
            if(codS>=0) arSimbsResult[codS]= arSimbsResult[codS] + resultTrans(ticket);
         }
      }
      tmpUltCalculo= tmpTrans;
   }   
   return(tmpUltCalculo);
}

 En arNombreParesFx[] (variable declarada global) tengo almacenados los nombres de los símbolos con los que trabajo; de ahí obtengo el índice que corresponde al símbolo. Declaro como variable global arResultSimb[]. Cada vez que se realiza una transacción el evento "trade" hace entrar en OnTrade() y se llama a la función resultParcialSimbsTmp() que recorre el historial sólo desde el momento último en que se llamó (almacenado en la variable estática tmpFinal) hasta el momento actual, evitando recorrer todo el historial de transacciones; resultParcialSimbsTmp() me devuelve la hora de la última transacción de salida analizada.

En todo momento arSimbsResult[] me tiene almacenado el resultado acumulado de cada símbolo. Si quiero saber "equity" o patrimonio actual de cada símbolo le sumo el resultado de la posición actual abierta con benefPosicion(simb)...

double benefPosicion(string simb)
  {
   double resp= 0;
   if(PositionSelect(simb)) resp= PositionGetDouble(POSITION_PROFIT);
   return(resp);
  }

 A ver si se anima este foro...

Rogerio Figurelli
Moderador
53101
Rogerio Figurelli  
josemiguel1812:


 A ver si se anima este foro...

Muy bien, usar OnTrade() también es una buena idea para mayor velocidad en las optimizaciones.

Gracias por tu contribución en este foro.

Para añadir comentario, por favor Autorícese o regístrese