English Русский 中文 Deutsch 日本語
preview
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 31): Motor de reconocimiento de velas japonesas en Python (I) — Detección manual

Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 31): Motor de reconocimiento de velas japonesas en Python (I) — Detección manual

MetaTrader 5Integración |
26 0
Christian Benjamin
Christian Benjamin

Contenido



Introducción

Los gráficos de velas japonesas son una herramienta fundamental que utilizan los analistas financieros y los operadores para visualizar e interpretar la evolución de los precios a lo largo del tiempo. Estos gráficos, que tienen su origen en los comerciantes de arroz japoneses de hace siglos, se han convertido en un componente fundamental del análisis técnico en diversos mercados financieros, entre ellos el bursátil, el de divisas y el de futuros. 

Patrones

Una vela japonesa ofrece información esencial sobre el estado de ánimo del mercado, ya que representa datos clave como los precios de apertura, cierre, máximo y mínimo dentro de un intervalo de tiempo concreto. La estructura única de cada vela japonesa ofrece información sobre la psicología del mercado y puede servir como una posible señal de trading. 

En este artículo, analizamos el desarrollo de un sistema integral de reconocimiento de velas japonesas que aprovecha las capacidades de MQL5 y Python. Comenzaremos por implementar métodos de detección manual, creando un script que extraiga métricas de MQL5 y asigne nombres a los patrones según criterios predefinidos. Aunque este reconocimiento puede llevarse a cabo íntegramente dentro de MQL5, optamos por una división de funciones entre MQL5 y Python para aprovechar sus respectivas ventajas, lo que garantiza una mayor flexibilidad y solidez. 

En un artículo posterior, ampliaremos este sistema incorporando bibliotecas de Python que ofrecen funciones avanzadas para el reconocimiento de patrones de velas japonesas, lo que mejorará la precisión y la variedad de la detección de patrones. Acompáñanos mientras nos adentramos en las complejidades de la identificación de patrones de velas japonesas y analizamos cómo este enfoque integrado mejora el análisis de trading. A continuación te ofrecemos un resumen de los pasos que seguiremos:

  • Analizar cada patrón: Examinaremos cada patrón de velas de forma individual y veremos cómo se implementa su reconocimiento en Python.
  • Explorar la interacción entre MQL5 y Python: Repasaremos cómo interactúa el asesor experto de MQL5 con el servidor de Python, incluyendo el proceso de intercambio de datos y el flujo de comunicación.
  • Evaluación de los resultados y conclusiones: Por último, evaluaremos los resultados del sistema, analizaremos su eficacia y extraeremos conclusiones sobre su rendimiento y las posibles mejoras.


Análisis de patrones de velas japonesas

La parte más ancha de una vela se conoce como «cuerpo real», que representa la diferencia entre los precios de apertura y de cierre dentro de un periodo concreto. Un cuerpo relleno o de color suele indicar que el precio de cierre fue inferior al de apertura, lo que señala una tendencia bajista. Por el contrario, un cuerpo sin relleno o de otro color sugiere que el precio de cierre fue superior al de apertura, lo que indica una tendencia alcista.

Las sombras o mechas se extienden desde el cuerpo real e indican los precios máximo y mínimo alcanzados durante la sesión bursátil. La longitud y la posición de estas sombras ofrecen información sobre la volatilidad del mercado y la confianza de los inversores, revelando cómo fluctuaron los precios con respecto a los niveles de apertura y cierre.

Los patrones de velas japonesas plasman la psicología colectiva de los participantes en el mercado, reflejando sus reacciones emocionales y sus expectativas. Los analistas técnicos utilizan estas señales visuales para identificar posibles puntos de entrada y salida. El origen de los gráficos de velas japonesas se remonta al Japón del siglo XVIII, donde los comerciantes de arroz utilizaban esta técnica para hacer un seguimiento de los precios del arroz. Hoy en día, sigue siendo una herramienta versátil para analizar activos líquidos como acciones, pares de divisas y futuros.

Velas alcistas y bajistas

  • Velas alcistas:

Una vela se considera alcista cuando el precio de cierre supera al de apertura. A menudo se representa como una vela blanca o verde, lo que indica un impulso alcista. Estas velas indican que los compradores tienen el control durante ese periodo. La importancia de las velas alcistas largas aumenta si aparecen cerca de niveles de soporte clave, lo que indica un fuerte interés comprador.

  • Velas bajistas:

Por el contrario, una vela bajista se produce cuando el precio de cierre es inferior al precio de apertura. Normalmente se representan como velas negras o rojas, lo que indica presión vendedora y un movimiento bajista de los precios. Las velas bajistas largas suelen indicar una intensa actividad vendedora y una posible continuación de la tendencia bajista.

  • Convenciones de color

Aunque muchas plataformas de negociación suelen representar las velas alcistas en blanco o verde y las bajistas en negro o rojo, la elección del color es flexible. Lo fundamental es comprender la relación entre los precios de apertura y de cierre, más que ceñirse estrictamente a las combinaciones de colores. Para interpretar con precisión el estado de ánimo del mercado, siempre hay que centrarse en la relación entre los precios de apertura y de cierre.

Dada la gran variedad de patrones de velas japonesas, nuestro sistema se centra en un conjunto selecto de formaciones clave. A continuación, analizaremos el aspecto visual de cada patrón y explicaremos cómo identificarlos utilizando Python:

Martillo (Hammer)

La vela «Hammer» se forma cuando los precios de apertura, máximo y cierre están muy próximos entre sí, lo que da lugar a un cuerpo real pequeño. Su característica más destacada es una sombra inferior larga y marcada, lo que indica que los compradores intentaron hacer bajar el precio, pero finalmente se vieron rechazados. Esto sugiere un posible cambio de tendencia al alza, lo que refleja un sentimiento alcista subyacente. A continuación se muestra un fragmento de código para identificar el patrón «Hammer» en el script de Python.

# inside detect_patterns(df: pd.DataFrame)
for i, _ in enumerate(df.index):
    o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
    body = abs(c - o)
    lower = min(o,c) - l
    upper = h - max(o,c)
    
    if lower >= 2*body and upper <= body:
        pats[i] = "hammer"
        continue

  • El cuerpo es el cuerpo real de la vela (abs(cierre - apertura)).
  • La mecha inferior debe tener, como mínimo, el doble del tamaño del cuerpo.
  • La mecha superior debe ser pequeña (no más grande que el cuerpo).
  • Si se cumple esta condición, se le asigna la etiqueta «hammer» en la matriz pats[].

Estrella Fugaz (Shooting Star)

El patrón de Estrella Fugaz aparece cuando los precios de apertura, mínimo y cierre están todos cerca del mismo nivel. Esto da lugar a una vela con un cuerpo real muy pequeño y una sombra superior muy marcada. A menudo considerada la contrapartida bajista del martillo, la estrella fugaz indica un posible cambio de tendencia o una vacilación en el impulso alcista. Los expertos en análisis técnico suelen recomendar que la sombra superior sea, como mínimo, el doble de larga que el cuerpo para confirmar la relevancia del patrón.

# inside detect_patterns(df: pd.DataFrame)
for i, _ in enumerate(df.index):
    o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
    body = abs(c - o)
    lower = min(o,c) - l
    upper = h - max(o,c)
    
    if upper >= 2*body and lower <= body:
        pats[i] = "shootingstar"
        continue

  • El cuerpo es la diferencia entre apertura y cierre.
  • La mecha superior debe medir al menos el doble que el cuerpo. La mecha inferior debe ser pequeña (igual o menor que el cuerpo).
  • Cuando se cumplen estas condiciones, el patrón se marca como «shootingstar».

Envolvente (alcista y bajista)

 Se produce un patrón envolvente alcista cuando una vela pequeña roja (bajista) es seguida por una vela más grande verde (alcista) que "envuelve" por completo el cuerpo de la vela anterior. Este patrón sugiere una posible reversión de una tendencia bajista a una tendencia alcista, ya que la presión compradora ha superado la presión vendedora. 

# Bullish Engulfing: small red followed by large green that engulfs it
if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c
    if (prev_c < prev_o and curr_c > curr_o and  # red candle then green
        curr_o < prev_c and curr_c > prev_o):    # body engulfs previous
        pats[i] = "bullishengulfing"
        continue

Un patrón envolvente bajista es lo opuesto. Aparece cuando una vela pequeña verde (alcista) es seguida por una vela más grande roja (bajista) que envuelve por completo el cuerpo de la vela anterior. Este patrón indica un posible cambio de tendencia, pasando de una tendencia alcista a una bajista, lo que refleja una mayor presión vendedora.

# Bearish Engulfing: small green followed by large red that engulfs it
if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c
    if (prev_c > prev_o and curr_c < curr_o and  # green candle then red
        curr_o > prev_c and curr_c < prev_o):    # body engulfs previous
        pats[i] = "bearishengulfing"
        continue

Doji

Un Doji es una vela japonesa que se forma cuando los precios de apertura y cierre son prácticamente iguales, lo que da como resultado un cuerpo real muy pequeño o inexistente. Este patrón denota indecisión en el mercado, ya que ni compradores ni vendedores han logrado tomar el control durante la sesión de negociación.

# Doji: very small or no real body
if abs(c - o) <= (h - l) * 0.1:
    pats[i] = "doji"
    continue

  • abs(c - o): tamaño real del cuerpo (diferencia entre el cierre y la apertura).
  • (h - l): rango total de la vela (máximo menos mínimo). Si el cuerpo es igual o inferior al 10 % del rango de la vela, se considera un Doji.

Harami (alcista y bajista)

El patrón Harami, derivado de la palabra japonesa que significa "embarazada", es una formación muy conocida en el análisis técnico que señala posibles cambios de tendencia o continuaciones. Consta de dos velas japonesas: el primero, el más grande, suele denominarse vela "madre", seguido de una vela "bebé" más pequeña que queda contenida dentro del rango de la primera. Para que el patrón se considere válido, la segunda vela debe cerrar dentro del cuerpo de la vela anterior, lo que indica una posible pausa o reversión en el impulso del mercado.

El patrón Harami puede indicar un cambio de tendencia bajista cuando aparece después de una tendencia alcista, lo que sugiere que la presión compradora está disminuyendo y que podría producirse un descenso. Por el contrario, cuando se produce después de una tendencia bajista, puede actuar como un indicador alcista, sugiriendo una posible corrección al alza o un cambio de tendencia.

if i >= 1:
    prev_o, prev_c = df.iloc[i-1][["OPEN", "CLOSE"]]
    curr_o, curr_c = o, c

    # Previous candle: large body (engulfing candle)
    prev_body = abs(prev_c - prev_o)
    curr_body = abs(curr_c - curr_o)

    if prev_body > 0 and curr_body > 0:
        # Bullish Harami
        if prev_o > prev_c and curr_o < curr_c:  # bearish → bullish
            if curr_o > prev_c and curr_c < prev_o:
                pats[i] = "bullishharami"
                continue

        # Bearish Harami
        if prev_o < prev_c and curr_o > curr_c:  # bullish → bearish
            if curr_o < prev_c and curr_c > prev_o:
                pats[i] = "bearishharami"
                continue

Estrella de la Mañana (Morning Star)

La Estrella de la Mañana es un patrón de reversión alcista prominente que suele aparecer después de una tendencia bajista, lo que indica un posible cambio en el sentimiento del mercado, de bajista a alcista. Consta de tres velas japonesas: la primera es una vela bajista grande, que indica una fuerte presión de venta; la segunda es una vela de cuerpo pequeño, ya sea alcista o bajista, que se separa de la primera, lo que representa indecisión o una pausa en el impulso; y la tercera es una vela alcista grande que cierra dentro del cuerpo de la primera vela, lo que confirma un cambio hacia un impulso alcista.

Este patrón sugiere que los vendedores están perdiendo el control y los compradores están ganando fuerza, lo que a menudo conduce a un movimiento alcista sostenido una vez confirmado. La Estrella de la Mañana es ampliamente utilizada por los operadores para identificar posibles puntos de entrada para posiciones largas, especialmente cuando aparece después de una caída prolongada.

if i >= 2:
    o1, c1 = df.iloc[i-2][["OPEN", "CLOSE"]]  # First candle
    o2, c2 = df.iloc[i-1][["OPEN", "CLOSE"]]  # Second (small) candle
    o3, c3 = df.iloc[i][["OPEN", "CLOSE"]]    # Third candle

    # Candle directions
    is_bearish1 = c1 < o1
    is_small2 = abs(c2 - o2) < abs(c1 - o1) * 0.5
    is_bullish3 = c3 > o3

    # Morning Star Logic
    if is_bearish1 and is_small2 and c3 > ((o1 + c1) / 2) and c3 > o3:
        if min(o2, c2) < c1 and max(o2, c2) > c1:  # small gap
            pats[i] = "morningstar"
            continue

  • Vela 1: Una vela bajista larga (cuerpo descendente).
  • Vela 2: Una vela de cuerpo pequeño (puede ser alcista o bajista).
  • Vela 3: Una vela alcista fuerte que cierra por encima del punto medio de la Vela 1.

Se trata de un patrón de reversión de tres velas, que suele indicar el final de una tendencia bajista.

Estrella del Anochecer (Evening Star)

La Estrella del Anochecer es un patrón de reversión bajista notable que generalmente aparece después de una tendencia alcista, lo que indica un posible cambio de un sentimiento alcista a uno bajista. Consta de tres velas japonesas: la primera es una vela alcista grande, que refleja una fuerte presión compradora; la segunda es una vela de cuerpo pequeño, ya sea alcista o bajista, que se separa de la primera, lo que indica indecisión o vacilación del mercado; y la tercera es una vela bajista grande que cierra dentro del cuerpo de la primera, confirmando el cambio de tendencia.

Este patrón indica que los compradores están perdiendo impulso y los vendedores están ganando control, lo que a menudo conduce a una tendencia a la baja o a una corrección. Los operadores suelen utilizar la Estrella del Anochecer como señal para considerar posiciones cortas o para cerrar posiciones largas, especialmente cuando aparece después de una subida prolongada.

if i >= 2:
    o1, c1 = df.iloc[i-2][["OPEN", "CLOSE"]]  # First candle
    o2, c2 = df.iloc[i-1][["OPEN", "CLOSE"]]  # Second (small) candle
    o3, c3 = df.iloc[i][["OPEN", "CLOSE"]]    # Third candle

    is_bullish1 = c1 > o1
    is_small2 = abs(c2 - o2) < abs(c1 - o1) * 0.5
    is_bearish3 = c3 < o3

    if is_bullish1 and is_small2 and c3 < ((o1 + c1) / 2) and c3 < o3:
        if max(o2, c2) > c1 and min(o2, c2) < c1:  # small gap possible
            pats[i] = "eveningstar"
            continue

  • Vela 1: Cuerpo alcista largo.
  • Vela 2: Cuerpo real pequeño (indecisión).
  • Vela 3: Fuerte vela bajista que cierra muy por debajo del punto medio de la Vela 1.

Este patrón de tres velas indica un posible cambio de tendencia, de alcista a bajista.


Interacción entre MQL5 y Python

En nuestra configuración, la lógica principal del patrón de velas japonesas reside en un microservicio de Python, mientras que el EA de MQL5 se centra en la recopilación de datos, la anotación de gráficos y las alertas. Cada vez que se cierra una nueva barra, el EA toma las 31 barras más recientes de datos OHLC, las envía como JSON a un servidor Flask local y luego muestra en el gráfico los patrones detectados por el servidor, todo prácticamente en tiempo real. Así es como funciona paso a paso:
  • MQL5 EA: Recopilación de datos en MQL5
En cada nueva barra (OnTick), el EA extrae las marcas de tiempo, así como los precios de apertura, máximo, mínimo y cierre de las últimas 31 barras, y los guarda en matrices.
void OnTick()
{
   static datetime lastBar = 0;
   datetime bar = iTime(_Symbol, InpTF, 0);
   if(bar == lastBar) return;
   lastBar = bar;

   double o[ BARS ], h[ BARS ], l[ BARS ], c[ BARS ];
   long   t[ BARS ];
   for(int i=0; i<BARS; i++)
   {
      o[i] = iOpen(_Symbol, InpTF, i+1);
      h[i] = iHigh(_Symbol, InpTF, i+1);
      l[i] = iLow (_Symbol, InpTF, i+1);
      c[i] = iClose(_Symbol, InpTF, i+1);
      t[i] = (long)iTime(_Symbol, InpTF, i+1);
   }
   // …then build JSON…
}
  • MQL5 EA: Construcción del payload JSON
Mediante StringFormat, el EA combina símbolos, intervalos de tiempo, marcas de tiempo y matrices OHLC en una cadena JSON de una sola línea, lista para su transmisión.
string json = StringFormat(
  "{\"symbol\":\"%s\",\"timeframe\":%d,"
  "\"time\":[%s],\"open\":[%s],\"high\":[%s],"
  "\"low\":[%s],\"close\":[%s]}",
  _Symbol, InpTF,
  CSVInt(t), CSV(o), CSV(h), CSV(l), CSV(c)
);
  • MQL5 EA: Envío mediante HTTP POST
El EA envía una solicitud WebRequest(«POST», …) a http://127.0.0.1:5000/patterns. Si la solicitud falla, registra el error; de lo contrario, captura la respuesta JSON del servidor Python.
char body[];    StringToCharArray(json, body);
char reply[];   string hdr="Content-Type: application/json\r\n", respHdr;
int code = WebRequest("POST", InpURL, hdr, InpTimeout, body, reply, respHdr);
if(code == -1)
  Print("[CSLAB] WebRequest failed: ", GetLastError());
else
  string resp = CharArrayToString(reply, 0, -1, CP_UTF8);
  • Python: Procesamiento en servidor con Flask
El servicio de Python elimina cualquier contenido sobrante al final del mensaje, decodifica el JSON limpio en un diccionario y reconstruye un DataFrame de pandas utilizando como claves las marcas de tiempo proporcionadas.
@app.route("/patterns", methods=["POST"])
def patterns():
    raw = request.get_data(as_text=True)
    idx = raw.rfind("}")
    clean = raw[:idx+1] if idx != -1 else raw
    payload = json.loads(clean)   # may raise JSONDecodeError
    # …build DataFrame…

  • Python: Construcción del DataFrame

La función build_dataframe es la que convierte las matrices JSON sin procesar de marcas de tiempo, precios de apertura, máximos, mínimos y precios de cierre en un DataFrame indexado por tiempo con el que nuestro detector de patrones puede trabajar fácilmente:

def build_dataframe(payload):
    times = [ datetime.fromtimestamp(int(t), timezone.utc)
              for t in payload["time"] ]
    df = pd.DataFrame({
      "OPEN":  payload["open"],
      "HIGH":  payload["high"],
      "LOW":   payload["low"],
      "CLOSE": payload["close"]
    }, index=times)
    df.index.name = "datetime"
    return df

  • Python: Detección manual de patrones

Nuestra rutina personalizada detect_patterns(df) analiza cada fila en busca de señales de Doji, Martillo, Estrella Fugaz, Envolvente, Harami, Estrella de la Mañana y Estrella del Anochecer, sin necesidad de bibliotecas externas de análisis técnico.

def detect_patterns(df):
    pats = ["None"]*len(df)
    for i in range(len(df)):
        o,h,l,c = df.iloc[i][["OPEN","HIGH","LOW","CLOSE"]]
        body = abs(c-o); rng = max(h-l,1e-6)
        lower = min(o,c)-l; upper = h-max(o,c)
        # doji
        if body/rng <= 0.1:
            pats[i] = "doji"; continue
        # hammer
        if lower>=2*body and upper<=body:
            pats[i] = "hammer"; continue
        # shooting star
        if upper>=2*body and lower<=body:
            pats[i] = "shootingstar"; continue
        # bullish engulfing
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc<po and c>o and o<=pc and c>=po:
                pats[i] = "bullishengulfing"; continue
        # bearish engulfing
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc>po and c<o and o>=pc and c<=po:
                pats[i] = "bearishengulfing"; continue
        # harami
        if i>0:
            po,pc = df.iloc[i-1][["OPEN","CLOSE"]]
            if pc<po and o<c and o>pc and c<po:
                pats[i] = "bullishharami"; continue
            if pc>po and o>c and o<pc and c>po:
                pats[i] = "bearishharami"; continue
        # morning star
        if i>1:
            o1,c1 = df.iloc[i-2][["OPEN","CLOSE"]]
            o2,c2 = df.iloc[i-1][["OPEN","CLOSE"]]
            if c1<o1 and abs(c2-o2)<(df.iloc[i-1]["HIGH"]-df.iloc[i-1]["LOW"])*0.3 \
               and c>o2 and c>(o1+c1)/2:
                pats[i] = "morningstar"; continue
        # evening star
        if i>1:
            o1,c1 = df.iloc[i-2][["OPEN","CLOSE"]]
            o2,c2 = df.iloc[i-1][["OPEN","CLOSE"]]
            if c1>o1 and abs(c2-o2)<(df.iloc[i-1]["HIGH"]-df.iloc[i-1]["LOW"])*0.3 \
               and c<o2 and c<(o1+c1)/2:
                pats[i] = "eveningstar"; continue
    return pats
  • Python: Generación de la respuesta

El servidor contabiliza todos los patrones que no sean "None" y devuelve una estructura JSON concisa:

pats = detect_patterns(df)
counts = Counter(pats)
log_lines = [f"{k}={v}" for k,v in counts.items() if k!="None"]
resp = {"patterns": pats, "log": log_lines, "ms": round((datetime.now(timezone.utc)-start).total_seconds()*1000,2)}
return make_response(json.dumps(resp), 200, {"Content-Type":"application/json"})
  • MQL5: El EA procesa la respuesta y actúa
De vuelta en MQL5, extraemos el array «patterns», nos aseguramos de que contenga 31 entradas y registramos cualquier mensaje de «log». A continuación, para cada patrón real, dibujamos una etiqueta de texto encima de la barra correspondiente y activamos un Alert().
// extract patterns array
string patTxt; ExtractArray(resp, "patterns", patTxt);
string patt[]; ParseArray(patTxt, patt);
// draw+alert
for(int i=0;i<BARS;i++)
   if(patt[i]!="None")
   {
      datetime tm=iTime(_Symbol,InpTF,i+1);
      ObjectCreate(0,"CS_"+i,OBJ_TEXT,0,tm,iHigh(_Symbol,InpTF,i+1));
      ObjectSetString(0,"CS_"+i,OBJPROP_TEXT,patt[i]);
      Alert(_Symbol, " ", patt[i], " at ", TimeToString(tm,TIME_DATE|TIME_MINUTES));
   }


Pruebas y resultados

En esta sección, nos centraremos en probar el sistema y analizar los resultados. Antes de continuar, repasemos primero cómo instalar Python y configurar el servidor para asegurarnos de que funcione correctamente.

Descarga

El primer paso es descargar e instalar Python desde la página web oficial. Haz clic en el botón amarillo grande que dice «Download Python 3.x.x.».

Ejecuta el instalador

Haz doble clic en el archivo descargado. Antes de hacer clic en «Install Now», marca la casilla que dice «Add Python to PATH». Así podrás ejecutar Python fácilmente desde cualquier lugar del Símbolo del sistema. Haz clic en «Install Now» y, cuando haya terminado, en «Close».

Verificar

Pulsa Win + R, escribe «cmd» y pulsa Intro. En la ventana negra que se abre, escribe:

python --version

Deberías ver algo parecido a «Python 3.10.4». Si es así, significa que Python se ha instalado correctamente.

Una vez instalado Python correctamente, el siguiente paso es crear nuestro script de Python

Abrir Notepad++

Abre Notepad++ (o cualquier editor de texto sin formato que prefieras).

Crear un nuevo archivo

Selecciona «Archivo» > «Nuevo» y, a continuación, elige «Idioma» > «P» > «Python» para activar el resaltado de sintaxis (opcional).

Pega el código del servidor

Copia todo el contenido de tu archivo pattern_server.py (la aplicación Flask con detect_patterns(df) y todo lo demás) y pégalo en esta nueva ventana.

Guardar el archivo

  • Ve a «Archivo» > «Guardar como…».
  • Navegue hasta una carpeta que recuerde, por ejemplo, C:\PatternServer\.
  • En «Nombre de archivo», escribe `pattern_server.py` (la extensión `.py` es fundamental).
  • Haz clic en Guardar.

Instalar las bibliotecas necesarias

Abre el «Símbolo del sistema»

Para empezar, pulsa simultáneamente la tecla Windows + R para abrir el cuadro de diálogo «Ejecutar». Escribe cmd en el campo de entrada y, a continuación, pulsa Intro o haz clic en «Aceptar» para abrir la ventana del «Símbolo del sistema». Aquí es donde ejecutarás comandos para navegar por tu sistema y ejecutar scripts.

Cambiar directorio

A continuación, debes indicarle a Windows la carpeta que contiene tu script de Python. En el símbolo del sistema, utilice el comando cd (cambiar directorio) seguido de la ruta a la carpeta de su script. Por ejemplo:

cd path\to\your\script\folder
Sustituye ruta\a\tu\carpeta\de\scripts por la ruta real de tu sistema. Este paso garantiza que la sesión de su terminal apunte a la ubicación correcta donde reside su script, lo que le permite ejecutarlo sin problemas.

Instala Flask y pandas

pip install flask pandas

Esto descarga Flask (nuestro pequeño servidor web) y pandas (para el manejo de datos). Verás algo como esto:

* Serving Flask app "pattern_server"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Esto significa que tu microservicio está activo y a la espera de solicitudes. A continuación, compila tu Asesor Experto (EA) MQL5 y arrástralo al gráfico. Esta acción establece una conexión entre el EA y el servidor Python en ejecución. A continuación se muestran los resultados y las observaciones que obtuvimos tras la ejecución del sistema. 

Pruebas en EURUSD

Registros de la pestaña Expertos de MetaTrader 5

2025.07.09 22:25:42.248 Candlestick Label (EURUSD,M15)  [CSLAB] EA started – allow http://127.0.0.1:5000/patterns in Tools→Options→Expert Advisors→WebRequest
2025.07.09 22:25:42.790 Candlestick Label (EURUSD,M15)  [CSLAB] JSON-OUT: {"symbol":"EURUSD",
"timeframe":0,"time":[1752064200,1752065100,1752066000,1752066900,1752067800,1752068700,1752069600,
1752070500,1752071400,1752072300,1752073200,1752074100,1752075000,1752075900,1752076800,1752077700,
1752078600,1752079500,1752080400,1752081300,1752082200,1752083100,1752084000,1752084900,1752085800,
1752086700,1752087600,1752088500,1752089400,1752090300,1752091200],"open":[1.17051,1.17045,1.17153,
1.17167,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17148,1.17095,1.1706

2025.07.09 22:25:42.790 Candlestick Label (EURUSD,M15)  [CSLAB] POST http://127.0.0.1:5000/patterns
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] HTTP 200 RESP: {"patterns": ["doji",
 "bullishengulfing", "None", "None", "eveningstar", "None", "bullishengulfing", "None", "doji", 
"bearishengulfing", "None", "None", "None", "None", "None", "bearishengulfing", "None", "None", 
"bullishengulfing", "doji", "bearishengulfing", "None", "None", "None", "None", "None", "None",
 "None", "hammer", "eveningstar", "None"], "log": ["doji=3", "bullishengulfing=3", "eveningstar=2",
 "bearishengulfing=3", "hammer=1", "total patterns=12"], "ms": 128.25}
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: doji=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: bullishengulfing=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: eveningstar=2
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: bearishengulfing=3
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: hammer=1
2025.07.09 22:25:42.938 Candlestick Label (EURUSD,M15)  [CSLAB] SERVER: total patterns=12

Registro de comandos de Python

2025-07-09 22:25:42,806 [INFO] RAW BODY: {"symbol":"EURUSD","timeframe":0,"time":[1752064200,1752065100,1752066000,1752066900,1752067800,
1752068700,1752069600,1752070500,1752071400,1752072300,1752073200,1752074100,1752075000,1752075900,1752076800,1752077700,1752078600,
1752079500,1752080400,1752081300,1752082200,1752083100,1752084000,1752084900,1752085800,1752086700,1752087600,1752088500,1752089400,
1752090300,1752091200],"open":[1.17051,1.17045,1.17153,1.17167,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17148,1.17095,1.17066,
1.17085,1.17060,1.17072,1.17015,1.17066,1.17050,1.17087,1.17088,1.17059,1.17086,1.17174,1.17160,1.17105,1.17134,1.17166,1.17216,1.17226,
1.17189],"high":[1.17091,1.17170,1.17206,1.17225,1.17186,1.17098,1.17160,1.17246,1.17223,1.17194,1.17163,1.17112,1.17098,1.17103,1.17091,
1.17088,1.17071,1.17073,1.17109,1.17104,1.17092,1.17102,1.17179,1.17176,1.17164,1.17147,1.17170,1.17222,1.17232,1.17232,1.17199],
"low":[1.17008,1.17036,1.17120,1.17109,1.17088,1.17005,1.17028,1.17152,1.17152,1.17131,1.17095,1.17050,1.17055,1.17050,1.17059,1.17009,1.17013,
1.17039,1.17039,1.17077,1.17043,1.17056,1.17051,1.17141,1.17091,1.17101,1.17130,1.17163,1.17188,1.17180,1.17163],"close":[1.17045,
1.17153,1.17170,1.17143,1.17096,1.17034,1.17152,1.17193,1.17194,1.17149,1.17096,1.17066,1.17086,1.17061,1.17072,1.17015,1.17067,
1.17050,1.17087,1.17088,1.17058,1.17087,1.17175,1.17160,1.17104,1.17133,1.17165,1.17216,1.17227,1.17189,1.17177]}
2025-07-09 22:25:42,934 [INFO] SEND: {'patterns': ['doji', 'bullishengulfing', 'None', 'None', 'eveningstar', 'None', 'bullishengulfing',
 'None', 'doji', 'bearishengulfing','None', 'None', 'None', 'None', 'None', 'bearishengulfing', 'None', 'None', 'bullishengulfing', 'doji',
 'bearishengulfing', 'None', 'None', 'None', 'None', 'None', 'None', 'None','hammer', 'eveningstar', 'None'], 'log': ['doji=3', 
'bullishengulfing=3', 'eveningstar=2', 'bearishengulfing=3', 'hammer=1', 'total patterns=12'], 'ms': 128.25}
2025-07-09 22:25:42,936 [INFO] 127.0.0.1 - - [09/Jul/2025 22:25:42] "POST /patterns HTTP/1.1" 200 -

Prueba en Crash 1000


Conclusión

En conclusión, esta arquitectura de dos partes —el EA MQL5 por un lado y el servidor de patrones Python por el otro— demuestra ser robusta y con buena capacidad de respuesta. El EA empaqueta cuidadosamente los datos OHLC de cada nueva barra, los envía y luego muestra fielmente las etiquetas de patrón devueltas en su gráfico. Mientras tanto, el servicio de Python procesa ese JSON, lo ejecuta a través de nuestra lógica de detección diseñada manualmente y registra cada solicitud y resultado para una total transparencia. En conjunto, forman un sistema integrado y de baja latencia: llegan nuevas barras, se identifican patrones y los gráficos se actualizan casi al instante. El registro de datos claro y estructurado en ambos extremos garantiza que siempre sepa exactamente lo que está sucediendo, lo que facilita la resolución de problemas.

En general, la integración es sólida, el rendimiento es fiable y el sistema proporciona información precisa y en tiempo real sobre velas japonesas, tal como se diseñó. Puede incorporar patrones de velas adicionales según sus necesidades específicas. Como ya se mencionó, en próximos artículos profundizaremos en la utilización de bibliotecas de Python para la detección de patrones de velas japonesas, proporcionando técnicas y herramientas más avanzadas.





   
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          

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

Archivos adjuntos |
patterns.py (5.24 KB)
Implementación de un circuito cuántico para Quantum Reservoir Computing (QRC) Implementación de un circuito cuántico para Quantum Reservoir Computing (QRC)
Hoy hablaremos de un enfoque revolucionario del aprendizaje automático en el trading mediante la computación cuántica. El artículo muestra la implementación práctica de un sistema QRC adaptativo con aprendizaje adicional continuo para predecir los movimientos del mercado en tiempo real.
Desarrollo de asesores expertos autooptimizables en MQL5 (Parte 8): Análisis de múltiples estrategias (3) — Política de votación ponderada Desarrollo de asesores expertos autooptimizables en MQL5 (Parte 8): Análisis de múltiples estrategias (3) — Política de votación ponderada
Este artículo analiza por qué determinar el número óptimo de estrategias en un conjunto puede ser una tarea compleja y cómo el optimizador genético de MetaTrader 5 facilita su resolución. MQL5 Cloud también se utiliza como recurso clave para acelerar las pruebas retrospectivas y la optimización. En síntesis, nuestro análisis aquí sienta las bases para desarrollar modelos estadísticos que permitan evaluar y mejorar las estrategias de negociación a partir de nuestros resultados iniciales del conjunto de estrategias.
Redes neuronales en el trading: descomposición en lugar de escalado — Construcción de módulos Redes neuronales en el trading: descomposición en lugar de escalado — Construcción de módulos
En este artículo continuamos la familiarización práctica con SSCNN: una solución arquitectónica de nueva generación capaz de trabajar con series temporales fragmentadas. En lugar de un escalado indiscriminado: modularidad inteligente, atención al detalle y normalización selectiva. Paso a paso, creamos bloques computacionales en el entorno MQL5 y sentamos las bases para un análisis predictivo fiable.
Robot de trading basado en redes neuronales sobre la moderna arquitectura Mamba con modelo selectivo de espacio de estados (SSM) Robot de trading basado en redes neuronales sobre la moderna arquitectura Mamba con modelo selectivo de espacio de estados (SSM)
El artículo analiza la revolucionaria arquitectura de red neuronal Mamba/SSM para la predicción de series temporales financieras. Se presenta una implementación completa en MQL5 de una alternativa moderna a la arquitectura del Transformer con una complejidad lineal O(N) en lugar de cuadrática O(N²). Se analizan en detalle los modelos selectivos de espacio de estados (Selective State Space Models, SSM), las optimizaciones conscientes del hardware, las técnicas de segmentación en parches (patching) y los métodos avanzados de entrenamiento con AdamW. Se incluyen los resultados prácticos de las pruebas, que mostraron un aumento de la precisión del 62 % al 71 %, junto con una reducción del tiempo de entrenamiento de 45 a 8 minutos. Se presenta un asesor experto listo para usar, con autoaprendizaje y gestión adaptativa del riesgo, para MetaTrader 5.