Cómo crear señales de trading con MQL5: Estrategia de dos EMA con filtro intradía

Mike 2011.01.13 23:32 13 0 0
Archivos adjuntos

MQL5 Wizard permite generar automáticamente el código de Asesores Expertos (EAs). Para más detalles, puedes consultar Creación de Asesores Expertos en MQL5 Wizard.

La estrategia que nos ocupa se basa en señales de trading generadas por dos medias móviles exponenciales. Este tipo de medias son efectivas en tendencia, pero pueden generar muchas señales falsas en otras condiciones. Una forma de mejorar la estrategia es mediante el uso de filtros temporales, como abrir nuevas posiciones solo durante la sesión europea del mercado de divisas (FOREX).

En este artículo, analizaremos una estrategia que utiliza el cruce de dos medias móviles exponenciales (una rápida y otra lenta) junto con un filtro temporal intradía. Esta estrategia se denomina "Señales basadas en el cruce de dos EMA con filtro intradía" cuando se crea el EA automáticamente en MQL5 Wizard.

Señales de trading:

  • Abrir posición larga: cuando la EMA rápida cruza hacia arriba la EMA lenta y se cumplen las condiciones del filtro temporal intradía.
  • Abrir posición corta: cuando la EMA rápida cruza hacia abajo la EMA lenta y se cumplen las condiciones del filtro temporal intradía.

Esta estrategia está implementada en la clase CSignal2EMA_ITF.

La filtración de señales basada en períodos de tiempo específicos se implementa en la clase CSignalITF. Como ejemplo, consideraremos la clase CSignal2EMA_ITF, que contiene un objeto de la clase CSignalITF.

El sistema de trading se basa en órdenes pendientes, donde los niveles de precio se calculan en función de los valores de las medias móviles y se utiliza el ATR (Rango Verdadero Promedio).

Figura 1. Señales de trading basadas en el cruce de dos EMA con filtro intradía

Figura 1. Señales de trading basadas en el cruce de dos EMA con filtro intradía

Señales de trading

La estrategia de trading se implementa en CSignal2EMA_ITF, que tiene métodos protegidos que facilitan el acceso a los valores de los indicadores:

 double  FastEMA(int ind)      // devuelve el valor de la EMA rápida de la barra double  SlowEMA(int ind)      // devuelve el valor de la EMA lenta de la barra double  StateFastEMA(int ind) // devuelve el valor positivo/negativo si la EMA rápida ha aumentado/disminuido double  StateSlowEMA(int ind) // devuelve el valor positivo/negativo si la EMA lenta ha aumentado/disminuido double  StateEMA(int ind)     // devuelve la diferencia entre la EMA rápida y la lenta double  ATR(int ind)          // devuelve el valor del ATR de la barra


La característica de este sistema es la siguiente: el trading depende del parámetro de entrada Limit. Según su signo, hay diferentes casos:

  1. Limit>0. Entrará en la retrocesión cuando haya un falso rompimiento de la media móvil a un precio mejor que el precio de mercado (se colocarán órdenes de Buy Limit y Sell Limit dependiendo de la señal de trading).
  2. Limit<0. Entrará en la dirección del movimiento del precio (se colocarán órdenes de Buy Stop y Sell Stop dependiendo de la señal de trading).
  3. Limit=0. En este caso, operará utilizando los precios de mercado.


1. Abrir posición larga

Se verifica la condición para abrir una posición larga: si la diferencia entre la EMA rápida y la EMA lenta en la última barra cerrada ha cambiado de signo de "-" a "+" (StateEMA(1)>0 && StateEMA(2)<0).

Luego, se chequean las condiciones del filtro temporal intradía llamando al método CheckOpenLong() de la clase CSignalITF. Si el trading está permitido, se calculará el nivel de precio base (el valor de la media móvil) y el rango del valor ATR de la última barra cerrada.

Dependiendo del signo del parámetro de entrada Limit, se colocará la orden pendiente de compra. El precio de la orden, los niveles de Take Profit y Stop Loss se calculan en relación al nivel de precio base (en unidades de ATR). El tiempo de expiración de la orden se define (en barras) mediante el parámetro de entrada Expiration.

//+------------------------------------------------------------------+ //| Verifica las condiciones para abrir una posición larga (compra)     | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration)   {    if(!(StateEMA(1)>0 && StateEMA(2)<0))                    return(false);    if(!m_time_filter.CheckOpenLong(price,sl,tp,expiration)) return(false); //---    double ema=SlowEMA(1);    double atr=ATR(1);    double spread=m_symbol.Ask()-m_symbol.Bid(); //---    price=m_symbol.NormalizePrice(ema-m_limit*atr+spread);    sl   =m_symbol.NormalizePrice(price+m_stop_loss*atr);    tp   =m_symbol.NormalizePrice(price-m_take_profit*atr);    expiration+=m_expiration*PeriodSeconds(m_period); //---    return(true);   }

2. Cerrar posición larga

En este caso, la función que verifica las condiciones para cerrar una posición larga siempre devuelve falso, es decir, se asume que la posición larga se cerrará por Take Profit o Stop Loss. Si es necesario, puedes escribir tu propio código para implementar este método.

//+------------------------------------------------------------------+ //| Verifica las condiciones para cerrar posición larga                | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckCloseLong(double& price)   {    return(false);   }


3. Abrir posición corta

Se verifica la condición para abrir una posición corta: si la diferencia entre la EMA rápida y la EMA lenta en la última barra cerrada ha cambiado de signo de "+" a "-" (StateEMA(1)<0 && StateEMA(2)>0).

Luego, se chequean las condiciones del filtro temporal intradía llamando al método CheckOpenLong() de la clase CSignalITF. Si el trading está permitido, se calculará el nivel de precio base (el valor de la media móvil) y el rango del valor ATR de la última barra cerrada.

Dependiendo del signo del parámetro de entrada Limit, se colocará la orden pendiente de venta. El precio de la orden, los niveles de Take Profit y Stop Loss se calculan en relación al nivel de precio base (en unidades de ATR). El tiempo de expiración de la orden se define (en barras) mediante el parámetro de entrada Expiration.

//+------------------------------------------------------------------+ //| Verifica las condiciones para abrir posición corta (venta)       | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration)   {    if(!(StateEMA(1)<0 && StateEMA(2)>0))                     return(false);    if(!m_time_filter.CheckOpenShort(price,sl,tp,expiration)) return(false); //---    double ema=SlowEMA(1);    double atr=ATR(1); //---    price      =m_symbol.NormalizePrice(ema+m_limit*atr);    sl         =m_symbol.NormalizePrice(price+m_stop_loss*atr);    tp         =m_symbol.NormalizePrice(price-m_take_profit*atr);    expiration+=m_expiration*PeriodSeconds(m_period); //---    return(true);   }

4. Cerrar posición corta

En este caso, la función que verifica las condiciones para cerrar una posición corta siempre devuelve falso, es decir, se asume que la posición se cerrará por Take Profit o Stop Loss. Si es necesario, puedes escribir tu propio código para implementar este método.

//+------------------------------------------------------------------+ //| Verifica las condiciones para cerrar posición corta               | //+------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckCloseShort(double& price)   {    return(false);   }


5. Trailing Stop de Orden Pendiente de Compra

El Asesor Experto seguirá las órdenes pendientes dependiendo del valor actual de la media móvil y el ATR.

El sistema de trading colocará órdenes pendientes basadas en las señales de trading. Si la orden se ha colocado correctamente, seguirá la orden pendiente junto a la media móvil. La orden se ejecutará si el precio del mercado alcanza el precio de la orden.
//+--------------------------------------------------------------------+ //| Verifica las condiciones para modificar la orden pendiente de compra| //+--------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckTrailingOrderLong(COrderInfo* order,double& price)   { //--- verificar    if(order==NULL) return(false); //---    double ema=SlowEMA(1);    double atr=ATR(1);    double spread=m_symbol.Ask()-m_symbol.Bid(); //---    price=m_symbol.NormalizePrice(ema-m_limit*atr+spread); //---    return(true);   }


6. Trailing Stop de Orden Pendiente de Venta

El Asesor Experto seguirá las órdenes pendientes dependiendo del valor actual de la media móvil y el ATR.

La orden se ejecutará si el precio del mercado alcanza el precio de la orden.

//+--------------------------------------------------------------------+ //| Verifica las condiciones para modificar la orden pendiente de venta | //+--------------------------------------------------------------------+ bool CSignal2EMA_ITF::CheckTrailingOrderShort(COrderInfo* order,double& price)   { //--- verificar    if(order==NULL) return(false); //---    double ema=SlowEMA(1);    double atr=ATR(1); //---    price=m_symbol.NormalizePrice(ema+m_limit*atr); //---    return(true);   }

Creando un Asesor Experto usando MQL5 Wizard

Para crear un robot de trading basado en la estrategia, debes seleccionar las propiedades de la señal como "Señales basadas en el cruce de dos EMA con filtro intradía" en la opción de "Creación de Asesores Expertos Listos" de MQL5 Wizard:

Figura 2. Selecciona

Figura 2. Selecciona "Señales basadas en el cruce de dos EMA con filtro intradía" en MQL5 Wizard

A continuación, debes especificar el algoritmo de trailing stop necesario y el sistema de gestión de dinero y riesgo. El código del Asesor Experto se generará automáticamente, podrás compilarlo y probarlo en el Tester de Estrategias del terminal cliente de MetaTrader 5.


Resultados de Pruebas

Veamos el backtesting del Asesor Experto sobre datos históricos (EUenSD H1, periodo de prueba: 1.1.2010-05.01.2011, PeriodFastEMA=5, PeriodSlowEMA=30, PeriodATR=7, Limit=1.2, StopLoss=5, TakeProfit=8, Expiration=4, GoodMinuteOfHour=-1, BadMinutesOfHour=0, GoodHourOfDay=-1, BadHoursOfDay=0, GoodDayOfWeek=-1, BadDaysOfWeek=0).

En la creación del Asesor Experto utilizamos un volumen fijo (Trading con Lote Fijo, 0.1), no se utiliza algoritmo de Trailing Stop (Trailing no utilizado).

Figura 3. Resultados de las pruebas del Asesor Experto con señales de trading, basadas en el cruce de dos EMA sin uso de filtro ITF

Figura 3. Resultados de las pruebas del Asesor Experto con señales de trading, basadas en el cruce de dos EMA sin uso de filtro ITF

Como no se utilizó el filtro intradía, hay muchas señales falsas. Las señales de trading pueden mejorarse si realizamos un análisis de los resultados de las operaciones en función de las horas de trading.

En nuestro caso, hemos encontrado que el cruce de dos EMA proporciona muchas señales falsas desde las 6:00 hasta las 23:59. Podemos especificar el filtro temporal intradía configurando los parámetros del filtro.

Por ejemplo, podemos especificar un filtro de tiempo que permita abrir posiciones solo desde las 0:00 hasta las 5:59. Esto se puede lograr configurando el valor de BadHoursOfDay=16777152=111111111111111111000000b. Todas las demás horas de trading son "malas", por lo que es mejor prohibir la apertura de nuevas posiciones desde las 6:00 hasta el final del día.

Al establecer el valor de BadHoursOfDay=16777152, filtraremos muchas señales falsas:

Figura 4. Resultados de las pruebas del Asesor Experto con señales de trading, basadas en el cruce de dos EMA con filtro de tiempo (BadHoursofDay=16777152)

Figura 4. Resultados de las pruebas del Asesor Experto con señales de trading, basadas en el cruce de dos EMA con filtro de tiempo (BadHoursofDay=16777152)


La CSignalITF ofrece muchas otras características de filtrado temporal (solo especifica los minutos y horas "buenos" y "malos" dentro de la hora, horas dentro del día, días de la semana).

El uso de filtros de tiempo permite mejorar las señales de trading y tener en cuenta la dinámica del mercado (por ejemplo, las características de la sesión de trading).

Adjuntos: El archivo Signal2EMA-ITF.mqh con la clase CSignal2EMA_ITF debe colocarse en la carpeta terminal_data_folder\MQL5\Include\Expert\Signal.

El archivo expert_2ema_itf.mq5 contiene el código del Asesor Experto, creado utilizando MQL5 Wizard.


Lista
Comentarios 0