English Русский 中文 Deutsch 日本語 Português
preview
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 6): Recolector de señales de reversión a la media

Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 6): Recolector de señales de reversión a la media

MetaTrader 5Sistemas comerciales |
325 3
Christian Benjamin
Christian Benjamin

Introducción

La reversión a la media es una estrategia de trading interesante que muchos traders expertos usan para optimizar su visión del mercado. Este concepto gira en torno a la idea de que los precios de los activos tienden a volver a sus promedios históricos, lo que crea oportunidades para realizar operaciones en momentos estratégicos. Sin embargo, analizar manualmente los movimientos de los precios puede llevar mucho tiempo y ser propenso a descuidos. Ahí es donde la automatización puede mejorar significativamente la experiencia de negociación.

En este artículo, desarrollaremos un Asesor Experto MQL5 diseñado para identificar oportunidades de trading basadas en los principios de reversión a la media. Mediante el uso de una media móvil exponencial (Exponential Moving Average, EMA) de 50 períodos y el índice de fuerza relativa (Relative Strength Index, RSI), generaremos señales de entrada precisas que nos permitirán sacar provecho de las fluctuaciones del mercado. Para que el proceso de negociación sea aún más intuitivo, nuestro EA mostrará señales de compra y venta en forma de flechas visuales directamente en el gráfico, junto con un resumen informativo que detalla las señales.

Si desea optimizar sus operaciones y aprovechar el poder de la automatización, únase a nosotros para explorar cómo crear un Asesor Experto MQL5 que capture la esencia de la reversión a la media. Entremos en detalles y echemos un vistazo al índice.



¿Qué es la reversión a la media?

La reversión a la media es un concepto financiero que postula que los precios de los activos, los rendimientos u otras métricas del mercado tienden a revertir a su promedio histórico o «media» a medida que pasa el tiempo. Este promedio se puede calcular mediante diferentes métodos, incluyendo el precio medio durante un periodo de tiempo determinado, una media móvil o una rentabilidad de referencia estándar.

La teoría se basa en la creencia de que las fluctuaciones extremas del mercado suelen ser de corta duración y que, en última instancia, los precios se estabilizarán. Los operadores y analistas aprovechan este principio para detectar posibles oportunidades de negociación, especialmente cuando los precios se desvían notablemente de sus medias históricas.

Breve historia y origen

La reversión a la media es un concepto arraigado en la estadística y las finanzas, reconocido por primera vez a principios del siglo XX a través de los trabajos de matemáticos como Francis Galton. Aplicada originalmente en el estudio de fenómenos naturales, como la tendencia de los rasgos extremos en las poblaciones (por ejemplo, la altura) a revertir a la media a lo largo de las generaciones, la reversión a la media se convirtió más tarde en una piedra angular de la teoría financiera.
En los mercados financieros, esta idea fue popularizada por economistas como John Maynard Keynes, quien observó que los precios de los activos suelen oscilar en torno a sus valores fundamentales. Esto condujo al desarrollo de estrategias comerciales que aprovechan estas tendencias. Por ejemplo, durante la burbuja puntocom de finales de la década de 1990, muchas acciones tecnológicas sobrevaloradas acabaron volviendo a sus valores fundamentales, lo que demostró la reversión a la media en acción.

Ejemplos prácticos de reversión a la media

  • Mercado bursátil: Durante la pandemia de COVID-19, muchas acciones experimentaron fuertes desviaciones con respecto a sus medias históricas. Por ejemplo, las acciones del sector turístico cayeron drásticamente por debajo de sus promedios, pero luego se recuperaron a medida que el mercado se normalizó.
  • Pares de divisas: Los tipos de cambio de las divisas suelen volver a sus medios a largo plazo debido a las políticas de los bancos centrales y a los fundamentos económicos. Por ejemplo, el par USDJPY oscila históricamente dentro de un rango predecible a lo largo del tiempo.
  • Materias primas: Los precios del oro y del petróleo suelen mostrar un comportamiento de reversión a la media, volviendo a niveles históricos tras subidas o bajadas extremas de precios debido a acontecimientos geopolíticos.

Definición de la reversión a la media en el contexto de nuestro Asesor Experto

En el contexto de este proyecto, la reversión a la media se refiere a la tendencia del precio de un activo a volver a su nivel medio (media) después de moverse significativamente por encima o por debajo de él. Este principio constituye la base de las señales de trading que generará el Asesor Experto.

  • Media (EMA 50):El código utiliza una media móvil exponencial (EMA) de 50 períodos para representar la media. El EMA se ajusta dinámicamente a los datos de precios recientes, proporcionando un punto de referencia fiable para la tendencia actual del mercado. Cuando el precio se desvía significativamente de la EMA, esto indica una posible reversión. 
  • Reversión en acción: Se genera una señal de compra cuando el precio está por debajo de la media móvil exponencial (EMA) de 50 y el índice de fuerza relativa (RSI) está sobrevendido. El EA predice un movimiento alcista del precio de vuelta hacia la EMA. Por el contrario, cuando el precio está por encima de la media móvil exponencial (EMA) de 50 y el RSI está sobrecomprado, el EA anticipa una corrección a la baja del precio.


Resumen de la estrategia

Esta estrategia se basa en el concepto de reversión a la media, que sugiere que los precios tienden a volver a sus niveles medios tras desviaciones significativas. Este comportamiento crea oportunidades de negociación cuando se combina con indicadores fiables como la media móvil exponencial (EMA) de 50 y el índice de fuerza relativa (RSI).

  • Cómo funciona

La estrategia utiliza dos indicadores clave:

  1. La media móvil exponencial (EMA) de 50 actúa como referencia, representando el precio medio dinámico durante un periodo específico. 
  2. El RSI identifica condiciones de sobrecompra o sobreventa.

Cuando los precios se desvían demasiado de la media móvil exponencial (EMA) de 50 y el índice de fuerza relativa (RSI) confirma condiciones extremas, la estrategia asume una probable reversión hacia la media.

Concepto de reversión a la mediaPrecio 

Figura 1. Concepto de reversión a la media

El diagrama anterior (Figura 1) se ilustra los movimientos de precios en relación con la media móvil exponencial (EMA) y destaca las señales de trading activadas en niveles extremos del índice de fuerza relativa (RSI).

Se genera una señal de compra cuando:
El precio está por debajo de la media móvil exponencial (EMA) de 50, lo que indica una desviación a la baja. El índice de fuerza relativa (RSI) está por debajo de 30, lo que confirma un mercado sobrevendido. Esta configuración indica un posible rebote del precio hacia la media.

Una señal de venta se produce cuando:
El precio está por encima de la media móvil exponencial (EMA) de 50, lo que indica una desviación al alza. El índice de fuerza relativa (RSI) está por encima de 70, lo que confirma un mercado sobrecomprado. Esta configuración anticipa una corrección del precio hacia la media.

  • Señales visuales y resumen del texto:
Las flechas verdes indican señales de compra. Las flechas rojas indican señales de venta. En la esquina superior derecha del gráfico se muestra un resumen de texto con el tipo de señal (compra/venta). La estrategia incorpora reglas claras de stop loss y take profit:
  1. Stop Loss: Se coloca por debajo del mínimo reciente para las posiciones de compra y por encima del máximo reciente para las posiciones de venta.
  2. Take Profit: Objetivo cercano a la media móvil exponencial (EMA) de 50, donde se espera una reversión del precio.
  3. Mecanismo de espera. Para evitar señales redundantes y el exceso de operaciones, se aplica un período de espera. Después de una señal, la estrategia espera un número específico de barras antes de considerar nuevas señales. Esta función ayuda a reducir el ruido durante condiciones volátiles del mercado. 

El ATR (rango medio verdadero) se utiliza para establecer niveles dinámicos para fijar los valores de Take Profit (TP) y Stop Loss (SL).

  • Ventajas principales de la estrategia

Beneficio
Explicación
Lógica simple pero efectiva
Combina EMA y RSI para oportunidades confiables de reversión a la media.
Señales visuales 
Las flechas y los resúmenes de texto hacen que las señales sean claras y procesables.
Integración de la gestión de riesgo 
Las reglas claras de stop loss y take profit protegen las operaciones y gestionan el riesgo. 
Reducción de ruido Los períodos de espera ayudan a filtrar las señales redundantes en mercados volátiles.
Parámetros configurables Personaliza fácilmente el período EMA, los niveles RSI y la configuración del tiempo de espera.

  • El código MQL5 del Asesor Experto.

//+------------------------------------------------------------------+
//|                                        Mean Reversion Reaper.mq5 |
//|                              Copyright 2024, Christian Benjamin. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com"
#property version   "1.00"

#property strict
#property indicator_chart_window

//--- Input Parameters
input int EMA_Period = 50;                     // EMA Period
input int RSI_Period = 14;                     // RSI Period
input double RSI_Overbought = 70.0;            // RSI Overbought level
input double RSI_Oversold = 30.0;              // RSI Oversold level
input int CooldownBars = 3;                    // Cooldown bars between signals
input double ATR_Multiplier = 2.0;             // ATR Multiplier for TP and SL
input int ATR_Period = 14;                     // ATR Period
input color BuySignalColor = clrGreen;         // Buy signal arrow color
input color SellSignalColor = clrRed;          // Sell signal arrow color
input int ArrowSize = 2;                       // Arrow size
input color TextColor = clrDodgerBlue;         // Color for TP/SL text summary

//--- Global Variables
int EMA_Handle, RSI_Handle, ATR_Handle;
datetime lastSignalTime = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
// Create handles for indicators
   EMA_Handle = iMA(NULL, 0, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
   RSI_Handle = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE);
   ATR_Handle = iATR(NULL, 0, ATR_Period);

   if(EMA_Handle == INVALID_HANDLE || RSI_Handle == INVALID_HANDLE || ATR_Handle == INVALID_HANDLE)
     {
      Print("Failed to create indicator handles. Error: ", GetLastError());
      return INIT_FAILED;
     }

   Print("Mean Reversion EA initialized.");
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Clear the Signal Summary text object upon deinitialization
   ObjectDelete(0, "SignalSummary");
   Print("Mean Reversion EA deinitialized.");
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// Avoid repeating signals on cooldown
   if(BarsSinceLastSignal() < CooldownBars)
      return;

   double EMA_Value = GetEMA();
   double RSI_Value = GetRSI();
   double ATR_Value = GetATR();

   if(EMA_Value == 0 || RSI_Value == 0 || ATR_Value == 0)
      return;

   double closePrice = iClose(NULL, 0, 0); // Current close price
   double highPrice = iHigh(NULL, 0, 1);   // Previous bar high
   double lowPrice = iLow(NULL, 0, 1);     // Previous bar low

// Check for Buy Signal
   if(closePrice < EMA_Value && RSI_Value <= RSI_Oversold)
     {
      DrawSignalArrow("BuySignal", closePrice, BuySignalColor);
      DisplayTextSummary("BUY", closePrice, lowPrice, ATR_Value);
      UpdateSignalTime();
     }
// Check for Sell Signal
   else
      if(closePrice > EMA_Value && RSI_Value >= RSI_Overbought)
        {
         DrawSignalArrow("SellSignal", closePrice, SellSignalColor);
         DisplayTextSummary("SELL", closePrice, highPrice, ATR_Value);
         UpdateSignalTime();
        }
  }

//+------------------------------------------------------------------+
//| Get EMA Value                                                    |
//+------------------------------------------------------------------+
double GetEMA()
  {
   double emaValues[1];
   if(CopyBuffer(EMA_Handle, 0, 0, 1, emaValues) <= 0)
      return 0;
   return emaValues[0];
  }

//+------------------------------------------------------------------+
//| Get RSI Value                                                    |
//+------------------------------------------------------------------+
double GetRSI()
  {
   double rsiValues[1];
   if(CopyBuffer(RSI_Handle, 0, 0, 1, rsiValues) <= 0)
      return 0;
   return rsiValues[0];
  }

//+------------------------------------------------------------------+
//| Get ATR Value                                                    |
//+------------------------------------------------------------------+
double GetATR()
  {
   double atrValues[1];
   if(CopyBuffer(ATR_Handle, 0, 0, 1, atrValues) <= 0)
      return 0;
   return atrValues[0];
  }

//+------------------------------------------------------------------+
//| Draw signal arrow on the chart                                   |
//+------------------------------------------------------------------+
void DrawSignalArrow(string signalType, double price, color arrowColor)
  {
   string arrowName = signalType + "_" + TimeToString(TimeCurrent(), TIME_MINUTES);
// Delete the existing arrow if it exists
   if(ObjectFind(0, arrowName) != -1)  // If the object exists
     {
      ObjectDelete(0, arrowName); // Delete the existing object
     }
   ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), price);
   ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, (signalType == "BuySignal") ? 233 : 234);
   ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
   ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, ArrowSize);
  }

//+------------------------------------------------------------------+
//| Display TP and SL as text summary                                |
//+------------------------------------------------------------------+
void DisplayTextSummary(string signalType, double price, double refPrice, double ATR)
  {
   string objectName = "SignalSummary"; // Unique object name for the summary

// Delete the existing summary if it exists
   if(ObjectFind(0, objectName) != -1)  // If the object exists
     {
      ObjectDelete(0, objectName); // Delete the existing object
     }

   double SL = (signalType == "BUY") ? refPrice - (ATR * ATR_Multiplier) : refPrice + (ATR * ATR_Multiplier);
   double TP = (signalType == "BUY") ? price + (ATR * ATR_Multiplier) : price - (ATR * ATR_Multiplier);

   string summary = signalType + " Signal\n" +
                    "Price: " + DoubleToString(price, 5) + "\n" +
                    "TP: " + DoubleToString(TP, 5) + "\n" +
                    "SL: " + DoubleToString(SL, 5);

   ObjectCreate(0, objectName, OBJ_LABEL, 0, 0, 0);
   ObjectSetString(0, objectName, OBJPROP_TEXT, summary);
   ObjectSetInteger(0, objectName, OBJPROP_COLOR, TextColor);
   ObjectSetInteger(0, objectName, OBJPROP_FONTSIZE, 10); // Adjust font size if needed

// Position the label at the left upper corner
   ObjectSetInteger(0, objectName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
   ObjectSetInteger(0, objectName, OBJPROP_XDISTANCE, 10); // 10 pixels from the left
   ObjectSetInteger(0, objectName, OBJPROP_YDISTANCE, 10); // 10 pixels from the top
  }

//+------------------------------------------------------------------+
//| Update signal time to prevent frequent signals                   |
//+------------------------------------------------------------------+
void UpdateSignalTime()
  {
   lastSignalTime = iTime(NULL, 0, 0);
  }

//+------------------------------------------------------------------+
//| Calculate bars since the last signal                             |
//+------------------------------------------------------------------+
int BarsSinceLastSignal()
  {
   datetime currentBarTime = iTime(NULL, 0, 0);
   if(lastSignalTime == 0)
      return INT_MAX; // If no signal has been generated return a large number.
   return (int)((currentBarTime - lastSignalTime) / PeriodSeconds());
  }
//+------------------------------------------------------------------+


Desglose del código

Información del encabezado

El encabezado proporciona metadatos básicos sobre el Asesor Experto, incluyendo su nombre, autor y versión. Esta información es útil para identificar la EA y garantizar la atribución. Las directivas #property especifican metadatos, como los derechos de autor, el enlace del autor y la versión, que se muestran cuando se utiliza el EA. Además, la directiva #property indicator_chart_window indica que este EA opera en la ventana principal del gráfico en lugar de en una subventana separada.
//+------------------------------------------------------------------+
//| Mean Reversion Reaper.mq5                                        |
//| Author: Christian Benjamin                                       |
//| Website: https://www.mql5.com                                    |
//+------------------------------------------------------------------+
#property copyright "Christian Benjamin"
#property link      "https://www.mql5.com"
#property version   "1.00"

// Indicator operates in the main chart window
#property indicator_chart_window

Parámetros de entrada

Los parámetros de entrada permiten a los usuarios personalizar el comportamiento del EA sin modificar el código en sí. Estos parámetros incluyen ajustes esenciales como los períodos EMA, RSI y ATR, así como los umbrales para los niveles RSI de sobrecompra y sobreventa. Se puede establecer un período de enfriamiento para evitar la generación frecuente de señales, lo que ayuda a reducir el ruido del mercado y garantiza la claridad. Los usuarios también pueden especificar elementos visuales como los colores y tamaños de las flechas para las señales de compra y venta, junto con el color del texto del resumen que se muestra en el gráfico. Al ajustar estos parámetros, los operadores pueden adaptar el EA a su estrategia de trading o a las condiciones del mercado.

input int EMA_Period = 50;                     // EMA Period
input int RSI_Period = 14;                     // RSI Period
input double RSI_Overbought = 75.0;            // RSI Overbought level
input double RSI_Oversold = 25.0;              // RSI Oversold level
input int CooldownBars = 3;                    // Cooldown bars between signals
input double ATR_Multiplier = 2.0;             // ATR Multiplier for TP and SL
input int ATR_Period = 14;                     // ATR Period
input color BuySignalColor = clrGreen;         // Buy signal arrow color
input color SellSignalColor = clrRed;          // Sell signal arrow color
input int ArrowSize = 2;                       // Arrow size
input color TextColor = clrDodgerBlue;         // Color for TP/SL text summary

Variables globales

La sección de variables globales define las variables críticas de seguimiento del estado y las referencias para los indicadores utilizados por el EA. Aquí se declaran los controladores para los indicadores EMA, RSI y ATR, junto con lastSignalTime, que almacena la marca de tiempo de la señal más reciente. Estas variables garantizan que el EA pueda acceder a los datos de los indicadores de manera eficiente y aplicar lógicas tales como el período de espera entre señales.

int EMA_Handle, RSI_Handle, ATR_Handle;        // Handles for EMA, RSI, and ATR
datetime lastSignalTime = 0;                   // Tracks last signal time
Inicialización (OnInit)

La función OnInit se ejecuta cuando el EA se carga en un gráfico. Su función principal es inicializar los indicadores utilizando funciones como iMA para EMA, iRSI para RSI e iATR para ATR. Estos controladores son esenciales para recuperar los valores de los indicadores durante el tiempo de ejecución. La función también realiza una comprobación de errores para garantizar que todos los controladores se hayan creado correctamente. Si falla la creación de algún controlador, se registra un mensaje de error y el EA deja de ejecutarse. Una inicialización correcta genera un mensaje de confirmación en el diario, lo que indica que el EA está listo para funcionar.

int OnInit()
{
    EMA_Handle = iMA(NULL, 0, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
    RSI_Handle = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE);
    ATR_Handle = iATR(NULL, 0, ATR_Period);

    if (EMA_Handle == INVALID_HANDLE || RSI_Handle == INVALID_HANDLE || ATR_Handle == INVALID_HANDLE) {
        Print("Failed to create indicator handles. Error: ", GetLastError());
        return INIT_FAILED; // Stops EA if initialization fails
    }

    Print("Mean Reversion EA initialized.");
    return INIT_SUCCEEDED;
}

Limpieza (OnDeinit)

La función OnDeinit se llama automáticamente cuando el EA se elimina del gráfico o se reinicializa. Su principal responsabilidad es limpiar los objetos de gráfico creados durante el tiempo de ejecución del EA. En concreto, elimina la etiqueta «SignalSummary» para garantizar que el gráfico quede despejado. Esta función también registra un mensaje que confirma la desinicialización del EA, lo que aporta claridad sobre su proceso de terminación.

void OnDeinit(const int reason)
{
    ObjectDelete(0, "SignalSummary"); // Remove any signal summary text
    Print("Mean Reversion EA deinitialized.");
}

Procesamiento de señales (OnTick)

La función OnTick es el núcleo del EA, ya que procesa cada nuevo tick del mercado. Comienza comprobando si ha transcurrido el periodo de enfriamiento desde la última señal. Si no es así, la función se cierra antes de tiempo para evitar señales redundantes. A continuación, recupera los últimos valores de los indicadores EMA, RSI y ATR utilizando sus respectivos identificadores. Utilizando estos valores, el EA evalúa las condiciones para las señales de compra o venta.

Se activa una señal de compra cuando el precio está por debajo de la EMA y el RSI se encuentra en territorio de sobreventa. Por el contrario, se produce una señal de venta cuando el precio está por encima de la EMA y el RSI está sobrecomprado. Para cada señal, la función dibuja una flecha en el gráfico y muestra un resumen de texto con el precio, los niveles de Stop Loss (SL) y Take Profit (TP). La marca de tiempo de la señal se actualiza para aplicar el mecanismo de espera.

void OnTick()
{
    if (BarsSinceLastSignal() < CooldownBars) return; // Skip if cooldown is active

    double EMA_Value = GetEMA();   // Fetch EMA value
    double RSI_Value = GetRSI();   // Fetch RSI value
    double ATR_Value = GetATR();   // Fetch ATR value

    double closePrice = iClose(NULL, 0, 0); // Current bar's close price

    if (closePrice < EMA_Value && RSI_Value <= RSI_Oversold) {
        // Buy Signal
        DrawSignalArrow("BuySignal", closePrice, BuySignalColor);
        DisplayTextSummary("BUY", closePrice, iLow(NULL, 0, 1), ATR_Value);
        UpdateSignalTime(); // Update last signal time
    } else if (closePrice > EMA_Value && RSI_Value >= RSI_Overbought) {
        // Sell Signal
        DrawSignalArrow("SellSignal", closePrice, SellSignalColor);
        DisplayTextSummary("SELL", closePrice, iHigh(NULL, 0, 1), ATR_Value);
        UpdateSignalTime(); // Update last signal time
    }
}

Funciones utilitarias
  • Recuperar valores de indicadores

Las funciones de utilidad como GetEMA, GetRSI y GetATR están diseñadas para obtener los valores más recientes de sus respectivos indicadores. Estas funciones utilizan el método CopyBuffer para extraer datos de los controladores de indicadores. Si la recuperación de datos falla por cualquier motivo, las funciones devuelven cero, lo que indica que el EA debe omitir el procesamiento del tick actual. Estas funciones son ligeras y modulares, lo que mantiene el código limpio y fácil de mantener.

double GetEMA()
{
    double emaValues[1];
    if (CopyBuffer(EMA_Handle, 0, 0, 1, emaValues) <= 0)
        return 0;
    return emaValues[0];
}

double GetRSI()
{
    double rsiValues[1];
    if (CopyBuffer(RSI_Handle, 0, 0, 1, rsiValues) <= 0)
        return 0;
    return rsiValues[0];
}

double GetATR()
{
    double atrValues[1];
    if (CopyBuffer(ATR_Handle, 0, 0, 1, atrValues) <= 0)
        return 0;
    return atrValues[0];
}
  • Dibujar flecha de señal

La función DrawSignalArrow añade una señal visual al gráfico, indicando una señal de compra o venta. Genera dinámicamente un nombre único para cada flecha utilizando el tipo de señal y la hora actual, lo que garantiza que no se superponga con los objetos existentes. Si ya existe una flecha con el mismo nombre, se elimina antes de crear una nueva. Las propiedades de la flecha, como el color, el tamaño y el tipo, se determinan mediante parámetros de entrada definidos por el usuario, lo que permite una representación visual clara y personalizable.

void DrawSignalArrow(string signalType, double price, color arrowColor)
{
    string arrowName = signalType + "_" + TimeToString(TimeCurrent(), TIME_MINUTES);
    if (ObjectFind(0, arrowName) != -1) ObjectDelete(0, arrowName);

    ObjectCreate(0, arrowName, OBJ_ARROW, 0, TimeCurrent(), price);
    ObjectSetInteger(0, arrowName, OBJPROP_ARROWCODE, (signalType == "BuySignal") ? 233 : 234);
    ObjectSetInteger(0, arrowName, OBJPROP_COLOR, arrowColor);
    ObjectSetInteger(0, arrowName, OBJPROP_WIDTH, ArrowSize);
}
  • Mostrar resumen TP/SL

La función DisplayTextSummary proporciona un resumen conciso de la señal, incluyendo el precio, los niveles de Stop Loss y Take Profit. Esta información se muestra como una etiqueta en el gráfico, situada en la esquina superior izquierda. La función calcula los niveles de TP y SL basándose en el ATR y su multiplicador, ofreciendo niveles dinámicos que se adaptan a la volatilidad del mercado. Si ya existe una etiqueta de resumen, se elimina antes de crear una nueva. Esto garantiza que solo se muestre la información más reciente de la señal, lo que reduce el desorden y mejora la legibilidad.

void DisplayTextSummary(string signalType, double price, double refPrice, double ATR)
{
    string objectName = "SignalSummary";
    if (ObjectFind(0, objectName) != -1) ObjectDelete(0, objectName);

    double SL = (signalType == "BUY") ? refPrice - (ATR * ATR_Multiplier) : refPrice + (ATR * ATR_Multiplier);
    double TP = (signalType == "BUY") ? price + (ATR * ATR_Multiplier) : price - (ATR * ATR_Multiplier);

    string summary = signalType + " Signal\n" +
                     "Price: " + DoubleToString(price, 5) + "\n" +
                     "TP: " + DoubleToString(TP, 5) + "\n" +
                     "SL: " + DoubleToString(SL, 5);

    ObjectCreate(0, objectName, OBJ_LABEL, 0, 0, 0);
    ObjectSetString(0, objectName, OBJPROP_TEXT, summary);
    ObjectSetInteger(0, objectName, OBJPROP_COLOR, TextColor);
    ObjectSetInteger(0, objectName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, objectName, OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, objectName, OBJPROP_YDISTANCE, 10);
}
  • Gestión de la espera
El EA impone un periodo de espera entre señales para evitar el exceso de operaciones en condiciones de mercado volátiles. La función UpdateSignalTime actualiza la variable lastSignalTime con la marca de tiempo de la señal más reciente, mientras que la función BarsSinceLastSignal calcula el número de barras que han transcurrido desde la última señal. Si aún no se ha generado ninguna señal, se devuelve un valor elevado para garantizar el funcionamiento normal. Este mecanismo garantiza que las señales estén espaciadas adecuadamente, lo que proporciona a los operadores información más clara y fiable.
void UpdateSignalTime()
{
    lastSignalTime = iTime(NULL, 0, 0); // Store time of the current bar
}

int BarsSinceLastSignal()
{
    datetime currentBarTime = iTime(NULL, 0, 0);
    if (lastSignalTime == 0) return INT_MAX; // No signals generated yet
    return (int)((currentBarTime - lastSignalTime) / PeriodSeconds());
}


Pruebas y resultados

Hablemos del backtesting, un paso esencial en la evaluación de su Asesor Experto. Básicamente, el backtesting consiste en ejecutar su EA sobre datos históricos del mercado para ver cómo habría funcionado en el pasado. Este proceso es crucial para determinar si su estrategia está en sintonía con las diferentes condiciones del mercado y para obtener información sobre su solidez general.
A continuación se indican algunos puntos clave que hay que tener en cuenta al realizar pruebas retrospectivas:
  • Rango de datos históricos: Asegúrese de utilizar datos que abarquen diferentes condiciones de mercado, como mercados con tendencia y mercados con oscilaciones. Esto le ayuda a evaluar la capacidad de adaptación de su EA.
  • Métricas clave: Céntrese en medir el rendimiento a través de métricas importantes, como el factor de beneficio, la tasa de ganancias, la caída máxima y la duración media de las operaciones. Esto te dará una idea más clara de la eficacia de tu estrategia.
  • Optimización: No dude en experimentar con sus parámetros de entrada, como el período EMA y los niveles RSI, para descubrir la configuración más eficaz para instrumentos de mercado o marcos temporales específicos.
  • Validación visual: Por último, comprueba siempre que las flechas y señales generadas por tu EA se ajustan a la lógica de trading que deseas. Esto es fundamental para garantizar que su estrategia funcione tal y como la diseñó.

Al realizar pruebas retrospectivas exhaustivas de su EA teniendo en cuenta estas consideraciones, podrá desarrollar una estrategia de trading más fiable y eficaz.

SEÑAL DE PRUEBA

Figura 2. Resultado de la prueba 1

El diagrama anterior muestra las pruebas realizadas en dos marcos temporales diferentes para el índice de Volatilidad 75 (1 s) durante un periodo de 29 días. A continuación, hemos tabulado los resultados de las dos pruebas.

Tablas de generación de señales y rendimiento

  • Tabla 1

Tipo de señal  Periodo de tiempo  Señales totales generadas
Señales verdaderas (donde el precio subió después de la señal)
Precisión de la señal (%)
Buy M30 41 33 80.5%
Sell M30 21 15 71.4%

  • Tabla 2

Tipo de señal  Periodo de tiempo  Señales totales generadas
Señales verdaderas (donde el precio subió después de la señal)
Precisión de la señal (%)
 Buy H1 19 14 73.6% 
 Sell H1  13 61.5% 

A continuación se muestra una ilustración de los resultados de las pruebas en tiempo real del Asesor Experto.

Señal en tiempo real

Figura 3. Resultado de la prueba 2

Echemos también un vistazo al GIF que aparece a continuación.

RESULTADO DE LA PRUEBA

Figura 4. Resultado de la prueba 3

Referencias:


Conclusión

El Asesor Experto "Mean Reversion Reaper" ofrece un sistema de generación de señales fiable, basado en principios de reversión a la media, logrando una tasa de precisión de al menos el 70% en las señales de compra. El uso del rango medio verdadero (ATR) para establecer los niveles de Stop Loss (SL) y Take Profit (TP) permite al sistema adaptarse a diversas condiciones de volatilidad del mercado, lo que lo hace especialmente eficaz en mercados con rangos limitados.

Sin embargo, es importante tener en cuenta que el EA puede ser menos eficaz durante mercados con fuertes tendencias, lo cual es una característica típica de las estrategias de reversión a la media. Para mejorar su experiencia de trading, considere ajustar los parámetros y explorar filtros adicionales para las señales de venta. Dado que el EA no ejecuta operaciones automáticamente, sus señales pueden ser especialmente beneficiosas para los operadores manuales que buscan sacar provecho de las reversiones a corto plazo.

En esencia, "Mean Reversion Reaper" puede ser un poderoso aliado para los operadores interesados en los patrones de reversión del mercado. Si permanece atento a las condiciones del mercado y está dispuesto a ajustar su estrategia, podrá maximizar el potencial de esta herramienta en su arsenal de trading.

Fecha Nombre de la herramienta  Descripción Versión  Actualizaciones  Notas
01/10/24 Chart Projector Script para superponer la acción del precio del día anterior con efecto fantasma. 1.0 Lanzamiento inicial Primera herramienta en Lynnchris Tool Chest.
18/11/24 Analytical Comment Proporciona información del día anterior en formato tabular y anticipa la dirección futura del mercado. 1.0 Lanzamiento inicial Segunda herramienta en Lynnchris Tool Chest.
27/11/24 Analytics Master Actualización periódica de las métricas del mercado cada dos horas.  1.01 Segundo lanzamiento Tercera herramienta en Lynnchris Tool Chest.
02/12/24 Analytics Forecaster  Actualización periódica de las métricas del mercado cada dos horas con integración en Telegram. 1.1 Tercera edición Herramienta número 4
09/12/24 Volatility Navigator EA que analiza las condiciones del mercado utilizando los indicadores Bandas de Bollinger, RSI y ATR. 1.0 Lanzamiento inicial Herramienta número 5
19/12/24 Mean Reversion Signal Reaper  Analiza el mercado utilizando la estrategia de reversión a la media y proporciona señales.  1.0  Lanzamiento inicial  Herramienta número 6 

Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/16700

Archivos adjuntos |
Mean_Reversion.mq5 (16.16 KB)
linfo2
linfo2 | 7 ene 2025 en 03:33
Gracias Christian , Muy útil como plantilla
Roman Shiredchenko
Roman Shiredchenko | 3 sept 2025 en 18:58
Sí.... Gracias. Material interesante - Voy a tomar en mi trabajo y también buscar variantes de enfoque comercial en probador de estrategia y en oficios reales......
khanatd
khanatd | 15 oct 2025 en 06:10

Hola señor es mql4 versión disponible con flechas en la vela actual?

gracias

khan

Algoritmo de optimización de Escalera Real - Royal Flush Optimisation (RFO) Algoritmo de optimización de Escalera Real - Royal Flush Optimisation (RFO)
El algoritmo Royal Flush Optimization del autor ofrece una nueva perspectiva en la resolución de problemas de optimización sustituyendo la clásica codificación binaria de los algoritmos genéticos por un enfoque basado en sectores e inspirado en los principios del póquer. El RFO demuestra cómo la simplificación de los principios básicos puede dar lugar a un método de optimización eficaz y práctico. El artículo presenta un análisis detallado del algoritmo y los resultados de las pruebas.
Redes neuronales en el trading: Transformador jerárquico de doble torre (Final) Redes neuronales en el trading: Transformador jerárquico de doble torre (Final)
Seguimos construyendo el modelo del transformador jerárquico Hidformer de dos torres, diseñado para analizar y predecir series temporales multivariantes complejas. En este artículo llevaremos el trabajo iniciado anteriormente a su conclusión lógica probando el modelo con datos históricos reales.
Automatización de estrategias de trading en MQL5 (Parte 3): Sistema RSI de recuperación de zona para la gestión dinámica de operaciones Automatización de estrategias de trading en MQL5 (Parte 3): Sistema RSI de recuperación de zona para la gestión dinámica de operaciones
En este artículo, creamos un sistema (un EA) de recuperación de zona RSI en MQL5, utilizando señales RSI para lanzar operaciones y una estrategia de recuperación para gestionar las pérdidas. Implementamos una clase «ZoneRecovery» para automatizar las entradas de operaciones, la lógica de recuperación y la gestión de posiciones. El artículo concluye con información sobre backtesting para optimizar el rendimiento y mejorar la eficacia del EA.
Características del Wizard MQL5 que debe conocer (Parte 51): Aprendizaje por refuerzo con SAC Características del Wizard MQL5 que debe conocer (Parte 51): Aprendizaje por refuerzo con SAC
Soft Actor Critic es un algoritmo de aprendizaje por refuerzo que utiliza tres redes neuronales. Una red de actores y dos redes de críticos. Estos modelos de aprendizaje automático se emparejan en una relación maestro-esclavo en la que los críticos se modelan para mejorar la precisión de las previsiones de la red de actores. Al tiempo que introducimos ONNX en esta serie, exploramos cómo estas ideas podrían ponerse a prueba como una señal personalizada de un asesor experto ensamblado por un asistente.