English Русский 中文 Deutsch 日本語
preview
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 33): Herramienta de teoría del rango de velas

Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 33): Herramienta de teoría del rango de velas

MetaTrader 5Ejemplos |
33 0
Christian Benjamin
Christian Benjamin

Contenido



Introducción

La volatilidad es el lenguaje principal del mercado. Antes de que cualquier oscilador gire, antes de que la mayoría de los filtros de seguimiento de tendencias reaccionen, el precio ya ha expresado una opinión clara a través de la simple distancia que recorre dentro de una sola barra. Una expansión repentina del rango suele indicar una participación agresiva de grandes inversores; una contracción prolongada sugiere que se está retirando liquidez anticipándose al próximo movimiento. Del mismo modo, una barra que permanece completamente dentro de la anterior revela indecisión temporal, mientras que una barra que envuelve el rango anterior refleja un flujo de órdenes decisivo. Estos comportamientos son evidentes, pero rara vez se formalizan en un proceso sólido y legible por máquina.

Este artículo presenta la Candle-Range Theory (CRT), un marco conciso que clasifica cada vela completada en una de cuatro categorías mutuamente excluyentes:

  • Large-Range (LR) – El rango verdadero de la vela supera un múltiplo configurable de su rango verdadero medio (ATR) reciente.
  • Small-Range (SR) – El rango de la vela es inferior a un múltiplo menor del ATR, lo que indica una compresión.
  • Inside Bar (IB) – La vela completa se mantiene dentro de los límites de máximo y mínimo de la vela inmediatamente anterior.
  • Outside Bar (OB) – La vela supera tanto el máximo como el mínimo anteriores durante su duración, abarcando así el rango anterior.

En lugar de introducir otro indicador opaco, CRT se centra en ofrecer estos conceptos bien definidos a través de un conjunto de herramientas ágil y listo para su uso en MetaTrader 5:

  • CRangePattern.mqh – Una clase definida íntegramente en el archivo de cabecera que clasifica una vela en tiempo constante. Solo requiere cuatro matrices de precios (apertura, máximo, mínimo, cierre), devuelve indicadores booleanos para cada patrón y no asigna memoria dinámica.  
  • CRT Indicator.mq5 – Una superposición que resalta cada vela LR, SR, IB y OB mediante rectángulos semitransparentes y flechas opcionales. Los colores, la opacidad, los glifos de flecha y los tamaños son totalmente personalizables, lo que garantiza que la capa visual se integre perfectamente con cualquier plantilla de gráfico existente sin sobrepasar el límite de ocho búferes de la plataforma.  
  • CRT Expert Advisor.mq5 – Un motor de alertas que funciona exclusivamente con barras cerradas, lo que garantiza señales sin repintado. Puede filtrar qué patrones generan ventanas emergentes, sonidos o notificaciones push y, cuando se desea, adjunta automáticamente el indicador para que la información visual y auditiva permanezca sincronizada durante las operaciones en tiempo real o las pruebas retrospectivas visuales.

Todos los componentes se compilan sin advertencias en MetaTrader 5 build 4180 o posterior y cumplen con #property strict. Solo copian la pequeña ventana de historial necesaria para el cálculo del ATR, lo que supone una mínima carga para la CPU incluso en gráficos de alta frecuencia. Debido a que el sistema procesa los datos estrictamente al cierre de cada vela, sus resultados se mantienen estables en todos los marcos temporales, símbolos y modos de prueba.

Los objetivos de este tutorial son cuatro:

  • Proporcionar las definiciones matemáticas precisas de LR, SR, IB y OB.
  • Mostrar cómo integrar la clase CRangePattern en cualquier indicador, EA o script.
  • Explica las decisiones de diseño que hacen que el indicador adjunto sea ligero, no parpadee y sea compatible con diseños de gráficos complejos.
  • Mostrar cómo el Asesor Experto emite alertas seguras para el simulador, lo que permite una evaluación exhaustiva de las señales CRT tanto en entornos históricos como en tiempo real.

Al finalizar este artículo, dispondrás de un marco compacto, pero ampliable, que transforma la volatilidad en bruto en información clara y útil, lista para su análisis discrecional, la negociación automatizada o investigaciones posteriores.

Ventajas del conjunto de herramientas de la teoría de la gama de velas:

Ventaja Descripción Impacto práctico
Definiciones precisas
Los indicadores LR, SR, IB y OB se calculan mediante fórmulas explícitas basadas en el ATR y en la relación de precios.
Elimina cualquier ambigüedad: cada vela pertenece a una —y solo a una— categoría.
Lógica sin repintado
Todos los cálculos se realizan sobre la barra que acaba de cerrarse; no se revisan valores posteriormente.
Las señales se mantienen estables durante las actualizaciones de los gráficos, las optimizaciones y las operaciones en tiempo real.
Mínimo consumo de datos
El indicador solo copia ATR_Period + 3 barras; el EA hace lo mismo.
Reduce el consumo de RAM y acelera la ejecución del Strategy Tester.
Visualización sin búfer
Los gráficos se dibujan con objetos de gráfico, no con búferes de indicadores.
Evita el límite de ocho búferes de MetaTrader; es compatible con plantillas complejas.
Personalización completa
Los colores, la opacidad, los glifos de flecha, el período ATR y los multiplicadores grandes/pequeños son parámetros que introduce el usuario.
Se adapta perfectamente a cualquier guía de estilo de gráficos personales o corporativos.
Arquitectura modular
La clase, el indicador y el EA son archivos independientes que se comunican a través de interfaces bien definidas.
Los desarrolladores pueden integrar la clase en otros proyectos o cambiar el indicador sin necesidad de refactorizar el código.
Cumplimiento en modo estricto
Todos los archivos fuente se compilan correctamente bajo #property strict en la compilación 4180+.
Garantiza la máxima compatibilidad con futuras versiones de MetaTrader.
Normalización ATR Los umbrales de rango se ajustan automáticamente a la volatilidad del instrumento. La configuración se transfiere de forma fiable entre Forex, CFD, criptomonedas, índices y futuros.


Resumen de la estrategia

La teoría del rango de velas clasifica cada vela completa en una —y solo una— de cuatro categorías. Una vela cuyo rango real se expande mucho más allá de la volatilidad reciente se denomina vela de rango amplio (LR), mientras que una que se contrae a una fracción de lo normal se denomina vela de rango pequeño (SR). Si todo el rango máximo-mínimo de la nueva barra se encuentra dentro del rango de la barra anterior, se convierte en una Barra Interior (IB); por el contrario, si excede tanto el máximo como el mínimo anteriores, se marca como una Barra Exterior (OB). Las secciones siguientes explican los fundamentos estadísticos y las reglas precisas utilizadas para detectar cada uno de estos cuatro patrones.

True Range (TR)

Es la medida de Wilder de la volatilidad pura. Captura el movimiento total de precios de un período, incluyendo cualquier brecha, tomando el mayor de los siguientes:

  • Corriente alta menos corriente baja
  • Valor absoluto del máximo actual menos el cierre anterior
  • Valor absoluto del mínimo actual menos el cierre anterior
TR = max(
  Highₜ – Lowₜ,
 │Highₜ – Closeₜ₋₁│,
  │Lowₜ – Closeₜ₋₁│
)

Al utilizar el «True Range» en lugar de limitarse al rango entre el máximo y el mínimo, se recogen íntegramente las brechas nocturnas, lo que garantiza que las medidas de volatilidad se mantengan coherentes en todos los instrumentos y sesiones de negociación.

Average True Range (ATR)

Para poner la volatilidad en contexto, el «True Range» sin procesar por sí solo no es significativo: 25 pips en el EURUSD es una cifra importante, pero 25 pips en el XAUUSD es insignificante. La teoría del rango de las velas explica este fenómeno normalizando el rango verdadero de cada período con respecto a la media de los últimos N valores, lo que suaviza los picos brutos y proporciona un punto de referencia coherente de la volatilidad.

// Simple arithmetic ATR
double ATR(const int shift,const int period,
           const double &H[],const double &L[],const double &C[])
{
   double sum = 0.0;
   for(int i = shift; i < shift + period; ++i)
      sum += MathMax(H[i]-L[i],
              MathMax(MathAbs(H[i]-C[i+1]),
                      MathAbs(C[i+1]-L[i])));
   return sum / period;
}

En la práctica, el CRT aplica una simple media aritmética —en lugar del suavizado exponencial de Wilder— porque es rápido, transparente y perfectamente adecuado para clasificar el comportamiento de los precios. De forma predeterminada, utiliza una ventana de 14 barras, que se ajusta a la configuración estándar del ATR.

Multiplicadores de rango: umbrales objetivos

Dos multiplicadores definidos por el usuario convierten el ATR en umbrales categóricos:
  • largeMult (valor predeterminado = 1,5)
  • smallMult (valor predeterminado = 0,5)
// ---- User-defined ATR multipliers --------------------------------------
input double largeMult = 1.5;   // Bars ≥ 1.5 × ATR are flagged “Large-Range”
input double smallMult = 0.5;   // Bars ≤ 0.5 × ATR are flagged “Small-Range”
Estos parámetros responden a:
  1. ¿Cuánto más grande que el promedio debe ser una barra para ser considerada inusualmente grande?
  2. ¿Qué tan pequeña debe ser una barra para que la consideremos comprimida?

Al expresar estos umbrales en unidades ATR, el CRT se mantiene compatible con diferentes símbolos, marcos temporales y regímenes de volatilidad.

Barras Large-Range (LR): Indicio de una participación urgente

Una vela se considera de «amplio rango» cuando su rango real es igual o superior al múltiplo seleccionado (largeMult) del ATR actual.
// ---- Large-Range (LR) test ---------------------------------------------
bool isLargeRange = (trueRange >= largeMult * atrCurrent);

La participación significativa, a menudo desencadenada por noticias programadas o transacciones en bloque, genera rangos de esta magnitud. Estas grandes barras suelen anunciar el inicio de un movimiento direccional sostenido o la capitulación final de la tendencia anterior. En ambos casos, se trata de eventos repletos de información: el "qué" (un rango anormalmente amplio) está perfectamente claro, aunque el "por qué" (publicación de resultados, datos macroeconómicos, liquidaciones forzadas) no lo esté.

Barras Small-Range (SR): Compresión de la volatilidad

Por el contrario, una vela se considera de «rango reducido» cuando su rango real no supera la fracción elegida (smallMult) del ATR vigente. Una contracción persistente indica una menor liquidez, operaciones de cobertura por parte de los traders o un libro de órdenes equilibrado.

// ---- Small-Range (SR) test ---------------------------------------------
bool isSmallRange = (trueRange <= smallMult * atrCurrent);

Los mercados rara vez permanecen tranquilos indefinidamente; la concentración de barras SR suele marcar la pausa previa a una nueva expansión, lo que las convierte en un elemento valioso en las estrategias de ruptura y straddle.

Barras internas (IB): contención e indecisión

Una vela se clasifica como «Inside Bar» cuando todo su rango queda comprendido dentro del de la vela anterior; es decir, su máximo es inferior al máximo anterior y su mínimo es superior al mínimo anterior.

// Inside-Bar test for the candle at 'shift' (e.g., shift = 1 → just-closed bar)
bool isInsideBar = (High[shift] < High[shift + 1]) &&   // current high is lower than previous high
                   (Low[shift]  > Low[shift + 1]);      // current low  is higher than previous low

Estas barras indican un flujo de órdenes intenso, que a menudo se debe a la búsqueda de órdenes stop-loss, a liquidaciones forzadas o a una acumulación o distribución agresiva. Dado que el mercado atraviesa ambos lados de la vela anterior, los OBs comprimen múltiples niveles de stop en una sola sesión, lo que suele dar lugar a: (a) una reversión duradera si predomina la absorción, o (b) una aceleración de la tendencia original si la liquidez de la ruptura se agota rápidamente.

Exclusividad mutua y jerarquía

Las cuatro categorías están concebidas para ser mutuamente excluyentes; una vela puede ajustarse, como mucho, a una sola definición:

  • Si se trata de LR o SR, prevalecen las reglas de rango y magnitud.
  • Si no es ni LR ni SR, el sistema comprueba si es IB.
  • Solo si falla el IB se comprueba el OB.

Esta jerarquía elimina la superposición interpretativa y garantiza que la lógica posterior (alertas, representación gráfica) no dé lugar a ambigüedades.

Disciplina temporal: procesamiento con barra cerrada

El CRT analiza únicamente la vela que se acaba de cerrar (barra 1), sin tener en cuenta la barra que aún se está formando (barra 0). Esto garantiza que no se modifiquen las señales: lo que ves en tiempo real es exactamente lo que habría arrojado una prueba retrospectiva.

De los datos brutos a las pistas útiles

Al clasificar cada barra en uno de los cuatro estados, CRT ofrece:

  • Un flujo de señales binarias para estrategias automatizadas (indicadores de «verdadero» o «falso» por categoría)
  • Un lenguaje visual para la negociación discrecional (barras y flechas codificadas por colores)
  • Un marco de activación para alertas y filtros adicionales (tendencia, sesión, volumen)


Desglose del código

El conjunto de herramientas de la «Teoría de la gama de velas» tiene un diseño deliberadamente modular. Cada componente —el archivo de cabecera, el indicador y el asesor experto— realiza una única tarea claramente definida y se comunica con los demás a través de una interfaz mínima. En esta sección se analiza el código fuente siguiendo el mismo orden en que MetaTrader lo ejecuta, explicando la finalidad de cada bloque principal y los motivos que justifican las decisiones de implementación.  

CandleRangeTheory.mqh: el motor de clasificación

El encabezado comienza con #property strict, lo que garantiza una comprobación de tipos moderna y elimina las tolerancias de los compiladores antiguos. Inmediatamente después, se declara la clase CRangePattern. Sus miembros de datos públicos —atrPeriod, largeMult y smallMult— actúan como parámetros en tiempo de ejecución en lugar de como constantes codificadas de forma fija, lo que garantiza que cualquier script que incluya el encabezado pueda ajustar el comportamiento sin necesidad de recompilar la propia clase. Cuatro indicadores booleanosisLarge, isSmall, isInside y isOutside— conforman la interfaz de salida. Una vez que Calculate() devuelva un resultado, exactamente una de estas condiciones será cierta; el programa que realiza la llamada no necesita realizar más cálculos aritméticos para determinar qué ha ocurrido en la vela analizada.

#property strict               // enforce modern type checking
#ifndef  __CANDLE_RANGE_THEORY_MQH__
#define  __CANDLE_RANGE_THEORY_MQH__

class CRangePattern
{
public:
   int    atrPeriod;           // ATR length
   double largeMult,smallMult; // LR / SR thresholds

   bool   isLarge,isSmall,
          isInside,isOutside;  // output flags
   double atr,trueRange,bodyRange;

El constructor asigna valores por defecto prácticos —un ATR de catorce períodos, un multiplicador grande de 1,5 y un multiplicador pequeño de 0,5— y, a continuación, llama a una función auxiliar privada Reset() que borra todos los campos de resultados y los restablece a un estado conocido. El uso de una función auxiliar evita la duplicación de código; la misma rutina se invoca tanto en el momento de la construcción como al inicio de cada cálculo.

private:
   void Reset()
   {
      isLarge=isSmall=isInside=isOutside=false;
      atr=trueRange=bodyRange=0.0;
   }

public:
   CRangePattern()             // default parameters
   {
      Reset();
      atrPeriod=14;
      largeMult=1.5;
      smallMult=0.5;
   }

La función Calculate() es, por sí misma, intencionadamente concisa. En primer lugar, comprueba que se disponga de un historial suficiente (barras < atrPeriod + sh + 2), ya que tanto el ATR como el rango real deben tomar como referencia al menos una barra anterior al punto de evaluación. El rango real y el rango corporal se calculan de acuerdo con la definición de Wilder, lo que garantiza la compatibilidad con cualquier lectura estándar del ATR, ya sea procedente de este script o de un indicador externo.

bool Calculate(const int sh,
               const double &H[],const double &L[],
               const double &O[],const double &C[],
               const int bars)
{
   Reset();
   if(bars < atrPeriod + sh + 2)   // enough candles?
      return false;

   // true range of target candle
   trueRange = MathMax(H[sh]-L[sh],
               MathMax(MathAbs(H[sh]-C[sh+1]),
                       MathAbs(C[sh+1]-L[sh])));
   bodyRange  = MathAbs(O[sh]-C[sh]);

El bucle ATR se repite exactamente atrPeriod veces. Dado que la comprobación previa garantiza que i + 1 está dentro de los límites, la comprobación interna && i+1 < bars resultaría redundante y, por lo tanto, se omite. Al eliminar esa protección, se simplifica la ruta del código y se suprime una ramificación, lo que mejora el rendimiento con datos de alta frecuencia sin comprometer la seguridad.

   double sum = 0.0;
   for(int i = sh; i < sh + atrPeriod; ++i)      // exactly atrPeriod
   {
      double tr = MathMax(H[i]-L[i],
                  MathMax(MathAbs(H[i]-C[i+1]),
                          MathAbs(C[i+1]-L[i])));
      sum += tr;
   }
   atr = sum / atrPeriod;

Una vez calculada la media, la función clasifica la vela. Si el rango real supera el múltiplo superior, se establece isLarge; si queda por debajo del múltiplo inferior, se establece isSmall. Una segunda capa de comparación evalúa la relación con los máximos y mínimos de la vela anterior, activando isInside o isOutside según corresponda. Dado que los cuatro indicadores son mutuamente excluyentes, no es necesario realizar más comprobaciones, y la función devuelve «true» para confirmar que se ha completado.

   if(trueRange >= largeMult*atr)      isLarge   = true;
   else
   if(trueRange <= smallMult*atr)      isSmall   = true;

   if(H[sh] < H[sh+1] && L[sh] > L[sh+1])        isInside  = true;
   else
   if(H[sh] > H[sh+1] && L[sh] < L[sh+1])        isOutside = true;

   return true;
}
#endif

CRT Indicator.mq5 – Presentación visual

El indicador no utiliza ningún búfer; en su lugar, se basa completamente en objetos de gráfico. Al evitar los buffers, el script sortea el límite de ocho buffers de MetaTrader, dejando espacio para que los operadores combinen la superposición con otros estudios. Al inicializarse, los valores introducidos en el cuadro de diálogo «Entradas» se escriben directamente en los campos públicos de una instancia interna de CRangePattern denominada «pat». No se almacena nada más a nivel global, lo que garantiza que un cambio de parámetro en MetaTrader dé lugar a una reinicialización completa, en lugar de a una transferencia parcial del estado.

#property indicator_chart_window
#include <CandleRangeTheory.mqh>

input int     ATR_Period = 14;
...
CRangePattern pat;

int OnInit()
{
   pat.atrPeriod = ATR_Period;
   pat.largeMult = LargeXATR;
   pat.smallMult = SmallXATR;
   return(INIT_SUCCEEDED);
}

La función OnCalculate() se invoca cada vez que MetaTrader detecta que hay nuevos datos disponibles. La función comprueba primero que el gráfico tenga al menos atrPeriod + 3 barras: dos más, ya que el bucle ATR requiere una barra anterior a la actual y la propia función Calculate() hace referencia a la vela en el índice shift + 1. Solo se copia un pequeño fragmento de la historia de este tamaño en cuatro matrices locales (H, L, O, C). A continuación, cada matriz se marca como una serie, de modo que el índice 0 siempre haga referencia a la barra más reciente.

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
   const int need = pat.atrPeriod + 3;
   if(rates_total < need) return rates_total;

   double H[],L[],O[],C[];
   ArrayResize(H,need); ArraySetAsSeries(H,true);
   ArrayResize(L,need); ArraySetAsSeries(L,true);
   ArrayResize(O,need); ArraySetAsSeries(O,true);
   ArrayResize(C,need); ArraySetAsSeries(C,true);

   CopyHigh (_Symbol,_Period,0,need,H);
   CopyLow  (_Symbol,_Period,0,need,L);
   CopyOpen (_Symbol,_Period,0,need,O);
   CopyClose(_Symbol,_Period,0,need,C);

Una vez preparados los datos, se llama a pat.Calculate(1, …). Al pasar un desplazamiento de uno, se garantiza que el análisis se realice sobre la barra cerrada más reciente, y nunca sobre la vela que aún se está formando. Si la clasificación no arroja ningún indicador de actividad —es decir, si la vela no es ni grande ni pequeña, ni interior ni exterior—, la función finaliza inmediatamente y el gráfico permanece sin cambios. Cuando se detecta un patrón, el indicador selecciona las propiedades de visualización: el color del rectángulo se deriva de los valores ARGB (lo que permite controlar la opacidad) y el código y el color de la flecha se ajustan a las preferencias del usuario. 

   if(!pat.Calculate(1,H,L,O,C,need)) return rates_total;

   uint  rClr  = 0;         // rectangle colour (ARGB)
   int   aCode = 221;       // ● default arrow
   color aClr  = clrYellow;

   if(pat.isLarge)
   {
      bool bull = (C[1] > O[1]);
      rClr  = ColorToARGB(bull?clrLime:clrRed,Opacity);
      aCode = bull ? 233 /*▲*/ : 234 /*▼*/;
      aClr  = bull ? clrLime     : clrRed;
   }
   else if(pat.isSmall)     { rClr = ColorToARGB(clrYellow,Opacity); }
   else if(pat.isInside)    { rClr = ColorToARGB(clrAqua,Opacity);   }
   else if(pat.isOutside)   { rClr = ColorToARGB(clrMagenta,Opacity);}
   else return rates_total; // nothing to draw

La creación de rectángulos utiliza dos coordenadas temporales: la apertura de la barra en el shift 2 y la apertura de la barra en el shift 1; esto abarca toda la duración de la vela objetivo. Los valores máximo y mínimo de la vela objetivo definen los límites verticales. OBJPROP_FILL está configurado como verdadero, por lo que el rectángulo se muestra como un bloque translúcido en lugar de un marco hueco. A continuación, se coloca una flecha opcional a una distancia ligeramente superior o inferior a la vela, ajustada según la escala ATR, para mantener la visibilidad en instrumentos con tamaños de tick muy diferentes. Tanto el rectángulo como la flecha están etiquetados con la marca de tiempo de apertura de la vela, lo que hace que sus nombres sean únicos y permite que el script elimine los duplicados anteriores antes de dibujar nuevos objetos. 

   datetime tClosed = iTime(_Symbol,_Period,1);
   string tagR = "CRT_RECT_"+(string)tClosed;
   string tagA = "CRT_ARW_" +(string)tClosed;

   ObjectDelete(0,tagR);                     // avoid duplicates
   ObjectCreate(0,tagR,OBJ_RECTANGLE,0,
                iTime(_Symbol,_Period,2),H[1],
                tClosed,L[1]);
   ObjectSetInteger(0,tagR,OBJPROP_COLOR,rClr);
   ObjectSetInteger(0,tagR,OBJPROP_FILL,true);
   ObjectSetInteger(0,tagR,OBJPROP_BACK,true);

   double y = (aCode==233 ? H[1]+0.2*pat.atr : L[1]-0.2*pat.atr);
   ObjectCreate(0,tagA,OBJ_ARROW,0,tClosed,y);
   ObjectSetInteger(0,tagA,OBJPROP_ARROWCODE,aCode);
   ObjectSetInteger(0,tagA,OBJPROP_COLOR,aClr);
   return rates_total;
}

CandleRangeTheory.mq5 – Generación de alertas

El asesor experto comparte el mismo encabezado y, por lo tanto, la misma lógica de clasificación determinista. Al iniciarse, duplica el paso de transferencia de parámetros que se lleva a cabo en el indicador. Además, comprueba si se está ejecutando en el modo sin interfaz gráfica del Strategy Tester; si es así, desactiva las funciones de la interfaz gráfica, como Alert() o PlaySound(), evitando así que se produzcan errores en tiempo de ejecución durante la optimización por lotes.

#include <CandleRangeTheory.mqh>
input bool Push_Alerts = false;
...
CRangePattern pat;
const bool NonVisualTest = (bool)MQLInfoInteger(MQL_TESTER) &&
                           !MQLInfoInteger(MQL_VISUAL_MODE);

int OnInit()
{
   pat.atrPeriod = ATR_Period;
   pat.largeMult = LargeXATR;
   pat.smallMult = SmallXATR;
   return INIT_SUCCEEDED;
}

Cuando se incorpora el EA a un gráfico en tiempo real o a una prueba visual, utiliza iCustom() para cargar el indicador automáticamente. El éxito o el fracaso se anotan en el diario de los expertos en aras de la transparencia. Al desinicializarse, los identificadores de los indicadores se liberan manualmente para evitar fugas de memoria y la saturación del gráfico.

int indHndl = INVALID_HANDLE;

int OnInit()
{
   ...
   if(!NonVisualTest)
   {
      indHndl = iCustom(_Symbol,_Period,"CRT Indicator",
                        ATR_Period,LargeXATR,SmallXATR);
      if(indHndl != INVALID_HANDLE)
         ChartIndicatorAdd(0,0,indHndl);
   }
   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason)
{
   if(indHndl != INVALID_HANDLE)
      IndicatorRelease(indHndl);
}

La lógica principal se encuentra dentro de OnTick(). El EA registra la hora de apertura de la vela en el shift 1 y no vuelve a ejecutarse hasta que ese valor cambie, lo que garantiza exactamente una evaluación por cada vela completada, independientemente de la frecuencia de los ticks. Se copia un bloque histórico compacto; en esta ocasión, las matrices se convierten explícitamente en series para ajustarlas a los requisitos de CRangePattern. Si la clasificación da como resultado un patrón activo, el EA elabora un mensaje en lenguaje sencillo que incluye el símbolo, el intervalo de tiempo y la categoría detectada. Las notificaciones emergentes, sonoras y push se envían según la configuración del usuario, pero solo cuando el entorno de ejecución actual lo permita. 

datetime lastDone = 0;

void OnTick()
{
   datetime tClosed = iTime(_Symbol,_Period,1);
   if(tClosed == lastDone) return;      // already processed
   lastDone = tClosed;

   const int need = pat.atrPeriod + 3;
   double H[],L[],O[],C[];
   ArrayResize(H,need); ArraySetAsSeries(H,true);
   ArrayResize(L,need); ArraySetAsSeries(L,true);
   ArrayResize(O,need); ArraySetAsSeries(O,true);
   ArrayResize(C,need); ArraySetAsSeries(C,true);

   CopyHigh (_Symbol,_Period,0,need,H);
   CopyLow  (_Symbol,_Period,0,need,L);
   CopyOpen (_Symbol,_Period,0,need,O);
   CopyClose(_Symbol,_Period,0,need,C);

   if(!pat.Calculate(1,H,L,O,C,need)) return;

   string sig;
   if(pat.isLarge)   sig="Large-Range bar";
   else if(pat.isSmall)   sig="Small-Range bar";
   else if(pat.isInside)  sig="Inside bar";
   else if(pat.isOutside) sig="Outside bar";
   if(sig=="") return;

   string msg = _Symbol+" "+EnumToString(_Period)+"  "+sig;
   Print("[CRT-EA] ",msg);

   if(!NonVisualTest) Alert(msg);
   if(Push_Alerts)    SendNotification(msg);
}

A lo largo de la EA, las instrucciones de depuración opcionales proporcionan información concisa sobre acciones como la incorporación correcta de un indicador o la falta de un historial adecuado. Dado que estos mensajes dependen del indicador DebugLog, las implementaciones en producción pueden ejecutarse de forma silenciosa, mientras que las sesiones de desarrollo o investigación pueden estar totalmente instrumentadas. 

input bool DebugLog = true;

if(DebugLog)
   PrintFormat("[CRT-EA] Attached on %s %s  (tester=%d)",
               _Symbol,EnumToString(_Period),
               (int)MQLInfoInteger(MQL_TESTER));

El conjunto de herramientas evita el estado estático o global mutable más allá de los objetos que se requieren explícitamente para su funcionamiento. Todos los objetos dinámicos creados en el gráfico son liberados automáticamente por MetaTrader cuando se elimina su indicador principal, o bien se eliminan explícitamente mediante código. Ningún array persistente crece con el tiempo; cada tick activa una copia de tamaño fijo y una pasada de clasificación cuya complejidad temporal es independiente de la longitud del gráfico. Por consiguiente, el sistema se adapta a gráficos semanales y a barras de un segundo sin necesidad de modificaciones y sin riesgo de que se produzca una pérdida gradual de rendimiento.

// inside any function needing history
const int need = pat.atrPeriod + 3;
double  H[need], L[need], O[need], C[need];   // stack allocation in C++17 style
// (or ArrayResize + quick release when the function exits)


Pruebas y resultados

En esta sección, analizamos los resultados de las pruebas en entorno real que se presentan a continuación.

El GIF que aparece a continuación muestra un gráfico Step-Index en tiempo real de 5 minutos generado por CRT_EA. A medida que se va cerrando cada barra, verás aparecer cuadros de colores, marcadores y flechas que indican si la volatilidad se está reduciendo, expandiendo o si engloba por completo el rango anterior. Se agrupan una serie de barras «internas» tranquilas y estrechas, y de repente surge una vela de amplio rango, lo que indica un estallido de impulso. Entre bastidores, cada vela se compara al instante con el ATR actual y se reclasifica, de modo que obtienes una visión general ininterrumpida y codificada por colores de la energía del mercado sin que se vuelvan a dibujar las barras anteriores. Esta visualización en tiempo real permite detectar fácilmente cuándo el mercado se está consolidando, cuándo rompe esa consolidación y cómo contribuye cada barra al ciclo de volatilidad más amplio.

La tabla que figura a continuación resume las observaciones clave extraídas del gráfico anterior, mientras que los diagramas siguientes mostrarán el rendimiento del conjunto de herramientas con otros símbolos y intervalos de tiempo.

Clase Color del rectángulo Flecha/Marcador Significado
Barra Large-Range (LR) Borde Royal-Blue Lime si la tendencia es alcista, Red si es bajista Rango anormalmente amplio: rango ≥ largeMult × ATR
Barra Small-Range (SR) Borde Yellow Punto color Yellow Rango comprimido: rango ≤ smallMult × ATR
Inside-Bar (IS) Borde Aqua Punto color Aqua Máximo < máximo anterior y mínimo > mínimo anterior
Fuera de la barra (OB) Borde Magenta Punto color Magenta Máximo > máximo anterior y mínimo < mínimo anterior
  • Gráfico del Step Index

  • Gráfico del índice Crash 1000

  • Gráfico del índice Boom 1000

B



Conclusión

El conjunto de herramientas «Candle-Range Theory» ofrece una solución completa y modular para el análisis de rangos en MetaTrader 5.

  • CRangePattern — Una clase compacta e independiente que identifica las barras de «Large-Range», «Small-Range», «Inside» y «Outside» sin repintado.
  • CRT_Indicator — Superpone las señales con recuadros y flechas codificados por colores para facilitar una interpretación visual inmediata.
  • CRT_EA — Convierte esas mismas señales en alertas u órdenes automáticas.

Todos los parámetros —longitud del ATR, multiplicadores pequeños y grandes, reglas de alerta— son totalmente configurables, lo que permite que el marco se adapte a cualquier símbolo, marco temporal o régimen de volatilidad. Dado que la lógica de detección está aislada de las capas de visualización y ejecución, puedes ampliarla o integrarla en escáneres, paneles de control o sistemas de negociación completos con cambios mínimos en el código.

Este conjunto de herramientas está destinado a fines educativos y debe probarse en una cuenta de demostración antes de cualquier implementación en producción. Combina sus señales de rango objetivo con tus propias reglas de selección de operaciones y gestión de riesgos para asegurarte de que la metodología se ajuste a tu estrategia general.

Utilizada de esta manera, la teoría de los rangos de velas te permite identificar, visualizar y actuar ante episodios de volatilidad con rapidez, claridad y confianza.





   
Chart Projector
Analytical Comment
Analytics Master
Analytics Forecaster 
Volatility Navigator
Mean Reversion Signal Reaper
Signal Pulse 
Metrics Board 
External Flow
VWAP
Heikin Ashi   FibVWAP  
RSI DIVERGENCE
Parabolic Stop and Reverse (PSAR) 
Quarters Drawer Script
Intrusion Detector
TrendLoom Tool  Quarters Board 
ZigZag Analyzer  Correlation Pathfinder  Market Structure Flip Detector Tool
Correlation Dashboard   Currency Strength Meter 
PAQ Analysis Tool 
Dual EMA Fractal Breaker
Pin bar, Engulfing and RSI divergence
Liquidity Sweep Opening Range Breakout Tool Boom and Crash Interceptor CCI Zer-Line EA
Candlestick Recognition Candlestick Detection using TA-Lib Candle Range Tool      

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

Archivos adjuntos |
CRT_EA.mq5 (8.11 KB)
Utilizando redes neuronales en MetaTrader Utilizando redes neuronales en MetaTrader
En el artículo se muestra la aplicación de las redes neuronales en los programas de MQL, usando la biblioteca de libre difusión FANN. Usando como ejemplo una estrategia que utiliza el indicador MACD se ha construido un experto que usa el filtrado con red neuronal de las operaciones. Dicho filtrado ha mejorado las características del sistema comercial.
Análisis de la dinámica horaria de los símbolos de trading y de sus spreads en MetaTrader 5 Análisis de la dinámica horaria de los símbolos de trading y de sus spreads en MetaTrader 5
El indicador de índice de estacionalidad ProSpread con media móvil, como herramienta de análisis técnico que identifica patrones estacionales en el movimiento del precio, analiza el comportamiento del precio en determinadas horas de negociación, puede usarse tanto con un único instrumento como con el spread entre dos activos, y visualiza la probabilidad estadística de movimientos direccionales.
Particularidades del trabajo con números del tipo double en MQL4 Particularidades del trabajo con números del tipo double en MQL4
En estos apuntes hemos reunido consejos para resolver los errores más frecuentes al trabajar con números del tipo double en los programas en MQL4.
Redes neuronales en el trading: entrenamiento de metaparámetros basado en la heterogeneidad (HimNet) Redes neuronales en el trading: entrenamiento de metaparámetros basado en la heterogeneidad (HimNet)
Te invitamos a conocer el framework HimNet, que combina la flexibilidad de la adaptación espaciotemporal con una alta eficiencia computacional, lo que permite obtener pronósticos precisos y estables en series temporales financieras. En el artículo se muestra en detalle cómo interactúan entre sí sus componentes clave, convirtiendo algoritmos complejos en una arquitectura manejable.