De principiante a experto: programando velas japonesas
Contenido
- Introducción
- Comprender los datos de velas y sus matemáticas de programación fundamentales
- Creación de una colección de patrones de velas japonesas conocidos y una biblioteca de funciones de patrones de velas japonesas reutilizables
- Pruebas
- Conclusión
Introducción
Con el tiempo, hemos aprendido y memorizado numerosos nombres de patrones de velas. Sin embargo, identificarlos a simple vista en un gráfico es una tarea compleja y puede verse afectada por errores de paralaje. La ilusión de mala interpretación es muy posible debido a cómo se define típicamente la lógica del patrón de velas.
Por ejemplo, un patrón envolvente alcista consiste en una vela bajista seguida de una alcista. La vela alcista abre por debajo del cierre de la vela bajista y cierra por encima de su apertura, cubriendo completamente el cuerpo de la vela bajista en una serie temporal. El desafío radica en juzgar con precisión la posición de apertura de la vela alcista en relación con el cierre de la vela bajista. El ojo humano es propenso a errores de juicio ocasionales, especialmente al analizar gráficos visualmente.
Ahora, imagine probar este patrón manualmente en datos históricos: sería difícil y propenso a múltiples errores. Sin embargo, si un algoritmo está codificado adecuadamente para detectar estos patrones y colocar marcadores estratégicos en el gráfico, identificarlos y realizar pruebas retrospectivas se vuelve mucho más fácil y preciso.
Propósito de este artículo
En esta discusión, mi objetivo es explorar la programación de patrones de velas, las matemáticas fundamentales detrás de ellos en MQL5 y, en última instancia, desarrollar una biblioteca de patrones de velas, basándome en las existentes.
Muchos sitios web de inversión enumeran una gran cantidad de patrones de velas en lenguaje natural, pero solo unos pocos se esfuerzan al máximo para explorar su estructura algorítmica. Algunos podrían afirmar que ya se han definido todos los patrones de velas posibles. Sin embargo, creo que todavía hay espacio para la innovación: se pueden descubrir y nombrar nuevos patrones.
En esta discusión, cubriremos algunos patrones bien conocidos y le brindaremos la capacidad de codificar cualquier patrón de velas que observe en un gráfico y nombrarlo a su manera. Para simplificar las cosas, nos centraremos en patrones populares para una mejor comprensión.
Es importante reconocer que codificar e inventar nuevos patrones puede ser un proceso tedioso, pero la recompensa es significativa: crear un algoritmo que automatice el reconocimiento de patrones lo liberará del análisis manual repetitivo de por vida.
¿Que sigue?
La siguiente sección está repleta de mi investigación y conceptos clave que he recopilado para dar estructura a esta discusión. Siga atentamente y estoy seguro de que encontrará gran valor en esta lectura.
Comprender los datos de velas y sus matemáticas de programación fundamentales
Supongo que ya está familiarizado con los conceptos básicos de los patrones de velas de varias fuentes, incluida la Comunidad MQL5, otros sitios web y libros. Si necesita refrescar la memoria, puede echar un vistazo rápido a este enlace para obtener información básica antes de continuar. Mi objetivo aquí no es reinventar la rueda, sino demostrar cómo podemos aplicar el lenguaje MQL5 para traducir el análisis de velas tradicional a un marco algorítmico. Este enfoque ayuda a quienes entienden los patrones de velas a desarrollar conceptualmente una mentalidad algorítmica más estructurada, lo que potencialmente les permite comenzar a automatizar sus propias estrategias comerciales en MQL5.
Para un principiante, es importante comenzar con conceptos simples y desarrollar gradualmente sus habilidades de codificación. Comience aprendiendo a definir velas alcistas y bajistas utilizando operadores relacionales básicos. Una vez que se sienta cómodo con estas comparaciones, pase a patrones de una sola vela integrando operaciones aritméticas para medir los tamaños del cuerpo y las longitudes de la mecha. Después de dominar el análisis de una sola vela, pase a los patrones de múltiples velas, donde aprenderá a utilizar la indexación para comparar datos de múltiples velas. Probar tu trabajo con funciones como Print() ayuda a verificar que tu lógica funciona según lo esperado.
En una revisión rápida, las velas son una herramienta visual utilizada en el trading para mostrar cómo se mueven los precios durante un período específico, como una hora o un día. Cada vela está definida por cuatro precios clave: el de apertura (el precio al comienzo del período), el máximo (el precio máximo durante el período), el mínimo (el precio mínimo) y el de cierre (el precio al final del período). El “cuerpo” de la vela representa el rango entre la apertura y el cierre, mientras que las “mechas” o sombras se extienden desde el cuerpo hasta los precios máximos y mínimos. Esta estructura le permite evaluar rápidamente el sentimiento del mercado. Por ejemplo, si el precio de cierre es más alto que el precio de apertura, la vela se considera alcista, lo que indica un impulso ascendente. Por el contrario, si el precio de cierre es inferior al precio de apertura, es bajista, lo que indica una tendencia bajista.
Quiero presentarles algunos términos clave que creo que son esenciales cuando comienzan a trabajar con datos de series de tiempo. Estos conceptos son fundamentales para comprender e implementar el reconocimiento de patrones de velas en MQL5. Los he explicado con mis propias palabras basándome en mi investigación para proporcionar una interpretación clara y práctica:
Estos son operadores de comparación, similares a las desigualdades que quizás hayas aprendido en la escuela secundaria. Sin embargo, en MQL5, se aplican desde una perspectiva diferente dentro de la lógica de programación. Se explican detalladamente en la documentación de MQL5, junto con otras operaciones de uso común. A continuación se muestra una lista de los operadores relacionales que utilizamos en nuestra discusión.
- < (menor que)
- > (mayor que)
- == (igual a)
- != (no es igual a)
- <= (menor o igual que)
- >= (mayor o igual que)
Es importante tener en cuenta que estos operadores no se limitan únicamente a la programación de patrones de velas. También se pueden utilizar para comparar distintos valores de mercado y desempeñan un papel crucial en la toma de decisiones en el trading algorítmico.
En los datos de series de tiempo, cada vela (o barra) está referenciada por un índice. La barra más reciente tiene un índice de 0, mientras que las barras más antiguas se referencian utilizando valores de índice crecientes (por ejemplo, 1, 2, 3, etc.). Comprender esto ayuda a iterar correctamente los datos de precios históricos.
Una serie temporal es un tipo especial de matriz que se utiliza para almacenar datos históricos de precios o indicadores, donde la indexación está invertida. En una serie temporal, se accede a los datos más recientes (como la barra actual o la más reciente) en el índice 0, y los datos más antiguos siguen en números de índice más altos.
ATR es un indicador de volatilidad que define umbrales dinámicos para los patrones de velas, lo que garantiza la adaptabilidad a las condiciones del mercado. Por ejemplo, un patrón Hammer (Martillo) requiere un cuerpo pequeño (menos del 30 % de ATR) y una mecha inferior al menos el doble del tamaño del cuerpo, lo que permite una detección flexible en diferentes activos y períodos de tiempo.
El desafío es definir qué significa “pequeño”, “largo” o “grande”. Un valor fijo (por ejemplo, 10 pips para un cuerpo pequeño) no funcionará de manera consistente en diferentes activos o condiciones de mercado. Un movimiento de 10 pips puede ser significativo para un par de baja volatilidad como EUR/USD en un gráfico de 5 minutos, pero trivial para un par volátil como GBP/JPY en un gráfico diario. Aquí es donde ATR brilla: proporciona un umbral dinámico ajustado a la volatilidad y adaptado al activo y al período de tiempo.
Al utilizar ATR, las condiciones para identificar patrones de velas se vuelven adaptativas:
- En mercados de alta volatilidad (ATR alto), un “cuerpo pequeño” puede ser más grande en términos absolutos, pero aún pequeño en relación con las oscilaciones recientes de precios.
- En mercados de baja volatilidad (ATR bajo), incluso un pequeño movimiento absoluto podría considerarse significativo.
5. MathAbs
MathAbs es una función incorporada en MQL5 que calcula el valor absoluto de un número. El valor absoluto es simplemente la distancia del número al cero, resultando siempre en un valor no negativo (positivo o cero).
Cómo funciona en este contexto:
- Si le das un número negativo, lo cambia a positivo. Por ejemplo, MathAbs(-5) devuelve 5.
- Si el número ya es positivo o cero, permanece igual. Por ejemplo, MathAbs(5) devuelve 5 y MathAbs(0) devuelve 0.
En un patrón de velas, MathAbs se utiliza para medir el tamaño del cuerpo de una vela, que es la diferencia entre el precio de cierre (Close[1]) y el precio de apertura (Open[1]), es decir, Close[1] - Open[1].
¿Por qué utilizar MathAbs?
1. Porque el tamaño del cuerpo debe ser un valor positivo, independientemente de si la vela es alcista (cierre > apertura) o bajista (cierre < apertura). Por ejemplo:
- Vela alcista: Close[1] = 10, open[1] = 8 → 10 - 8 = 2.
- Vela bajista: Close[1] = 8, open[1] = 10 → 8 - 10 = -2, pero MathAbs(8 - 10) = 2.
2. Esto garantiza que el tamaño del cuerpo sea siempre positivo para una comparación consistente en las reglas de patrón.
Comparación de precios con operadores relacionales en MQL5
En MQL5, los operadores relacionales son herramientas esenciales que permiten comparar valores, como los precios de apertura y cierre de una vela. Los operadores que mencionamos anteriormente <, >, ==, !=, <= y >= devuelven verdadero (1) o falso (0) y ayudan a determinar si una vela es alcista o bajista.
Por ejemplo,
- Una vela alcista se identifica cuando se cumple la condición close[0] > open[0], donde [0] se refiere al último índice de la vela.
Por otro lado,
- una vela bajista se indica mediante close[0] < open[0].
Esta comparación básica es la piedra angular del reconocimiento de patrones de velas. Piense en estas comparaciones como simples preguntas sobre el precio: "¿La vela cerró más alto de lo que abrió?" Si es así, está viendo una señal alcista.
Patrones de velas
Según mi investigación, podemos clasificar los patrones de velas en dos tipos principales: patrones de velas individuales y patrones de velas múltiples. Ahora todo lo que hemos discutido hasta ahora comenzará a tomar forma. Para que lo entiendas mejor, vamos a comparar brevemente ambos. He preparado dos tablas con información detallada para resaltar sus diferencias.
Patrón de vela única
Al trabajar con patrones de una sola vela, las operaciones aritméticas son esenciales para medir varios aspectos de una vela, como el tamaño de su cuerpo, la longitud de su mecha y su rango general. Los patrones de vela única, como el Doji, que se produce cuando los precios de apertura y cierre son casi iguales, son importantes porque indican indecisión del mercado o posibles reversiones. Al analizar las diferencias entre la apertura, el máximo, el mínimo y el cierre, puede derivar estos patrones y obtener información sobre cambios importantes del mercado.
Vela Doji
| Nombre de la vela | Descripción lógica | Imagen de referencia |
|---|---|---|
| Doji | Un patrón de vela Doji se identifica cuando los precios de apertura y cierre están muy cerca o son iguales, lo que indica indecisión del mercado. Esto significa abrir[1] ≈ cerrar[1], mientras que el máximo y el mínimo pueden variar significativamente. Un Doji puede aparecer en diferentes formas, como un Doji de patas largas, un Doji de libélula o un Doji de lápida, dependiendo de la ubicación de las mechas.// Check for Doji pattern if( MathAbs(Open[1] - Close[1]) < Point * 2 ) // Open and close are almost equal { Print("Doji pattern detected"); } | ![]() |
Patrones de múltiples velas
Los patrones de múltiples velas requieren que analicemos las relaciones entre velas consecutivas. En MQL5, utilizamos indexación para referirnos a velas pasadas: close[1] representa el precio de cierre de la vela anterior, mientras que close[2] representa la anterior. Un patrón popular de múltiples velas es la envolvente alcista, donde una pequeña vela bajista es seguida por una vela alcista más grande que "envuelve" completamente a la anterior.
Para codificar este patrón, debes verificar que la vela anterior sea bajista (usando close[1] < open[1]), y luego verificar que la vela actual sea alcista (usando close[0] > open[0]) mientras también confirmas que el cuerpo de la vela actual se extiende más allá de los límites de la vela anterior. Las condiciones en su código garantizan que el patrón siga las relaciones de secuencia y tamaño esperadas, lo cual es fundamental para detectar con precisión un patrón envolvente alcista.
| Patrón de velas | Descripción lógica | Imagen de referencia |
|---|---|---|
| Envolvente alcista | Un patrón envolvente alcista se identifica cuando la vela en el índice 2 es bajista (su cierre es más bajo que su apertura, es decir, Close[2] < Open[2]), y la vela en el índice 1 es alcista (su cierre es más alto que su apertura, es decir, Close[1] > Open[1]). Además, la vela en el índice 1 debe envolver el cuerpo de la vela en el índice 2 abriendo por debajo de su cierre (Open[1] < Close[2]) y cerrando por encima de su apertura (Close[1] > Open[2]).// Check for bullish engulfing pattern if( Close[2] < Open[2] && // Candle at index 2 is bearish Close[1] > Open[1] && // Candle at index 1 is bullish Open[1] < Close[2] && // Candle at index 1 opens below candle at index 2 close Close[1] > Open[2] ) // Candle at index 1 closes above candle at index 2 open { Print("Bullish engulfing pattern detected"); } | ![]() |
Creación de una colección de patrones de velas japonesas conocidos y una biblioteca de funciones de patrones de velas japonesas reutilizables
Para simplificar el proceso, he compilado dos tablas con una colección de patrones de velas conocidos y he creado una tabla de referencia completa con una columna de descripción y una columna de imagen de referencia. Esta tabla servirá como un recurso valioso tanto durante el desarrollo como para futuros lectores. Además, se puede ampliar y perfeccionar con el tiempo con nuevos descubrimientos, lo que facilita la creación de una biblioteca de patrones de velas más completa y sofisticada.
Colección de patrones de velas unicas
| Patrón de velas | Descripción lógica | Imagen de referencia |
|---|---|---|
| Hammer (Martillo) | Un patrón de martillo se identifica cuando la vela en el índice 1 tiene un cuerpo pequeño (la diferencia absoluta entre su cierre y apertura es menor que 0,3 veces el ATR, es decir, MathAbs(Close[1] - Open[1]) < 0,3 * ATR), una mecha inferior larga (la distancia desde el mínimo de apertura o cierre hasta el mínimo es al menos el doble del tamaño del cuerpo, es decir, MathMin(Open[1], Close[1]) - Low[1] >= 2 * MathAbs(Close[1] - Open[1])), y una mecha superior pequeña o nula (la distancia desde el máximo de apertura o cierre hasta el máximo es menor o igual a la mitad del tamaño del cuerpo, es decir, High[1] - MathMax(Open[1], Close[1]) <= 0,5 * MathAbs(Close[1] - Open[1]))// Check for Hammer pattern if( MathAbs(Close[1] - Open[1]) < 0.3 * ATR[1] && // Small body // Long lower wick (MathMin(Open[1], Close[1]) - Low[1]) >= 2 * MathAbs(Close[1] - Open[1]) && // Small or no upper wick (High[1] - MathMax(Open[1], Close[1]) <= 0.5 * MathAbs(Close[1] - Open[1])) { Print("Hammer pattern detected"); } | ![]() |
| Shooting Star (Estrella fugaz) | Un patrón de estrella fugaz se identifica cuando la vela en el índice 1 tiene un cuerpo pequeño (la diferencia absoluta entre su cierre y apertura es menor que 0,3 veces el ATR, es decir, MathAbs(Close[1] - Open[1]) < 0,3 * ATR), una mecha superior larga (la distancia desde el punto más alto de apertura o cierre hasta el máximo es al menos el doble del tamaño del cuerpo, es decir, High[1] - MathMax(Open[1], Close[1]) >= 2 * MathAbs(Close[1] - Open[1])), y una mecha inferior pequeña o nula (la distancia desde el punto más bajo de apertura o cierre hasta el mínimo es menor o igual a la mitad del tamaño del cuerpo, es decir, MathMin(Open[1], Close[1]) - Low[1] <= 0,5 * MathAbs(Close[1] - Open[1]))// Check for Shooting Star pattern if( MathAbs(Close[1] - Open[1]) < 0.3 * ATR[1] && // Small body // Long upper wick (High[1] - MathMax(Open[1], Close[1]) >= 2 * MathAbs(Close[1] - Open[1]) && // Small or no lower wick (MathMin(Open[1], Close[1]) - Low[1]) <= 0.5 * MathAbs(Close[1] - Open[1]) ) { Print("Shooting Star pattern detected"); } | |
| Doji estándar | Un patrón Doji estándar se identifica cuando la vela en el índice 1 tiene un cuerpo mínimo, lo que significa que la apertura y el cierre son casi iguales (la diferencia absoluta entre su cierre y apertura es menor a 0,1 veces el ATR, es decir, MathAbs(Close[1] - Open[1]) < 0,1 * ATR)// Check for Standard Doji pattern if( MathAbs(Close[1] - Open[1]) < 0.1 * ATR[1] ) // Open and close are nearly equal { Print("Standard Doji pattern detected"); } | ![]() |
| Doji Libélula | Un patrón doji de libélula se identifica cuando la vela en el índice 1 tiene un cuerpo pequeño (la diferencia absoluta entre su cierre y apertura es menor que 0,1 veces el ATR, es decir, MathAbs(Close[1] - Open[1]) < 0,1 * ATR), una mecha inferior larga (la distancia desde el mínimo de apertura o cierre hasta el mínimo es mayor que 0,5 veces el ATR, es decir, MathMin(Open[1], Close[1]) - Low[1] > 0,5 * ATR), y poca o ninguna mecha superior (la distancia desde el máximo de apertura o cierre hasta el máximo es menor que 0,1 veces el ATR, es decir, High[1] - MathMax(Open[1], Close[1]) < 0,1 * ATR)// Check for Dragonfly Doji pattern if( MathAbs(Close[1] - Open[1]) < 0.1 * ATR[1] && // Small body (MathMin(Open[1], Close[1]) - Low[1]) > 0.5 * ATR[1] && // Long lower wick (High[1] - MathMax(Open[1], Close[1]) < 0.1 * ATR[1] ) // Little to no upper wick { Print("Dragonfly Doji pattern detected"); } | ![]() |
| Doji Lápida | Un patrón doji de lápida se identifica cuando la vela en el índice 1 tiene un cuerpo pequeño (la diferencia absoluta entre su cierre y apertura es menor que 0,1 veces el ATR, es decir, MathAbs(Close[1] - Open[1]) < 0,1 * ATR), una mecha superior larga (la distancia desde el punto más alto de apertura o cierre hasta el máximo es mayor que 0,5 veces el ATR, es decir, High[1] - MathMax(Open[1], Close[1]) > 0,5 * ATR), y poca o ninguna mecha inferior (la distancia desde el punto más bajo de apertura o cierre hasta el mínimo es menor que 0,1 veces el ATR, es decir, MathMin(Open[1], Close[1]) - Low[1] < 0,1 * ATR)// Check for Gravestone Doji pattern if( MathAbs(Close[1] - Open[1]) < 0.1 * ATR[1] && // Small body (High[1] - MathMax(Open[1], Close[1]) > 0.5 * ATR[1] && // Long upper wick (MathMin(Open[1], Close[1]) - Low[1]) < 0.1 * ATR[1] ) // Little to no lower wick { Print("Gravestone Doji pattern detected"); } | ![]() |
| Marubozu alcista | Un patrón marubozu alcista se identifica cuando la vela en el índice 1 es fuertemente alcista (su cierre es más alto que su apertura, es decir, Close[1] > Open[1]) casi sin mechas, lo que significa que la apertura está muy cerca del mínimo (Open[1] - Low[1] < 0,1 * ATR) y el cierre está muy cerca del máximo (High[1] - Close[1] < 0,1 * ATR)// Check for Bullish Marubozu pattern if( Close[1] > Open[1] && // Bullish candle (High[1] - Close[1]) < 0.1 * ATR[1] && // Close is very close to high (Open[1] - Low[1]) < 0.1 * ATR[1] ) // Open is very close to low { Print("Bullish Marubozu pattern detected"); } | ![]() |
| Marubozu bajista | Un patrón marubozu bajista se identifica cuando la vela en el índice 1 es fuertemente bajista (su cierre es más bajo que su apertura, es decir, Close[1] < Open[1]) con casi ninguna mecha, lo que significa que la apertura está muy cerca del máximo (High[1] - Open[1] < 0,1 * ATR) y el cierre está muy cerca del mínimo (Close[1] - Low[1] < 0,1 * ATR)// Check for Bearish Marubozu pattern if( Close[1] < Open[1] && // Bearish candle (High[1] - Open[1]) < 0.1 * ATR[1] && // Open is very close to high (Close[1] - Low[1]) < 0.1 * ATR[1] ) // Close is very close to low { Print("Bearish Marubozu pattern detected"); } | ![]() |
| Spinning Top (Peonza/Trompo) | Un patrón de trompo se identifica cuando la vela en el índice 1 tiene un cuerpo pequeño (la diferencia absoluta entre su cierre y apertura es menor que 0,3 veces el ATR, es decir, MathAbs(Close[1] - Open[1]) < 0,3 * ATR) y mechas superiores e inferiores largas (la distancia desde el más alto de la apertura o cierre hasta el máximo es mayor que 0,5 veces el ATR, es decir, High[1] - MathMax(Open[1], Close[1]) > 0,5 * ATR, y la distancia desde el más bajo de la apertura o cierre hasta el mínimo es mayor que 0,5 veces el ATR, es decir, MathMin(Open[1], Close[1]) - Low[1] > 0,5 * ATR)// Check for Spinning Top pattern if( MathAbs(Close[1] - Open[1]) < 0.3 * ATR[1] && // Small body (High[1] - MathMax(Open[1], Close[1]) > 0.5 * ATR[1] && // Long upper wick (MathMin(Open[1], Close[1]) - Low[1]) > 0.5 * ATR[1] ) // Long lower wick { Print("Spinning Top pattern detected"); } | ![]() |
Colección de patrones de múltiples velas
| Patrón de velas | Descripción lógica | Imagen de referencia |
|---|---|---|
| Morning Star (Estrella de la mañana) | Un patrón de estrella de la mañana se identifica cuando la vela en el índice 3 es bajista (su cierre es más bajo que su apertura, es decir, Close[3] < Open[3]), la vela en el índice 2 tiene un cuerpo pequeño (la diferencia absoluta entre su cierre y apertura es menor que 0,3 veces el ATR, es decir, MathAbs(Close[2] - Open[2]) < 0,3 * ATR), y la vela en el índice 1 es alcista (su cierre es más alto que su apertura, es decir, Close[1] > Open[1]). Además, el cierre de la vela 1 debe estar por encima del punto medio de la vela 3 (Close[1] > (Open[3] + Close[3]) / 2)// Check for Morning Star pattern if( Close[3] < Open[3] && // Candle at index 3 is bearish MathAbs(Close[2] - Open[2]) < 0.3 * ATR[1] && // Candle at index 2 has a small body Close[1] > Open[1] && // Candle at index 1 is bullish Close[1] > (Open[3] + Close[3]) / 2 ) // Candle at index 1 closes above midpoint of candle 3 { Print("Morning Star pattern detected"); } | ![]() |
| Evening Star (Estrella vespertina) | Un patrón de estrella vespertina se identifica cuando la vela en el índice 3 es alcista (su cierre es más alto que su apertura, es decir, Close[3] > Open[3]), la vela en el índice 2 tiene un cuerpo pequeño (la diferencia absoluta entre su cierre y apertura es menor que 0,3 veces el ATR, es decir, MathAbs(Close[2] - Open[2]) < 0,3 * ATR), y la vela en el índice 1 es bajista (su cierre es más bajo que su apertura, es decir, Close[1] < Open[1]). Además, el cierre de la vela 1 debe estar por debajo del punto medio de la vela 3 (Close[1] < (Open[3] + Close[3]) / 2)// Check for Evening Star pattern if( Close[3] > Open[3] && // Candle at index 3 is bullish MathAbs(Close[2] - Open[2]) < 0.3 * ATR[1] && // Candle at index 2 has a small body Close[1] < Open[1] && // Candle at index 1 is bearish Close[1] < (Open[3] + Close[3]) / 2 ) // Candle at index 1 closes below midpoint of candle 3 { Print("Evening Star pattern detected"); } | ![]() |
| Three White Soldiers (Tres soldados blancos) | El patrón de los tres soldados blancos se identifica cuando aparecen tres velas alcistas consecutivas: vela en el índice 3 (Close[3] > Open[3]), vela en el índice 2 (Close[2] > Open[2]) y vela en el índice 1 (Close[1] > Open[1]). El cuerpo de cada vela debe ser más grande que el ATR (por ejemplo, Close[3] - Open[3] > ATR), tener mechas superiores pequeñas (por ejemplo, High[3] - Close[3] < 0,3 * ATR) y cada una se abre dentro del cuerpo de la vela anterior (por ejemplo, Open[2] > Open[3] y Open[2] < Close[3])// Check for Three White Soldiers pattern // Candle 3 is bullish with large body and small upper wick if( Close[3] > Open[3] && (Close[3] - Open[3]) > ATR[1] && (High[3] - Close[3]) < 0.3 * ATR[1] && // Candle 2 is bullish with large body and small upper wick Close[2] > Open[2] && (Close[2] - Open[2]) > ATR[1] && (High[2] - Close[2]) < 0.3 * ATR[1] && // Candle 1 is bullish with large body and small upper wick Close[1] > Open[1] && (Close[1] - Open[1]) > ATR[1] && (High[1] - Close[1]) < 0.3 * ATR[1] && // Candle 2 opens within candle 3's body and closes higher Open[2] > Open[3] && Open[2] < Close[3] && Close[2] > Close[3] && // Candle 1 opens within candle 2's body and closes higher Open[1] > Open[2] && Open[1] < Close[2] && Close[1] > Close[2] ) { Print("Three White Soldiers pattern detected"); } | ![]() |
| Three Black Crows (Tres cuervos negros) | El patrón de los tres cuervos negros se identifica cuando aparecen tres velas bajistas consecutivas: vela en el índice 3 (Close[3] < Open[3]), vela en el índice 2 (Close[2] < Open[2]) y vela en el índice 1 (Close[1] < Open[1]). El cuerpo de cada vela debe ser más grande que el ATR (por ejemplo, Open[3] - Close[3] > ATR), tener mechas inferiores pequeñas (por ejemplo, Open[3] - Low[3] < 0,3 * ATR) y cada una se abre dentro del cuerpo de la vela anterior (por ejemplo, Open[2] < Open[3] && Open[2] > Close[3])// Check for Three Black Crows pattern // Candle 3 is bearish with large body and small lower wick if( Close[3] < Open[3] && (Open[3] - Close[3]) > ATR[1] && (Open[3] - Low[3]) < 0.3 * ATR[1] && // Candle 2 is bearish with large body and small lower wick Close[2] < Open[2] && (Open[2] - Close[2]) > ATR[1] && (Open[2] - Low[2]) < 0.3 * ATR[1] && // Candle 1 is bearish with large body and small lower wick Close[1] < Open[1] && (Open[1] - Close[1]) > ATR[1] && (Open[1] - Low[1]) < 0.3 * ATR[1] && // Candle 2 opens within candle 3's body and closes lower Open[2] < Open[3] && Open[2] > Close[3] && Close[2] < Close[3] && // Candle 1 opens within candle 2's body and closes lower Open[1] < Open[2] && Open[1] > Close[2] && Close[1] < Close[2] ) { Print("Three Black Crows pattern detected"); } | ![]() |
| Harami alcista | Un patrón harami alcista se identifica cuando la vela en el índice 2 es bajista (su cierre es más bajo que su apertura, es decir, Close[2] < Open[2]) con un cuerpo más grande que el ATR (Open[2] - Close[2] > ATR), y la vela en el índice 1 es alcista (su cierre es más alto que su apertura, es decir, Close[1] > Open[1]) con su cuerpo completamente dentro del cuerpo de la vela 2 (Open[1] > Close[2] && Close[1] < Open[2])// Check for Bullish Harami pattern // Candle 2 is bearish with large body if( Close[2] < Open[2] && (Open[2] - Close[2]) > ATR[1] && // Candle 1 is bullish and within candle 2's body Close[1] > Open[1] && Open[1] > Close[2] && Close[1] < Open[2] ) { Print("Bullish Harami pattern detected"); } | ![]() |
| Harami bajista | Un patrón harami bajista se identifica cuando la vela en el índice 2 es alcista (su cierre es más alto que su apertura, es decir, Close[2] > Open[2]) con un cuerpo más grande que el ATR (Close[2] - Open[2] > ATR), y la vela en el índice 1 es bajista (su cierre es más bajo que su apertura, es decir, Close[1] < Open[1]) con su cuerpo completamente dentro del cuerpo de la vela 2 (Open[1] < Close[2] && Close[1] > Open[2])// Check for Bearish Harami pattern // Candle 2 is bullish with large body if( Close[2] > Open[2] && (Close[2] - Open[2]) > ATR[1] && // Candle 1 is bearish and within candle 2's body Close[1] < Open[1] && Open[1] < Close[2] && Close[1] > Open[2] ) { Print("Bearish Harami pattern detected"); } | ![]() |
| Envolvente alcista | Un patrón envolvente alcista se identifica cuando la vela en el índice 2 es bajista (su cierre es más bajo que su apertura, es decir, Close[2] < Open[2]), y la vela en el índice 1 es alcista (su cierre es más alto que su apertura, es decir, Close[1] > Open[1]). Además, la vela en el índice 1 debe envolver el cuerpo de la vela en el índice 2 abriendo por debajo de su cierre (Open[1] < Close[2]) y cerrando por encima de su apertura (Close[1] > Open[2]).// Check for Bullish Engulfing pattern if( Close[2] < Open[2] && // Candle at index 2 is bearish Close[1] > Open[1] && // Candle at index 1 is bullish Open[1] < Close[2] && // Candle at index 1 opens below candle at index 2's close Close[1] > Open[2] ) // Candle at index 1 closes above candle at index 2's open { Print("Bullish Engulfing pattern detected"); } | ![]() |
| Bearish Engulfing (Envolvente bajista) | Un patrón envolvente bajista se identifica cuando la vela en el índice 2 es alcista (su cierre es más alto que su apertura, es decir, Close[2] > Open[2]), y la vela en el índice 1 es bajista (su cierre es más bajo que su apertura, es decir, Close[1] < Open[1]). Además, la vela en el índice 1 debe envolver completamente el cuerpo de la vela en el índice 2 abriendo por encima de su cierre (Open[1] > Close[2]) y cerrando por debajo de su apertura (Close[1] < Open[2]).// Check for Bearish Engulfing pattern if( Close[2] > Open[2] && // Candle at index 2 is bullish Close[1] < Open[1] && // Candle at index 1 is bearish Open[1] > Close[2] && // Candle at index 1 opens above candle at index 2's close Close[1] < Open[2] ) // Candle at index 1 closes below candle at index 2's open { Print("Bearish Engulfing pattern detected"); } | ![]() |
| Three Inside Up (Tres dentro arriba) | El patrón de tres dentro arriba se identifica cuando la vela en el índice 3 es bajista (su cierre es más bajo que su apertura, es decir, Close[3] < Open[3]) con un cuerpo grande (Open[3] - Close[3] > ATR), la vela en el índice 2 es alcista (Close[2] > Open[2]) y está contenida dentro de la vela 3 (Open[2] > Close[3] && Close[2] < Open[3]), y la vela 1 es alcista (Close[1] > Open[1]) cerrando por encima del máximo de la vela 2 (Close[1] > High[2])// Check for Three Inside Up pattern // Candle 3 is bearish with large body if( Close[3] < Open[3] && (Open[3] - Close[3]) > ATR[1] && // Candle 2 is bullish and within candle 3's body Close[2] > Open[2] && Open[2] > Close[3] && Close[2] < Open[3] && // Candle 1 is bullish and closes above candle 2's high Close[1] > Open[1] && Close[1] > High[2] ) { Print("Three Inside Up pattern detected"); } | ![]() |
| Three Inside Down (Tres dentro abajo) | El patrón de tres dentro abajo se identifica cuando la vela en el índice 3 es alcista (su cierre es más alto que su apertura, es decir, Close[3] > Open[3]) con un cuerpo grande (Close[3] - Open[3] > ATR), la vela en el índice 2 es bajista (Close[2] < Open[2]) y está contenida dentro de la vela 3 (Open[2] < Close[3] && Close[2] > Open[3]), y la vela 1 es bajista (Close[1] < Open[1]) cerrando por debajo del mínimo de la vela 2 (Close[1] < Low[2])// Check for Three Inside Down pattern // Candle 3 is bullish with large body if( Close[3] > Open[3] && (Close[3] - Open[3]) > ATR[1] && // Candle 2 is bearish and within candle 3's body Close[2] < Open[2] && Open[2] < Close[3] && Close[2] > Open[3] && // Candle 1 is bearish and closes below candle 2's low Close[1] < Open[1] && Close[1] < Low[2] ) { Print("Three Inside Down pattern detected"); } | ![]() |
| Tweezer Bottom (Pinzas de suelo) | Un patrón de pinzas de suelo se identifica cuando la vela en el índice 2 es bajista (su cierre es más bajo que su apertura, es decir, Close[2] < Open[2]), la vela en el índice 1 es alcista (su cierre es más alto que su apertura, es decir, Close[1] > Open[1]), y los mínimos de ambas velas son casi iguales (la diferencia absoluta entre Low[2] y Low[1] es menor que 0,1 veces el ATR, es decir, MathAbs(Low[2] - Low[1]) < 0,1 * ATR)// Check for Tweezer Bottom pattern if( Close[2] < Open[2] && // Candle at index 2 is bearish Close[1] > Open[1] && // Candle at index 1 is bullish // Lows of both candles are nearly equal MathAbs(Low[2] - Low[1]) < 0.1 * ATR[1] ) { Print("Tweezer Bottom pattern detected"); } | ![]() |
| Tweezer Top (Pinzas de techo) | Un patrón de pinzas de techo se identifica cuando la vela en el índice 2 es alcista (su cierre es más alto que su apertura, es decir, Close[2] > Open[2]), la vela en el índice 1 es bajista (su cierre es más bajo que su apertura, es decir, Close[1] < Open[1]), y los máximos de ambas velas son casi iguales (la diferencia absoluta entre High[2] y High[1] es menor que 0,1 veces el ATR, es decir, MathAbs(High[2] - High[1]) < 0,1 * ATR)// Check for Tweezer Top pattern if( Close[2] > Open[2] && // Candle at index 2 is bullish Close[1] < Open[1] && // Candle at index 1 is bearish // Highs of both candles are nearly equal MathAbs(High[2] - High[1]) < 0.1 * ATR[1] ) { Print("Tweezer Top pattern detected"); } | ![]() |
| Bullish Kicker (Kicker alcista) | Un patrón Kicker alcista se identifica cuando la vela en el índice 2 es bajista (su cierre es más bajo que su apertura, es decir, Close[2] < Open[2]), y la vela en el índice 1 es alcista (su cierre es más alto que su apertura, es decir, Close[1] > Open[1]) con su apertura por encima de la apertura de la vela 2 (Open[1] > Open[2])// Check for Bullish Kicker pattern if( Close[2] < Open[2] && // Candle at index 2 is bearish // Candle at index 1 is bullish Close[1] > Open[1] && // Candle at index 1 opens above candle at index 2's open Open[1] > Open[2] ) { Print("Bullish Kicker pattern detected"); } | ![]() |
| Bearish Kicker (Kicker bajista) | Un patrón de Kicker bajista se identifica cuando la vela en el índice 2 es alcista (su cierre es más alto que su apertura, es decir, Close[2] > Open[2]), y la vela en el índice 1 es bajista (su cierre es más bajo que su apertura, es decir, Close[1] < Open[1]) con su apertura por debajo de la apertura de la vela 2 (Open[1] < Open[2])// Check for Bearish Kicker pattern // Candle at index 2 is bullish if( Close[2] > Open[2] && // Candle at index 1 is bearish Close[1] < Open[1] && // Candle at index 1 opens below candle at index 2's open Open[1] < Open[2] { Print("Bearish Kicker pattern detected"); } | ![]() |
Estas tablas podrían continuar indefinidamente, ya que hay muchos más patrones que no he incluido. Para mantener la discusión concisa, ahora me centraré en la implementación de estas estrategias dentro de un programa único y significativo. El objetivo final es construir una biblioteca completa de patrones de velas.
Realicé una investigación y encontré un trabajo notable en MQL5 CodeBase desarrollado por algunos de los pioneros del trading algorítmico hace más de una década. Puedes explorar su trabajo para obtener un enfoque más detallado. Sin embargo, en esta discusión, nuestro objetivo es mantener las cosas lo más simples posible para los principiantes. Con esto en mente, ahora avanzaremos con el desarrollo de nuestra propia biblioteca de patrones de velas.
Creación de un archivo de encabezado de patrón de velas reutilizable
En este punto, demostraré cómo crear una biblioteca de funciones que incluya una colección de patrones de velas. Lo llamamos biblioteca porque reúne múltiples funciones de detección de patrones reutilizables. Una vez desarrollados, estos patrones se pueden integrar fácilmente en otros proyectos simplemente incluyendo la biblioteca y llamando a las funciones según sea necesario.
El término adecuado para este tipo de archivo es archivo de encabezado, y me entusiasma nombrarlo. infinity_candlestick_pattern.mqh, lo que refleja su capacidad de expansión, ya que se pueden agregar más patrones con el tiempo. Lo he estructurado como una plantilla, que más adelante demostraré en un indicador para mostrar su uso práctico.
En los archivos adjuntos, compartiré una versión más completa del archivo de encabezado, que contiene funciones para los patrones que enumeramos anteriormente en la tabla de referencia. Puede ampliar aún más esta biblioteca siguiendo las pautas comentadas dentro del fragmento de código.
El archivo incluye dos funciones principales, IsHammer y IsShootingStar, que analizan conjuntos de datos de precios junto con un rango verdadero promedio (Average True Range, ATR) correspondiente para determinar si una vela en particular cumple las condiciones para estos patrones. Cada función verifica que el índice proporcionado sea válido, calcula el tamaño del cuerpo de la vela y luego evalúa las longitudes de las mechas en relación con el tamaño del cuerpo y los valores de ATR. Este enfoque cuidadoso cuantifica los patrones comerciales visuales utilizando criterios matemáticos precisos, lo que permite un reconocimiento de patrones sólido que se ajusta a la volatilidad del mercado. Además, el uso del parámetro patternATR (pasado por referencia) ayuda a prevenir posibles conflictos y advertencias cuando el valor ATR se utiliza más adelante en el indicador de ejemplo, lo que garantiza la coherencia en el valor pasado.
Para integrar estas funciones en otros proyectos, simplemente puede incluir este archivo de encabezado en su código fuente usando una directiva #include. Una vez incluidos, pueden llamar a la función IsHammer o IsShootingStar pasando las matrices apropiadas y el índice de interés.
//+------------------------------------------------------------------+ //| infinity_candlestick_pattern.mqh (Template) | //| Copyright 2025, Metaquotes Ltd | //| https://www.mql5.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Metaquotes Ltd" #property link "https://www.mql5.com/" #ifndef INFINITY_CANDLESTICK_PATTERNS_MQH #define INFINITY_CANDLESTICK_PATTERNS_MQH //+------------------------------------------------------------------+ //| Single-Candlestick Pattern Functions | //+------------------------------------------------------------------+ // Hammer Pattern bool IsHammer(double &open[], double &high[], double &low[], double &close[], double &patternATR[], int index) { if (index < 0) return false; // Ensure the index is valid // Calculate the body size (absolute difference between close and open) double body = MathAbs(close[index] - open[index]); // Check if the body is small relative to ATR (less than 30% of ATR) if (body >= 0.3 * patternATR[index]) return false; // Calculate wick lengths double upperWick = high[index] - MathMax(open[index], close[index]); double lowerWick = MathMin(open[index], close[index]) - low[index]; // Hammer conditions: long lower wick (2x body), small upper wick (≤0.5x body) if (lowerWick >= 2 * body && upperWick <= 0.5 * body) return true; return false; } // Shooting Star Pattern bool IsShootingStar(double &open[], double &high[], double &low[], double &close[], double &patternATR[], int index) { if (index < 0) return false; // Ensure the index is valid // Calculate the body size (absolute difference between close and open) double body = MathAbs(close[index] - open[index]); // Check if the body is small relative to ATR (less than 30% of ATR) if (body >= 0.3 * patternATR[index]) return false; // Calculate wick lengths double upperWick = high[index] - MathMax(open[index], close[index]); double lowerWick = MathMin(open[index], close[index]) - low[index]; // Shooting Star conditions: long upper wick (2x body), small lower wick (≤0.5x body) if (upperWick >= 2 * body && lowerWick <= 0.5 * body) return true; return false; } //+------------------------------------------------------------------+ //| How to Expand the Library | //+------------------------------------------------------------------+ // To add more patterns: // 1. Create a new function, e.g., IsDoji, IsEngulfing, etc. // 2. Use the same inputs: open[], high[], low[], close[], patternATR[], index // 3. Define the pattern’s conditions (e.g., for Doji, check if open ≈ close) // 4. Return true if the pattern matches, false otherwise // 5. For multi-candle patterns, adjust the index check (e.g., index < 1 for 2 candles) // 6. Use patternATR to adapt to volatility (optional) // 7. Add comments to explain your logic #endif //+------------------------------------------------------------------+
Ahora, pasemos al desarrollo de un indicador que demuestre cómo aplicar el archivo de encabezado que acabamos de crear. He decidido llamarlo Hammer&ShootingStar, ya que utilizará nuestra biblioteca para detectar y visualizar estos dos patrones de velas en el gráfico. Esto proporcionará un ejemplo práctico de cómo nuestras funciones reutilizables pueden implementarse en escenarios comerciales reales. Al incluir la biblioteca al inicio del indicador, obtenemos acceso inmediato a las funciones de reconocimiento de patrones de velas, es decir, IsHammer e IsShootingStar en este contexto. Este diseño modular permite que el indicador se centre en la recopilación y el procesamiento de datos del mercado mientras delega la lógica de evaluación de patrones a la biblioteca, lo que garantiza la consistencia y simplifica el mantenimiento.
En la fase de inicialización (OnInit), el indicador configura sus buffers y propiedades gráficas, incluida la definición de dos gráficos de flechas que representan visualmente los patrones detectados. También crea un controlador ATR, que se utiliza para obtener datos de volatilidad del mercado que requieren las funciones de la biblioteca. Durante la fase de cálculo (OnCalculate), el indicador recupera datos de precios y valores ATR, luego itera a través de la serie de precios. En cada iteración, llama a las funciones de la biblioteca para verificar si una vela particular cumple los criterios de un martillo (señal de compra) o una estrella fugaz (señal de venta). Dependiendo del resultado, el buffer correspondiente se rellena con el nivel de precio en el que se debe dibujar una flecha.
Además, el diseño de este indicador favorece una futura expansión. Puede agregar fácilmente más buffers si se incorporan funciones de reconocimiento de patrones adicionales a la biblioteca. Este enfoque flexible fomenta la ampliación de la biblioteca de patrones manteniendo al mismo tiempo una separación clara entre la lógica del indicador central y los algoritmos de detección de patrones. Si desea adquirir más experiencia en codificación, puede crear más buffers utilizando funciones en la biblioteca adjunta.
//+------------------------------------------------------------------+ //| Hammer&ShootingStar.mq5 | //| Copyright 2025, Metaquotes Ltd | //| https://www.mql5.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Metaquotes Ltd" #property link "https://www.mql5.com/" #property version "1.00" #property indicator_chart_window //--- Include the library #include <infinity_candlestick pattern.mqh> //--- Indicator settings #property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_ARROW #property indicator_color1 0x0000FF #property indicator_label1 "Sell " #property indicator_type2 DRAW_ARROW #property indicator_color2 0xFF0000 #property indicator_label2 "Buy " //--- Indicator buffers and variables double Buffer1[]; double Buffer2[]; double Open[]; double High[]; double Low[]; double Close[]; double atr[]; int atrHandle; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, Buffer1); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(0, PLOT_ARROW, 242); SetIndexBuffer(1, Buffer2); PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(1, PLOT_ARROW, 241); // Create ATR handle atrHandle = iATR(_Symbol, _Period, 14); if (atrHandle == INVALID_HANDLE) { Print("Failed to create ATR handle"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime& time[], const double& open[], const double& high[], const double& low[], const double& close[], const long& tick_volume[], const long& volume[], const int& spread[]) { // Copy price data and ATR if (CopyOpen(Symbol(), PERIOD_CURRENT, 0, rates_total, Open) <= 0) return(rates_total); ArraySetAsSeries(Open, true); if (CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total); ArraySetAsSeries(High, true); if (CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total); ArraySetAsSeries(Low, true); if (CopyClose(Symbol(), PERIOD_CURRENT, 0, rates_total, Close) <= 0) return(rates_total); ArraySetAsSeries(Close, true); if (CopyBuffer(atrHandle, 0, 0, rates_total, atr) <= 0) return(rates_total); ArraySetAsSeries(atr, true); ArraySetAsSeries(Buffer1, true); ArraySetAsSeries(Buffer2, true); // Main loop for (int i = rates_total-2; i >= 0; i--) { // Sell Supply (Shooting Star) if (IsShootingStar(Open, High, Low, Close, atr, i)) Buffer1[i] = High[i]; // Arrow at high else Buffer1[i] = EMPTY_VALUE; // Buy Supply (Hammer) if (IsHammer(Open, High, Low, Close, atr, i)) Buffer2[i] = Low[i]; // Arrow at low else Buffer2[i] = EMPTY_VALUE; } return(rates_total); }
Pruebas
Con todo integrado exitosamente, pude ejecutar Hammer&ShootingStar en MetaTrader 5 y observé excelentes resultados. El indicador identificó y resaltó eficazmente los patrones de velas, demostrando la precisión y practicidad de nuestra biblioteca en condiciones reales de mercado.

Volatility 75 (1s) Index.0,5 : Prueba Hammer&ShootingStar.
Conclusión
Esta discusión ha sido extensa, pero servirá como uno de los temas más valiosos y frecuentemente revisados como referencia y aprendizaje. Con el algoritmo implementado, solucionamos el problema de la búsqueda manual de patrones. El proceso ahora es totalmente automático y, sin indicadores visuales en el gráfico, gestionar tus estrategias nunca ha sido tan fácil. El algoritmo garantiza la precisión al manejar todos los cálculos, incluidos los valores ATR, lo que hace que el proceso sea eficiente y preciso.
Hemos cubierto una amplia gama de conceptos y técnicas que son útiles para programar patrones de velas y construir indicadores de múltiples búferes. Si bien esta discusión se centró principalmente en los patrones de velas, presentamos un enfoque algorítmico para analizarlos y utilizarlos, lo que lo hace especialmente útil para principiantes que buscan automatizar sus estrategias comerciales. Tenga en cuenta que las señales generadas por patrones de velas pueden requerir filtros adicionales para convertirse en señales comerciales confiables. La secciónCodeBase es un recurso excelente si buscas mejorar las señales generadas por patrones de velas o agregar funciones más avanzadas.
Me encantaría verte compartir los resultados del código adjunto en la sección de comentarios. Si el tiempo lo permite, volveré a tratar este tema para aprovechar lo que hemos logrado hasta ahora y explorar nuevos avances.| Nombre del archivo | Descripción |
|---|---|
| infinity_candlestick_pattern.mqh | Un archivo de encabezado que contiene una colección de funciones booleanas para los patrones de velas más populares, listos para ser llamados en otros proyectos. |
| Hammer&ShootingStar.mq5, | Un indicador de ejemplo que integra la biblioteca infinity_candlestick_pattern.mqh. |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/17525
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
Criterios de tendencia. Final
Particularidades del trabajo con números del tipo double en MQL4
Descifrando las estrategias de trading intradía de ruptura del rango de apertura
- 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






















