Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 26): Herramienta de patrones pin bar y envolventes con divergencia del RSI (patrones múltiples)
Introducción
En mi artículo anterior, me centré en identificar cuatro formaciones de velas japonesas: pin bar, doji, envolvente y marubozu. Estos patrones se utilizaban para generar señales de compra o venta en cuanto se detectaban. Sin embargo, este enfoque generaba a veces señales erróneas, ya que la confirmación se basaba únicamente en el reconocimiento de patrones, sin filtros adicionales.
Este artículo presenta una nueva herramienta que se centra en dos patrones clave: la pin bar y el patrón envolvente. Estos patrones se combinan con la divergencia del RSI para confirmar cada señal. La divergencia del RSI es una herramienta que desarrollé en el pasado como indicador independiente basado en la evolución del precio. Al integrar el reconocimiento de patrones con la divergencia del RSI, creamos un método analítico más sólido y eficaz, que ofrece una visión más profunda y mejora la precisión de las operaciones gracias a un análisis exhaustivo de la evolución de los precios.
Comenzaremos analizando ambos patrones con mayor detalle, para luego pasar a una visión general de la estrategia, un desglose de los componentes del código, los resultados del backtesting y el análisis. Por último, concluiremos con los puntos clave. Consulte el índice que figura a continuación.
- Comprender los patrones de velas japonesas
- Resumen de la estrategia
- Desglose de los componentes del código
- Backtesting y resultados
- Conclusión
Comprender los patrones de velas japonesas
Los patrones de velas japonesas son formaciones que se utilizan en el análisis técnico para analizar los movimientos de los precios en los mercados financieros. Representan visualmente los precios de apertura, máximo, mínimo y cierre de un mercado durante un periodo concreto, lo que ofrece información sobre la posible dirección y el sentimiento del mercado. Existen muchos patrones de velas japonesas, pero, tal y como se menciona en este artículo, nos centraremos en dos patrones principales: la vela pin bar y el patrón envolvente. Estos patrones pueden aparecer como una o dos velas en los timeframes superiores, o como varias velas en los gráficos de menor intervalo de tiempo. Veamos la ilustración siguiente, donde lo explicaré con más detalle para que entiendas a qué me refiero.El primer gráfico (Fig. 1) muestra un patrón de envolvente bajista en el marco temporal M30. Consta de dos velas: la primera es una vela alcista con un cuerpo pequeño, seguida de una vela bajista con un cuerpo más grande que envuelve a la vela alcista anterior.

Fig. 1. Patrón envolvente bajista en M30
El mismo patrón puede representarse mediante varias velas cuando se observa en un marco temporal inferior. Echemos un vistazo al siguiente diagrama (Fig. 2). Muestra el mismo patrón de velas que antes, pero ahora en el marco temporal M5, donde se representa mediante una serie de varias velas.

Fig. 2. Patrón envolvente bajista en el M5
Pasemos ahora a analizar los dos patrones en los que nos vamos a centrar: la pin bar y el patrón envolvente, así como la divergencia del RSI. No profundizaremos en estos temas aquí, ya que los tratamos ampliamente en nuestro artículo anterior. Puedes consultar ese artículo a través del enlace proporcionado.
Pin Bar
Una vela pin bar es un tipo de vela japonesa que se caracteriza por un cuerpo real pequeño y una mecha prominente, lo que indica un rechazo significativo del precio en un nivel específico. Aparece como una sola vela que a menudo indica un posible cambio de tendencia o un punto de inflexión crítico en el mercado. La mecha extendida demuestra que los precios se movieron bruscamente en una dirección, pero fueron rápidamente rechazados, lo que implica un cambio en el sentimiento del mercado y un posible cambio en la tendencia.
Patrón envolvente
El patrón de vela envolvente es una herramienta popular en el análisis técnico que señala una posible reversión en la dirección del mercado. Consiste en dos velas consecutivas, donde el cuerpo de la segunda vela "envuelve" por completo el cuerpo de la primera, lo que indica un cambio en el sentimiento del mercado. Este patrón sirve como señal de reversión, lo que sugiere que la tendencia anterior puede estar terminando y que está comenzando una nueva tendencia, ya sea una reversión alcista cuando una vela ascendente más grande envuelve a una vela descendente más pequeña, o una reversión bajista cuando una vela descendente más grande envuelve a una vela ascendente más pequeña.
Divergencia del RSI
La divergencia del RSI (Índice de Fuerza Relativa) se produce cuando el precio de un activo y el indicador RSI se mueven en direcciones opuestas, lo que indica un posible cambio en el impulso y una posible inversión de la tendencia. Esta divergencia se hace evidente cuando el precio forma nuevos máximos o mínimos, pero el RSI no coincide con los máximos o mínimos correspondientes. Existen dos tipos principales: la divergencia bajista, que se produce cuando el precio alcanza un nuevo máximo mientras que el RSI crea un máximo inferior, lo que indica un debilitamiento del impulso alcista y una posible caída inminente; y la divergencia alcista, donde el precio alcanza un nuevo mínimo, pero el RSI forma un mínimo superior, lo que sugiere que el impulso bajista está disminuyendo y que podría producirse un movimiento alcista.
El RSI, como oscilador de impulso, mide la velocidad y el cambio de los movimientos de precios, lo que ayuda a los operadores a identificar condiciones de sobrecompra o sobreventa, pero también revela patrones de divergencia. Cuando el precio alcanza nuevos extremos sin un movimiento correspondiente en el RSI, indica un posible cambio de impulso y una reversión de la tendencia.
Divergencia bajista

Fig. 3. Divergencia bajista del RSI
Divergencia alcista del RSI

Fig. 4. Divergencia alcista del RSI
Resumen de la estrategia
Nuestra herramienta busca y reconoce minuciosamente los patrones de velas pin bar y envolventes, al tiempo que comprueba la divergencia del RSI para confirmar cada señal, ya sea de compra o de venta. En otras palabras, cuando se detecta una vela pin bar o un patrón envolvente, el EA verifica la divergencia del RSI como confirmación antes de validar la señal. La herramienta solo muestra la señal de trading si el RSI confirma el patrón. A continuación, se muestra un diagrama que ilustra cómo una vela pin bar puede confirmarse mediante una divergencia alcista del RSI.
Fig. 5. Confirmación de pin bar
Desglose de los componentes del código
1. Propiedades de metadatos e inicialización
La sección inicial del EA define metadatos esenciales que ayudan a identificar y gestionar el script dentro del entorno MetaTrader. La declaración de derechos de autor, el enlace y el número de versión proporcionan atribución y control de versiones, lo que garantiza que los usuarios conozcan el origen y el estado de actualización del script. La directiva #property strict impone reglas de compilación más estrictas, lo que permite detectar posibles errores en una fase temprana y fomenta unas mejores prácticas de programación. Esta configuración garantiza que el EA cumpla con los estándares esperados, lo que facilita el mantenimiento, la resolución de problemas y la identificación cuando se ejecutan varios scripts simultáneamente.
//+------------------------------------------------------------------+ //| Multi-Pattern Signal EA| //| Copyright 2025, MetaQuotes Ltd.| //| https://www.mql5.com/en/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict
2. Incluir bibliotecas y definir entradas de usuario
El EA incluye la biblioteca <Trade/Trade.mqh> para permitir operaciones con órdenes, como la apertura, el cierre y la gestión de operaciones. Si bien esta versión se centra principalmente en la detección de patrones y las alertas, la integración de la biblioteca de operaciones permite una futura ampliación hacia el trading automatizado. Los parámetros de entrada son vitales para la personalización: los operadores pueden ajustar el período del RSI para modificar la sensibilidad, establecer umbrales de sobrecompra y sobreventa para la detección de divergencias, y configurar los niveles de stop-loss y take-profit en pips.
El EntryBuffer actúa como una zona de amortiguación para evitar entradas demasiado cercanas a los extremos recientes de los precios, lo que reduce las señales falsas. Las opciones de notificación permiten activar o desactivar las alertas sonoras, las notificaciones push y los correos electrónicos, lo que da a los operadores control sobre cómo reciben las alertas. En conjunto, estos parámetros hacen que el EA sea adaptable a diversos estilos de negociación y condiciones de mercado.
#include <Trade/Trade.mqh> input int RSI_Period = 14; // RSI calculation period input double RSI_Overbought = 70.0; // RSI level indicating overbought input double RSI_Oversold = 30.0; // RSI level indicating oversold input double SL_Pips = 20.0; // Default stop loss in pips input double TP_Pips = 20.0; // Default take profit in pips input double EntryBuffer = 5.0; // Buffer in points for entry price input bool EnableSound = true; // Enable sound alerts input bool EnablePush = true; // Enable push notifications input bool EnableEmail = false; // Enable email alerts
3. Inicialización: Creación de manejadores de indicadores y búferes
Durante la configuración inicial, el EA crea un manejador para el indicador RSI usandoiRSI()especificando el símbolo, el período y los parámetros RSI. Este identificador es esencial para recuperar los valores RSI en tiempo real durante cada tick, constituyendo la base de la detección de divergencias. Los arrays están configurados como series, lo que significa que los datos más recientes siempre están en el índice 0. Los búferes internos para el tiempo, la apertura, el precio máximo, el precio mínimo y el precio de cierre se inicializan para almacenar datos históricos para su análisis. La variable lastBarTime registra la marca de tiempo de la última vela procesada, lo que impide que se generen múltiples señales dentro de la misma vela, evitando así alertas redundantes y garantizando la precisión de las señales.
int OnInit() { rsiHandle = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE); if(rsiHandle == INVALID_HANDLE) return INIT_FAILED; // Set arrays as series for easier access to recent data ArraySetAsSeries(rsiBuffer, true); ArraySetAsSeries(timeBuffer, true); ArraySetAsSeries(openBuffer, true); ArraySetAsSeries(highBuffer, true); ArraySetAsSeries(lowBuffer, true); ArraySetAsSeries(closeBuffer, true); return INIT_SUCCEEDED; }
4. Monitorización y procesamiento continuo de datos en OnTick()
La función OnTick() se ejecuta con cada tick del mercado y actúa como el bucle principal del EA. El proceso comienza verificando que haya al menos 20 barras disponibles, lo que garantiza suficientes datos históricos para el reconocimiento de patrones. A continuación, copia los últimos 20 puntos de datos de marcas de tiempo y datos de precios (apertura, máximo, mínimo, cierre) en búferes internos. Este paso es crucial porque los datos de mercado se actualizan constantemente y el análisis depende de datos recientes y precisos. Si falla alguna operación de copia, la función se detiene para evitar errores o señales falsas.
Para evitar que se generen múltiples señales dentro de la misma vela, comprueba si la marca de tiempo de la vela anterior coincide con lastBarTime. En ese caso, omite el procesamiento; de lo contrario, actualiza lastBarTime con la marca de tiempo de la nueva vela. A continuación, actualiza los datos del RSI. Una vez preparados los datos, se llama a la función FindSignalBar() para analizar las barras recientes en busca de patrones de divergencia y señales de velas japonesas, lo que constituye la base para la generación de alertas.
void OnTick() { // Ensure enough data is available if(Bars(_Symbol, _Period) < 20) return; // Copy recent market data if(CopyTime(_Symbol, _Period, 0, 20, timeBuffer) <= 0 || CopyOpen(_Symbol, _Period, 0, 20, openBuffer) <= 0 || CopyHigh(_Symbol, _Period, 0, 20, highBuffer) <= 0 || CopyLow(_Symbol, _Period, 0, 20, lowBuffer) <= 0 || CopyClose(_Symbol, _Period, 0, 20, closeBuffer) <= 0) return; // Prevent multiple signals in the same candle if(timeBuffer[1] == lastBarTime) return; lastBarTime = timeBuffer[1]; // Update RSI data if(CopyBuffer(rsiHandle, 0, 0, 20, rsiBuffer) <= 0) return; // Detect potential divergence and pattern int dir = FindSignalBar(); if(dir == 0) return; // Determine direction and compute entry/stop levels bool isBullish = (dir > 0); int idx = 1; // most recent completed bar double entry = isBullish ? highBuffer[idx] + EntryBuffer * _Point : lowBuffer[idx] - EntryBuffer * _Point; double stopL = isBullish ? lowBuffer[idx] - SL_Pips * _Point : highBuffer[idx] + SL_Pips * _Point; // Visualize and notify DrawSignal(idx, isBullish, entry, stopL); }
5. Reconocimiento de patrones mediante el análisis de divergencias y velas japonesas
La función FindSignalBar() desempeña un papel fundamental a la hora de identificar posibles señales de reversión. Analiza las barras recientes (de 5 a 15 barras atrás) para detectar patrones de divergencia. La divergencia alcista se confirma cuando el precio marca un mínimo más bajo mientras el RSI forma un mínimo más alto en zona de sobreventa. Por el contrario, la divergencia bajista se produce cuando el precio marca un máximo más alto mientras el RSI forma un máximo más bajo en zona de sobrecompra.
La función también analiza la última barra en busca de patrones de velas que respalden la divergencia, como las velas pin bar y las velas envolventes, conocidas por su importancia en los cambios de tendencia. Si se cumplen tanto las condiciones de divergencia como las del patrón, devuelve +1 para una señal alcista o -1 para una señal bajista; de lo contrario, devuelve 0, lo que indica que no hay una configuración válida en ese momento. Este enfoque por capas combina la divergencia del impulso con la evolución del precio para mejorar la fiabilidad de las señales.
int FindSignalBar() { bool bullDiv = false, bearDiv = false; for(int i = 5; i <= 15; i++) { // Bullish divergence condition if(lowBuffer[i] > lowBuffer[1] && rsiBuffer[i] < rsiBuffer[1] && rsiBuffer[1] < RSI_Oversold) bullDiv = true; // Bearish divergence condition if(highBuffer[i] < highBuffer[1] && rsiBuffer[i] > rsiBuffer[1] && rsiBuffer[1] > RSI_Overbought) bearDiv = true; } // No divergence detected if(!bullDiv && !bearDiv) return 0; // Check for candlestick patterns supporting divergence bool bullPat = IsBullishPinBar(1) || IsBullishEngulfing(1); bool bearPat = IsBearishPinBar(1) || IsBearishEngulfing(1); // Confirmed signals if(bullDiv && bullPat) return +1; if(bearDiv && bearPat) return -1; return 0; // No valid signal }
6. Detección de patrones de velas japonesas para la confirmación
Estas funciones analizan las velas individuales para confirmar señales de reversión. La función IsBullishPinBar() comprueba si la vela tiene un cuerpo pequeño con una mecha inferior larga, lo que indica un rechazo de los precios más bajos —un indicio de reversión alcista—. IsBearishPinBar() hace lo contrario. IsBullishEngulfing() confirma si el cuerpo de la vela actual envuelve al de la anterior, lo que indica una fuerte presión compradora, mientras que IsBearishEngulfing() indica una fuerte presión vendedora. Estas funciones de detección de patrones utilizan medidas proporcionales de los cuerpos y las mechas de las velas en relación con su rango de máximos y mínimos para garantizar que solo se tengan en cuenta los patrones bien formados, lo que reduce los falsos positivos y aumenta la fiabilidad de las señales.
// Bullish Pin Bar Pattern bool IsBullishPinBar(int i) { double body = MathAbs(openBuffer[i] - closeBuffer[i]); double rng = highBuffer[i] - lowBuffer[i]; double lw = MathMin(openBuffer[i], closeBuffer[i]) - lowBuffer[i]; double uw = highBuffer[i] - MathMax(openBuffer[i], closeBuffer[i]); return closeBuffer[i] > openBuffer[i] && lw > 2.0 * body && uw < 0.5 * body && body > 0.1 * rng; } // Bearish Pin Bar Pattern bool IsBearishPinBar(int i) { double body = MathAbs(openBuffer[i] - closeBuffer[i]); double rng = highBuffer[i] - lowBuffer[i]; double uw = highBuffer[i] - MathMax(openBuffer[i], closeBuffer[i]); double lw = MathMin(openBuffer[i], closeBuffer[i]) - lowBuffer[i]; return closeBuffer[i] < openBuffer[i] && uw > 2.0 * body && lw < 0.5 * body && body > 0.1 * rng; } // Bullish Engulfing Pattern bool IsBullishEngulfing(int i) { if(closeBuffer[i] <= openBuffer[i]) return false; if(openBuffer[i] > closeBuffer[i+1]) return false; if(closeBuffer[i] < openBuffer[i+1]) return false; return true; } // Bearish Engulfing Pattern bool IsBearishEngulfing(int i) { if(closeBuffer[i] >= openBuffer[i]) return false; if(openBuffer[i] < closeBuffer[i+1]) return false; if(closeBuffer[i] > openBuffer[i+1]) return false; return true; }
7. Visualización y generación de alertas
Una vez confirmados un patrón válido y una divergencia, DrawSignal() visualiza la configuración trazando flechas en los puntos de entrada, líneas horizontales para los niveles de entrada y de stop-loss, y líneas de tendencia que ilustran el patrón de divergencia. El color y el código de la flecha indican la dirección: verde para las tendencias alcistas y rojo para las bajistas. Las líneas de tendencia conectan los mínimos o máximos recientes para confirmar visualmente la divergencia.
Esta función también genera un mensaje de alerta detallado que incluye el tipo de patrón, el lado, el símbolo, la hora, el punto de entrada y los niveles de stop-loss. A continuación, activa notificaciones (reproduciendo un sonido, enviando notificaciones push o correos electrónicos) según las preferencias del usuario, lo que garantiza que el operador esté informado de inmediato y pueda actuar con rapidez. Este completo sistema de visualización y alerta mejora el conocimiento de la situación y la toma de decisiones.
void DrawSignal(int i, bool isBullish, double entry, double stopL) { string tag = TimeToString(timeBuffer[i], TIME_SECONDS); string nameA = "Arr_" + tag; string nameE = "Ent_" + tag; string nameS = "SL_" + tag; string nameL = "Div_" + tag; color clrArr = isBullish ? clrLime : clrRed; int code = isBullish ? 233 : 234; // Arrow at entry point ObjectCreate(0, nameA, OBJ_ARROW, 0, timeBuffer[i], entry); ObjectSetInteger(0, nameA, OBJPROP_COLOR, clrArr); ObjectSetInteger(0, nameA, OBJPROP_ARROWCODE, code); ObjectSetInteger(0, nameA, OBJPROP_WIDTH, 2); // Horizontal lines for entry and stop-loss ObjectCreate(0, nameE, OBJ_HLINE, 0, 0, entry); ObjectSetInteger(0, nameE, OBJPROP_COLOR, clrAqua); ObjectCreate(0, nameS, OBJ_HLINE, 0, 0, stopL); ObjectSetInteger(0, nameS, OBJPROP_COLOR, clrOrangeRed); ObjectSetInteger(0, nameS, OBJPROP_STYLE, STYLE_DASH); // Divergence trend line for visual confirmation for(int j = i + 5; j < i + 15; j++) { if(isBullish && lowBuffer[j] > lowBuffer[i]) { ObjectCreate(0, nameL, OBJ_TREND, 0, timeBuffer[j], lowBuffer[j], timeBuffer[i], lowBuffer[i]); ObjectSetInteger(0, nameL, OBJPROP_COLOR, clrDodgerBlue); break; } if(!isBullish && highBuffer[j] < highBuffer[i]) { ObjectCreate(0, nameL, OBJ_TREND, 0, timeBuffer[j], highBuffer[j], timeBuffer[i], highBuffer[i]); ObjectSetInteger(0, nameL, OBJPROP_COLOR, clrOrange); break; } } // Construct alert message string pattern = isBullish ? (IsBullishEngulfing(i) ? "Engulfing" : "PinBar") : (IsBearishEngulfing(i) ? "Engulfing" : "PinBar"); string side = isBullish ? "Buy" : "Sell"; string txt = StringFormat( "%s + RSI Divergence %s Signal\nSymbol: %s\nTime: %s\nEntry: %.5f\nSL: %.5f", pattern, side, _Symbol, TimeToString(timeBuffer[i], TIME_MINUTES), entry, stopL ); // Notify trader Alert(txt); if(EnableSound) PlaySound("alert.wav"); if(EnablePush) SendNotification(txt); if(EnableEmail) SendMail("Signal EA Alert", txt); Print(txt); }
EA completo para MQL5
//+------------------------------------------------------------------+ //| Multi-Pattern Signal EA| //| Copyright 2025, MetaQuotes Ltd.| //| https://www.mql5.com/en/users/lynnchris| //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com/en/users/lynnchris" #property version "1.0" #property strict #include <Trade/Trade.mqh> input int RSI_Period = 14; input double RSI_Overbought = 70.0; input double RSI_Oversold = 30.0; input double SL_Pips = 20.0; // in pips input double TP_Pips = 20.0; // in pips input double EntryBuffer = 5.0; // in points input bool EnableSound = true; input bool EnablePush = true; input bool EnableEmail = false; CTrade trade; // internal buffers double rsiBuffer[]; datetime timeBuffer[]; double openBuffer[], highBuffer[], lowBuffer[], closeBuffer[]; int rsiHandle; datetime lastBarTime = 0; //+------------------------------------------------------------------+ int OnInit() { rsiHandle = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE); if(rsiHandle == INVALID_HANDLE) return INIT_FAILED; ArraySetAsSeries(rsiBuffer, true); ArraySetAsSeries(timeBuffer, true); ArraySetAsSeries(openBuffer, true); ArraySetAsSeries(highBuffer, true); ArraySetAsSeries(lowBuffer, true); ArraySetAsSeries(closeBuffer, true); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ void OnTick() { if(Bars(_Symbol,_Period) < 20) return; if(CopyTime(_Symbol,_Period,0,20,timeBuffer) <= 0 || CopyOpen(_Symbol,_Period,0,20,openBuffer) <= 0 || CopyHigh(_Symbol,_Period,0,20,highBuffer) <= 0 || CopyLow(_Symbol,_Period,0,20,lowBuffer) <= 0 || CopyClose(_Symbol,_Period,0,20,closeBuffer) <= 0) return; if(timeBuffer[1] == lastBarTime) return; lastBarTime = timeBuffer[1]; if(CopyBuffer(rsiHandle,0,0,20,rsiBuffer) <= 0) return; int dir = FindSignalBar(); if(dir == 0) return; int idx = 1; bool isBullish = (dir > 0); double entry = isBullish ? highBuffer[idx] + EntryBuffer * _Point : lowBuffer[idx] - EntryBuffer * _Point; double stopL = isBullish ? lowBuffer[idx] - SL_Pips * _Point : highBuffer[idx] + SL_Pips * _Point; DrawSignal(idx, isBullish, entry, stopL); } //+------------------------------------------------------------------+ int FindSignalBar() { bool bullDiv = false, bearDiv = false; for(int i = 5; i <= 15; i++) { if(lowBuffer[i] > lowBuffer[1] && rsiBuffer[i] < rsiBuffer[1] && rsiBuffer[1] < RSI_Oversold) bullDiv = true; if(highBuffer[i] < highBuffer[1] && rsiBuffer[i] > rsiBuffer[1] && rsiBuffer[1] > RSI_Overbought) bearDiv = true; } if(!bullDiv && !bearDiv) return 0; bool bullPat = IsBullishPinBar(1) || IsBullishEngulfing(1); bool bearPat = IsBearishPinBar(1) || IsBearishEngulfing(1); if(bullDiv && bullPat) return +1; if(bearDiv && bearPat) return -1; return 0; } //+------------------------------------------------------------------+ bool IsBullishPinBar(int i) { double body = MathAbs(openBuffer[i] - closeBuffer[i]); double rng = highBuffer[i] - lowBuffer[i]; double lw = MathMin(openBuffer[i], closeBuffer[i]) - lowBuffer[i]; double uw = highBuffer[i] - MathMax(openBuffer[i], closeBuffer[i]); return closeBuffer[i] > openBuffer[i] && lw > 2.0 * body && uw < 0.5 * body && body > 0.1 * rng; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsBearishPinBar(int i) { double body = MathAbs(openBuffer[i] - closeBuffer[i]); double rng = highBuffer[i] - lowBuffer[i]; double uw = highBuffer[i] - MathMax(openBuffer[i], closeBuffer[i]); double lw = MathMin(openBuffer[i], closeBuffer[i]) - lowBuffer[i]; return closeBuffer[i] < openBuffer[i] && uw > 2.0 * body && lw < 0.5 * body && body > 0.1 * rng; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsBullishEngulfing(int i) { if(closeBuffer[i] <= openBuffer[i]) return false; if(openBuffer[i] > closeBuffer[i+1]) return false; if(closeBuffer[i] < openBuffer[i+1]) return false; return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsBearishEngulfing(int i) { if(closeBuffer[i] >= openBuffer[i]) return false; if(openBuffer[i] < closeBuffer[i+1]) return false; if(closeBuffer[i] > openBuffer[i+1]) return false; return true; } //+------------------------------------------------------------------+ void DrawSignal(int i, bool isBullish, double entry, double stopL) { string tag = TimeToString(timeBuffer[i], TIME_SECONDS); string nameA = "Arr_" + tag; string nameE = "Ent_" + tag; string nameS = "SL_" + tag; string nameL = "Div_" + tag; color clrArr = isBullish ? clrLime : clrRed; int code = isBullish ? 233 : 234; ObjectCreate(0, nameA, OBJ_ARROW, 0, timeBuffer[i], entry); ObjectSetInteger(0, nameA, OBJPROP_COLOR, clrArr); ObjectSetInteger(0, nameA, OBJPROP_ARROWCODE, code); ObjectSetInteger(0, nameA, OBJPROP_WIDTH, 2); ObjectCreate(0, nameE, OBJ_HLINE, 0, 0, entry); ObjectSetInteger(0, nameE, OBJPROP_COLOR, clrAqua); ObjectCreate(0, nameS, OBJ_HLINE, 0, 0, stopL); ObjectSetInteger(0, nameS, OBJPROP_COLOR, clrOrangeRed); ObjectSetInteger(0, nameS, OBJPROP_STYLE, STYLE_DASH); for(int j = i + 5; j < i + 15; j++) { if(isBullish && lowBuffer[j] > lowBuffer[i]) { ObjectCreate(0, nameL, OBJ_TREND, 0, timeBuffer[j], lowBuffer[j], timeBuffer[i], lowBuffer[i]); ObjectSetInteger(0, nameL, OBJPROP_COLOR, clrDodgerBlue); break; } if(!isBullish && highBuffer[j] < highBuffer[i]) { ObjectCreate(0, nameL, OBJ_TREND, 0, timeBuffer[j], highBuffer[j], timeBuffer[i], highBuffer[i]); ObjectSetInteger(0, nameL, OBJPROP_COLOR, clrOrange); break; } } string pattern = isBullish ? (IsBullishEngulfing(i) ? "Engulfing" : "PinBar") : (IsBearishEngulfing(i) ? "Engulfing" : "PinBar"); string side = isBullish ? "Buy" : "Sell"; string txt = StringFormat( "%s + RSI Divergence %s Signal\nSymbol: %s\nTime: %s\nEntry: %.5f\nSL: %.5f", pattern, side, _Symbol, TimeToString(timeBuffer[i], TIME_MINUTES), entry, stopL ); Alert(txt); if(EnableSound) PlaySound("alert.wav"); if(EnablePush) SendNotification(txt); if(EnableEmail) SendMail("Signal EA Alert", txt); Print(txt); } //+------------------------------------------------------------------+
Backtesting y resultados
El backtesting es un proceso que consiste en evaluar una estrategia de negociación utilizando datos históricos del mercado para estimar cuál habría sido su rendimiento en el pasado. Esta simulación permite a los operadores ver cómo habrían funcionado sus reglas predefinidas en condiciones reales de mercado, lo que les ofrece una visión de la rentabilidad y los riesgos potenciales. Al analizar los resultados de estas operaciones simuladas, los operadores pueden tomar decisiones fundamentadas sobre si aplicar la estrategia en operaciones reales.
El primer paso para realizar un backtesting es definir claramente la estrategia de negociación. Esto implica establecer reglas específicas para entrar y salir de las operaciones, incluyendo los indicadores, los patrones de precios u otras condiciones que activarán señales de compra o venta. Una estrategia bien definida garantiza la realización de pruebas sistemáticas y la obtención de resultados precisos. A continuación, los operadores deben recopilar datos históricos relevantes, como gráficos de precios, volumen y otra información pertinente correspondiente al periodo que deseen analizar. Para obtener resultados fiables en las pruebas retrospectivas, es fundamental disponer de datos precisos y exhaustivos.
Es fundamental elegir la plataforma de backtesting adecuada. Existen diversas herramientas de software disponibles, algunas que permiten el análisis manual y otras que admiten pruebas totalmente automatizadas. La plataforma elegida debe ser capaz de simular con precisión las operaciones basándose en las reglas de su estrategia y de proporcionar métricas detalladas de rendimiento. Una vez seleccionada la plataforma, el operador debe configurar el entorno de backtesting. Esto incluye la configuración de parámetros como los timeframes, los costes de transacción, el slippage y otros factores que pueden influir en el rendimiento, garantizando que la simulación refleje las condiciones reales de negociación con la mayor fidelidad posible.
Tras la configuración inicial, el siguiente paso es aplicar la estrategia ejecutando la prueba retrospectiva. La plataforma genera entonces operaciones simuladas de acuerdo con las reglas predefinidas y los datos históricos del mercado. Durante este proceso, es importante analizar los resultados minuciosamente. Los indicadores clave, como el beneficio o la pérdida total, la tasa de éxito, el drawdown máximo y la relación riesgo-beneficio, proporcionan información valiosa sobre la eficacia y la solidez de la estrategia.
En función del análisis, los operadores deberían refinar y optimizar su estrategia. Los ajustes en los parámetros o las reglas pueden mejorar el rendimiento y ayudar a solucionar cualquier deficiencia detectada durante las pruebas. Para garantizar la fiabilidad de la estrategia y evitar el sobreajuste, es fundamental validarla con datos fuera de muestra. Ejecutar la estrategia refinada sobre un conjunto independiente de datos históricos ayuda a confirmar su solidez y su potencial para obtener buenos resultados en mercados reales.
A continuación se muestran los resultados de mis backtests.

Fig. 6. Confirmación de patrón envolvente alcista
La figura anterior (Fig. 6) muestra una captura de pantalla de la prueba retrospectiva del EURUSD en el marco temporal M30, que muestra un patrón envolvente alcista que fue confirmado por una divergencia alcista.

Fig. 7. Backtesting del USDCHF
La figura anterior (Fig. 7) muestra una captura de pantalla de la prueba retrospectiva del USDCHF en el marco temporal M30, que muestra un patrón envolvente alcista confirmado por una divergencia alcista. Además, a continuación se muestra un GIF que ilustra el proceso de backtesting del par USDCHF, destacando cómo se identificaron varias señales.
Conclusión
Este Asesor Experto (EA) ejemplifica un enfoque avanzado para el reconocimiento de patrones y la detección de divergencias dentro de una estrategia de trading. Al combinar indicadores técnicos como el RSI con el análisis de patrones de velas japonesas, como las pin bars y los patrones envolventes, identifica eficazmente señales de reversión de alta probabilidad. El diseño modular del EA le permite analizar datos recientes del mercado en tiempo real, generar señales visuales en el gráfico y enviar alertas oportunas, lo que lo convierte en una herramienta valiosa para los operadores que buscan entradas sistemáticas y disciplinadas.
Los resultados de las pruebas retrospectivas demuestran que el EA puede lograr altas tasas de éxito, especialmente cuando las señales se confirman mediante múltiples criterios. Sin embargo, como ocurre con cualquier estrategia automatizada, es fundamental validar su solidez en diferentes pares de divisas y condiciones de mercado mediante pruebas fuera de la muestra. Una correcta optimización de los parámetros y una gestión eficaz del riesgo son esenciales para maximizar la rentabilidad y reducir los drawdowns. En definitiva, este asesor experto demuestra el potencial de combinar el reconocimiento de patrones con el análisis de divergencias, sentando una base sólida para una mayor integración del aprendizaje automático y la toma de decisiones inteligentes en los sistemas de negociación.
| Fecha | Nombre de la herramienta | Descripción | Versión | Actualizaciones | Notas |
|---|---|---|---|---|---|
| 01/10/24 | Chart Projector | Script para superponer un efecto fantasma a la evolución del precio del día anterior. | 1.0 | Versión inicial | Herramienta número 1 |
| 18/11/24 | Analytical Comment | Proporciona la información del día anterior en formato tabular, además de anticipar la dirección futura del mercado. | 1.0 | Versión inicial | Herramienta número 2 |
| 27/11/24 | Analytics Master | Actualización periódica de las métricas del mercado cada dos horas. | 1.01 | Segundo lanzamiento | Herramienta número 3 |
| 02/12/24 | Analytics Forecaster | Actualización periódica de las métricas del mercado cada dos horas con integración de Telegram. | 1.1 | Tercera edición | Herramienta número 4 |
| 09/12/24 | Volatility Navigator | El EA analiza las condiciones del mercado utilizando los indicadores Bandas de Bollinger, RSI y ATR. | 1.0 | Versión inicial | Herramienta número 5 |
| 19/12/24 | Mean Reversion Signal Reaper | Analiza el mercado utilizando una estrategia de reversión a la media y proporciona una señal. | 1.0 | Versión inicial | Herramienta número 6 |
| 09/01/25 | Signal Pulse | Analizador de múltiples marcos temporales | 1.0 | Versión inicial | Herramienta número 7 |
| 17/01/25 | Metrics Board | Panel con botón para análisis | 1.0 | Versión inicial | Herramienta número 8 |
| 21/01/25 | External Flow | Análisis a través de bibliotecas externas | 1.0 | Versión inicial | Herramienta número 9 |
| 27/01/25 | VWAP | Volume Weighted Average Price | 1.3 | Versión inicial | Herramienta número 10 |
| 02/02/25 | Heikin Ashi | Suavizado de tendencias e identificación de señales de reversión | 1.0 | Versión inicial | Herramienta número 11 |
| 04/02/25 | FibVWAP | Generación de señales mediante análisis con Python | 1.0 | Versión inicial | Herramienta número 12 |
| 14/02/25 | RSI DIVERGENCE | Divergencias entre la acción del precio y el RSI | 1.0 | Versión inicial | Herramienta número 13 |
| 17/02/25 | Parabolic Stop and Reverse (PSAR) | Automatización de la estrategia PSAR | 1.0 | Versión inicial | Herramienta número 14 |
| 20/02/25 | Quarters Drawer Script | Trazar los niveles de los cuartos en el gráfico | 1.0 | Versión inicial | Herramienta número 15 |
| 27/02/25 | Intrusion Detector | Detecta y alerta cuando el precio alcanza niveles de cuartos | 1.0 | Versión inicial | Herramienta número 16 |
| 27/02/25 | TrendLoom Tool | Panel de análisis de múltiples marcos temporales | 1.0 | Versión inicial | Herramienta número 17 |
| 11/03/25 | Quarters Board | Panel con botones para activar o desactivar los niveles de cuartos | 1.0 | Versión inicial | Herramienta número 18 |
| 26/03/25 | ZigZag Analyzer | Trazado de líneas de tendencia con el indicador ZigZag | 1.0 | Versión inicial | Herramienta número 19 |
| 10/04/25 | Correlation Pathfinder | Representación gráfica de correlaciones monetarias mediante bibliotecas de Python | 1.0 | Versión inicial | Herramienta número 20 |
| 23/04/25 | Market Structure Flip Detector Tool | Detección de cambios en la estructura del mercado | 1.0 | Versión inicial | Herramienta número 21 |
| 08/05/25 | Correlation Dashboard | Relación entre diferentes pares | 1.0 | Versión inicial | Herramienta número 22 |
| 13/05/25 | Currency Strength Meter | Medir la fortaleza de cada divisa en diferentes pares | 1.0 | Versión inicial | Herramienta número 23 |
| 21/05/25 | PAQ Analysis Tool | Detector de formación de velas | 1.0 | Versión inicial | Herramienta número 24 |
| 23/05/25 | Pin bar, Engulfing and RSI divergence | Uso de la divergencia del RSI para confirmar las señales de los patrones de «pin bar» y «engulfing» | 1.0 | Versión inicial | Herramienta número 25 |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/17962
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Utilizando redes neuronales en MetaTrader
Análisis de las brechas temporales de precios en MQL5 (Parte I): Creando un indicador básico
Particularidades del trabajo con números del tipo double en MQL4
Algoritmo de ecolocalización de delfines — Dolphin Echolocation Algorithm (DEA)
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso