Discusión sobre el artículo "La implementación del modo multidivisa en MetaTrader 5" - página 5

 
Lazarev:

dime

1. si sólo necesito Bid y Ask de otras divisas, ¿es justo usar "espías"?

2. es sólo una idea, ¿no existe la posibilidad en la función onChartEvent de comprobar eventos de otras divisas y no sólo de la divisa actual?

3. ¿es posible establecer el valor del temporizador en menos de uno en el evento onTimer, para que descargue el valor de las cotizaciones mucho más a menudo y, en consecuencia, se retrase respecto al tiempo del último tick en el tiempo mínimo?

4. ¿o es posible utilizar "CHARTEVENT_CUSTOM+n" para comprobar, en mi caso, el cruce de mashes en otros gráficos?

1. Utilizando.

2. Hay una opción. El evento de otra divisa debe enviarse al gráfico donde está configurado el EA con OnChartEvent().

3. No. Uno es el mínimo.

4. Puede.

 

He creado un simple "indicador espía" SendEvent.mq5, que envía un evento cuando llega una nueva cotización:

#property indicator_chart_window
#property indicator_plots 0
int OnInit()
  {
   return(0);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   EventChartCustom(0,1,0,0,_Symbol);
   return(rates_total);
  }

He creado un sencillo Asesor Experto que recibe eventos de este indicador e intenta realizar una operación de trading (aquí una parte, el texto completo está en el archivo adjunto):

void OnChartEvent(const int id, // Controlador de eventos ChartEvent
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)            // sparam contiene el nombre del instrumento
  {
      // solicitar Digit,Point,Ask,Bid para el instrumento para el que se ha producido el evento
      if(!SymbolInfoInteger(sparam,SYMBOL_DIGITS,dig)) Print("SymbolInfoInteger(SYMBOL_DIGITS) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_POINT,p)) Print("SymbolInfoDouble(SYMBOL_POINT) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_BID,Bid)) Print("SymbolInfoDouble(SYMBOL_BID) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_ASK,Ask)) Print("SymbolInfoDouble(SYMBOL_ASK) ERROR!");
      d=(int)dig;
      if(1>0) // siempre compramos
        {
         q.action=TRADE_ACTION_DEAL; // rellenar la estructura MqlTradeRequest e intentar realizar una operación comercial
         q.symbol=sparam; // sparam contiene el nombre de la herramienta
         q.volume=Lot;
         q.price=NormalizeDouble(Ask,d);
         q.sl=NormalizeDouble(Ask-p*StopLoss,d);
         q.tp=NormalizeDouble(Ask+p*TakeProfit,d);
         q.deviation=0;
         q.type=ORDER_TYPE_BUY;
         q.type_filling=ORDER_FILLING_FOK;
         // comprobar las propiedades actuales de la herramienta
         Print("Bid=",DoubleToString(Bid,8),", Ask=",DoubleToString(Ask,8),", Digits=",d,", Points=",DoubleToString(p,8));
         // comprueba la estructura de la solicitud de operación que enviaremos
         Print("q.action=",q.action,", q.symbol=",q.symbol,", q.volume=",q.volume,", q.price=",DoubleToString(q.price,d),", q.sl=",DoubleToString(q.sl,d),", q.tp=",DoubleToString(q.tp,d),", q.deviation=",q.deviation,", q.type=",q.type,", q.type_filling=",q.type_filling);
         Print(OrderCheck(q,ch));                                  // comprobar si se puede realizar una operación comercial
         Print("ch.retcode=",ch.retcode,", ch.comment=",ch.comment); // resultado
         Print("OrderSend:",OrderSend(q,s));                        // intento de realizar una operación comercial
         Print("s.retcode=",s.retcode,", s.comment=",s.comment);     // resultado
        }
      if(0>0) // si se corrige la condición, venderemos
        {
         // аналогично для продажи
        }
     }
  }

El Asesor Experto recibe eventos del indicador, pero en el tester (tanto con visualización como sin ella) no puede realizar una operación de trading - se devuelve el error "Invalid Request", código de retorno 10013. En tiempo real funciona normalmente. Si la operación de comercio en el Asesor Experto se realiza desde OnTick() en lugar de OnChartEvent() - también funciona bien.

He insertado el envío de la solicitud de comercio en la plantilla de Asesor Experto ofrecida por el autor del artículo en CodeBase - también las operaciones de comercio no funcionan (el mismo error).

¿Puede alguien decirme cuál es la razón? He leído en este hilo que OnChartEvent( ) no se procesa en el probador, pero en este caso los eventos enviados por el indicador se procesan en el probador, pero es imposible ejecutar una operación comercial desde OnChartEvent() en el probador.

Archivos adjuntos:
ea.mq5  4 kb
SendEvent.mq5  1 kb
[Eliminado]  
zdd:

He creado un simple "indicador-espía" SendEvent.mq5, que envía un evento cuando llega una nueva cotización:

Creé un simple Asesor Experto que recibe eventos de este indicador e intenta hacer una operación (doy una parte, el texto completo está en el archivo adjunto):

El Asesor Experto recibe eventos del indicador, pero en el tester (tanto con visualización como sin ella) no puede realizar una operación de trading - se devuelve el error "Solicitud no válida", código de retorno 10013. En tiempo real funciona normalmente. Si una operación comercial en el Asesor Experto se realiza desde OnTick() en lugar de OnChartEvent() - también funciona bien.

He insertado el envío de la solicitud de comercio en la plantilla del Asesor Experto ofrecida por el autor del artículo en CodeBase - las operaciones de comercio tampoco funcionan (el mismo error).

¿Puede alguien decirme cuál es la razón? He leído en este hilo que OnChartEvent( ) no se procesa en el tester, pero en este caso los eventos enviados por el indicador sí se procesan en el tester, pero es imposible ejecutar una operación de trade desde OnChartEvent() en el tester.

Intenta traerme el pez a la cabeza. Por supuesto, la lógica no es completa y muy tonto, pero parece ser muy similar a lo que usted necesita.

Al menos las posiciones del mercado se abre tanto en el probador y en la demo.

No sé por qué (me da pereza averiguarlo), pero tu ejemplo me daba 10013 en cualquier situación.

PS

Es mejor enlazar a objetos estándar (como CAccountInfo y CTrade). Pero si tienes la paciencia de escribirlo todo tú mismo, me alegraré.

Por cierto, la implementación del propio espía es mejor tomarla del artículo, o hacer una copia modificable (yo, por ejemplo, sugiero sustituir este año "(long)_Period" por la fecha-hora de envío del evento u otra información útil). Su variante es de alguna manera bastante "crudo".

Archivos adjuntos:
DemoEA.mq5  20 kb
 
Interesting:

A ver si consigues que funcione mi pez. La lógica es incompleta y muy obtusa, pero parece ser muy similar a lo que necesitas.

Gracias, lo tengo. Si declaras las estructuras MqlTradeRequest y MqlTradeResult a nivel global, ¡funciona!
 
Muchas gracias por el artículo.
 

Estoy tratando de obtener los precios de tres pares EURUSD, EURGBP, GBPUSD. Todo funciona bien cuando selecciono "Todos los ticks" o "Sólo precios abiertos" en el probador de estrategias. Pero si selecciono "Cada tick basado en ticks reales", entonces por alguna razón pueden ocurrir varios eventos de "Nueva Barra" en un minuto para un instrumento.

Para repetir, puede seleccionar un intervalo, por ejemplo de 2016.07.15 a 2016.07.19. Aquí está un registro de ejemplo, ver el minuto 7, minuto 9:

2016.07.15 00:05:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333

2016.07.15 00:05:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:05:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33399

2016.07.15 00:06:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8334

2016.07.15 00:06:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:06:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33382

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33381

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33384

2016.07.15 00:08:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83329

2016.07.15 00:08:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11167

2016.07.15 00:08:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

2016.07.15 00:09:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33396

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

¿A qué se debe este comportamiento cuando se selecciona el modo "Todos los ticks basados en ticks reales"?
 
ooparadise:

Estoy tratando de obtener los precios de tres pares EURUSD, EURGBP, GBPUSD. Todo funciona bien cuando selecciono "Todos los ticks" o "Sólo precios abiertos" en el probador de estrategias. Pero si selecciono "Cada tick basado en ticks reales", entonces por alguna razón pueden ocurrir varios eventos de "Nueva Barra" en un minuto para un instrumento.

Para repetir, puede seleccionar un intervalo, por ejemplo de 2016.07.15 a 2016.07.19. Aquí está un registro de ejemplo, ver el minuto 7, minuto 9:

¿A qué se debe este comportamiento cuando se selecciona el modo "Todos los ticks basados en ticks reales"?

¿Cómo se captura el evento "Nueva barra"? En la versión 1375 se ha mejorado la precisión de la llegada de los ticks a milisegundos:

Probador: Añadido soporte para la precisión de tiempo a milisegundos. Anteriormente en el probador de estrategias el quantum de tiempo era de un segundo.

  • Las funciones EventSetMillisecondTimer y Sleep funcionan ahora con mayor precisión en el probador de estrategias.
  • Se ha incrementado la precisión del envío de ticks en las pruebas de Asesores Expertos multidivisa. Anteriormente, si se colocaban varios ticks en un segundo (el volumen de ticks de una barra de un minuto es superior a 60), a todos ellos se les asignaba el mismo tiempo. Al probar Asesores Expertos monodivisa, no importa mucho, ya que los ticks simplemente se pasan al Asesor Experto secuencialmente. Sin embargo, cuando se prueban varios pares, es importante saber qué tick del par llegó primero. Anteriormente, los ticks de cada símbolo se transmitían al Asesor Experto secuencialmente: primero todos los ticks de un símbolo durante un segundo, luego todos los ticks de otro símbolo. Ahora se transmiten teniendo en cuenta los milisegundos.

    Cuando se realizan pruebas con ticks reales, los milisegundos se toman de los datos originales del tick. Al generar los ticks, los milisegundos se deletrean según el volumen del tick. Por ejemplo, si hay 3 ticks en un segundo, se les asignará el tiempo 000, 333 y 666 milisegundos.
 

Capto unanueva barra de la forma en que está escrito en el artículo. Es decir, el indicador envía el evento "Nueva Barra" de esta manera (en comparación con el tiempo anterior minutos, horas, días, meses):

   double price_current=price[rates_total-1];

   TimeCurrent(time);

   if(prev_calculated==0)

     {

      EventCustom(CHARTEVENT_INIT,price_current);

      prev_time=time; 

      return(rates_total);

     }

//--- new tick

   if((flag_event & CHARTEVENT_TICK)!=0) EventCustom(CHARTEVENT_TICK,price_current);       


//--- check change time

   if(time.min==prev_time.min && 

      time.hour==prev_time.hour && 

      time.day==prev_time.day &&

      time.mon==prev_time.mon) return(rates_total);


//--- new minute

   if((flag_event & CHARTEVENT_NEWBAR_M1)!=0) EventCustom(CHARTEVENT_NEWBAR_M1,price_current); 

ACTUALIZACIÓN: El problema desapareció al instalar la build 1375.

 

Gracias por este enorme artículo. No había oído hablar hasta ahora de EventChartCustom. Estaba probando otros eventos de gráficos pero sólo tenían en cuenta los eventos causados por la acción humana. Esto soluciona muchas cosas.

Por cierto, trabajo en MQL4, me pasaba al 98% lo mismo.

Saludos

 

Muchas gracias por esto, es muy útil. ¡Buen trabajo!