English Русский 中文 Deutsch 日本語
preview
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 20): Flujo externo (IV) — Correlation Pathfinder

Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 20): Flujo externo (IV) — Correlation Pathfinder

MetaTrader 5Ejemplos |
18 0
Christian Benjamin
Christian Benjamin

Contenido


Introducción

Operar en el mercado de divisas exige una comprensión clara de muchos factores. Un factor clave es la correlación de divisas. La correlación de divisas define cómo se mueven dos pares de divisas entre sí. Muestra si se mueven en la misma dirección, en direcciones opuestas o de forma independiente a lo largo del tiempo. Dado que las divisas siempre se negocian en pares, cada par está vinculado a otros, creando una red de interdependencias.

Conocer estas relaciones puede perfeccionar tu estrategia de trading y reducir el riesgo. Por ejemplo, comprar tanto EUR/USD como GBP/USD durante un período de alta correlación positiva duplica la exposición a las mismas fuerzas del mercado y aumenta el riesgo. Alternativamente, este conocimiento permite a los operadores construir carteras diversificadas e implementar estrategias de cobertura de manera efectiva.

Este artículo explica cómo incorporar el análisis de correlación de divisas a sus herramientas de trading. Ofrece información práctica y estrategias aplicables para mejorar el rendimiento en las operaciones de trading. Los dos diagramas que aparecen a continuación ilustran la evolución del mercado para el par EUR/USD y el par GBP/USD en las mismas fechas. Ambos pares mostraron una tendencia alcista el 2 de abril y una tendencia bajista el 3 de abril, lo que demuestra una correlación positiva. Los operadores pueden utilizar un par de divisas para confirmar cambios de tendencia en el otro. Por ejemplo, si el par EUR/USD está sobrecomprado y el par GBP/USD está cayendo, eso proporciona una señal clara de una posible reversión en el EUR/USD. La herramienta Correlation Pathfinder es fundamental porque muestra claramente la interrelación entre los pares de divisas, lo que ayuda a los operadores a obtener una visión más precisa del mercado.

GBP/USD

GPBUSD

Figura 1. GBP/USD


EUR/USD

EURUSD

Figura 2. EUR/USD



Descripción general del sistema

Las correlaciones de divisas se expresan mediante un coeficiente que oscila entre -1 y +1. Un valor cercano a +1 indica que los pares de divisas tienden a moverse en la misma dirección, mientras que un valor cercano a -1 señala que se mueven en direcciones opuestas. Un coeficiente cercano a cero indica poca o ninguna relación.

Este conocimiento es vital para una gestión de riesgos eficaz. Por ejemplo, comprar tanto EUR/USD como GBP/USD durante períodos de fuerte correlación positiva aumenta la exposición general al mercado al duplicar efectivamente el riesgo. En cambio, conocer el grado de correlación permite a los operadores diversificar sus carteras y aplicar estrategias de cobertura para protegerse contra movimientos inesperados del mercado, como se ha mencionado anteriormente.

El sistema consta de dos componentes interconectados. En primer lugar, un Asesor Experto MQL5 recupera continuamente datos históricos de precios para EUR/USD y GBP/USD. Este proceso empaqueta estos datos en una formato JSON y los envía a un servidor Python. El segundo componente es un motor de análisis basado en Python. Utiliza Pandas para calcular las correlaciones generales y móviles, y emplea Matplotlib para generar un gráfico de correlación móvil con ancho fijo. Además, el servidor genera comentarios interpretativos que explican si los pares de divisas se mueven juntos o divergen, y describe las implicaciones para las estrategias de negociación.

Para comprender mejor el sistema, consulte el siguiente diagrama de flujo, que describe el flujo de datos y el proceso de análisis.

Diagrama de flujo

Figura 3. Diagrama de flujo

Este diagrama proporciona una visión general clara y visual del flujo de trabajo del sistema, mostrando el proceso desde la recuperación de datos en MetaTrader 5 hasta la generación de análisis y comentarios en el servidor Python. Los nodos etiquetados de la A a la H representan cada paso del proceso, ilustrando cómo se recopilan los datos, se empaquetan en formato JSON, se transmiten al servidor, se analizan con Pandas, se visualizan con Matplotlib y, finalmente, se acompañan de comentarios interpretativos antes de devolver los resultados del análisis.


Detalles técnicos

El asesor experto de MQL5

Recuperación de datos

El Asesor Experto (EA) recupera datos históricos de precios mediante la función integrada de MetaTrader 5, CopyRates(). Esta función recupera una matriz de registros de precios (estructurados como MqlRates) que contienen información como la hora, los precios de apertura, máximo, mínimo y cierre para un símbolo y un período de tiempo determinados. En este EA, el usuario puede configurar el intervalo de tiempo (por ejemplo, intervalos de 15 minutos mediante PERIOD_M15) y el número de barras (puntos de datos) que se van a exportar utilizando el parámetro BarsToExport. Al permitir que estos valores sean configurables, el Asesor Experto (EA) puede adaptarse a diversas estrategias de negociación. Tanto si un operador necesita una visión general a corto plazo como una perspectiva más amplia de las tendencias históricas.

MqlRates rates1[];
if(CopyRates(Symbol1, TimeFrame, 0, BarsToExport, rates1) <= 0)
{
   Print("Failed to copy rates for ", Symbol1);
   return "";
}
ArraySetAsSeries(rates1, true);

Una vez recuperados los datos para cada par de divisas (como EUR/USD y GBP/USD), el EA se asegura de que la matriz de datos esté configurada como una serie. Este paso es crucial porque organiza la matriz de manera que la barra más reciente esté en el índice 0, lo que coincide con la forma en que muchas otras funciones del entorno MQL5 esperan que se formateen los datos. Esta preparación de datos históricos garantiza que se recupere el número correcto de barras y se mantenga el orden cronológico adecuado, lo cual es esencial para el análisis posterior.

Construcción de carga útil JSON

Una vez recopilados los datos de precios, el EA construye una carga útil JSON que organiza los datos de forma ordenada en un formato estructurado para su transmisión. La función BuildJSONPayload() comienza creando un objeto JSON que incluye los nombres de los dos pares de divisas. Luego, para cada par de divisas, la función construye una matriz de objetos de datos. Cada elemento de la matriz representa una barra de datos históricos e incluye dos datos fundamentales: la hora (formateada de manera uniforme mediante TimeToString() con los parámetros TIME_DATE y TIME_SECONDS) y el precio de cierre (formateado con cinco decimales mediante DoubleToString()).

string json = "{";
json += "\"symbol1\":\"" + Symbol1 + "\",";
json += "\"symbol2\":\"" + Symbol2 + "\",";
json += "\"data1\":[";
for(int i = 0; i < ArraySize(rates1); i++)
{
   string timeStr = TimeToString(rates1[i].time, TIME_DATE | TIME_SECONDS);
   json += "{\"time\":\"" + timeStr + "\",\"close\":" + DoubleToString(rates1[i].close, 5) + "}";
   if(i < ArraySize(rates1) - 1)
      json += ",";
}
json += "],";
// The same pattern repeats for Symbol2's data array.
json += "}";
return json;

Este enfoque modular garantiza que la carga útil incluya todos los datos necesarios para el análisis en el servidor Python. La formato JSON facilita el mantenimiento de la coherencia y garantiza que el servidor pueda analizar los datos sin confusiones. Por ejemplo, al etiquetar los arrays como data1 y data2, el script del servidor sabe exactamente qué conjunto de datos corresponde a cada par de divisas. Esta clara separación es fundamental para combinar los datos posteriormente al calcular la correlación. La función itera sobre cada matriz de datos históricos, concatenando cada registro con el formato JSON adecuado, y luego finaliza la construcción cerrando el objeto JSON.

Integración de WebRequest

Una vez que se ha creado la carga útil JSON, el EA envía los datos utilizando la función WebRequest() de MetaTrader, una herramienta esencial para realizar solicitudes HTTP directamente desde la plataforma de negociación. Este componente gestiona la comunicación entre el Asesor Experto MQL5 y el servidor Python que realiza análisis adicionales. Antes de enviar los datos, el EA convierte la cadena JSON en una matriz dinámica de caracteres con la función StringToCharArray() porque WebRequest() acepta el cuerpo de la solicitud en este formato. Esta conversión es necesaria para garantizar que la carga útil se transmita correctamente a través de la red.

string requestHeaders = "Content-Type: application/json\r\n";
uchar result[];
string responseHeaders;
int webRequestResult = WebRequest("POST", pythonUrl, requestHeaders, timeout, requestData, result, responseHeaders);
if(webRequestResult == -1)
{
   Print("Error in WebRequest. Error code = ", GetLastError());
   return;
}

string response = CharArrayToString(result);
Print("Server response: ", response);

A continuación, el EA configura los encabezados HTTP, especificando que los datos están en formato JSON con el encabezado "Content-Type: application/json\r\n". Las entradas configurables, como pythonUrl (el punto final del servidor) y el tiempo de espera (el tiempo que el EA espera una respuesta), permiten al usuario ajustar con precisión los parámetros de red en función de su entorno. La función WebRequest() se utiliza con estos encabezados y ajustes de tiempo de espera para enviar una solicitud HTTP POST al servidor Python. Si la solicitud falla, el EA muestra un código de error, lo que ayuda a resolver los problemas de conectividad. De lo contrario, convierte la respuesta resultante, una matriz uchar, de nuevo en una cadena y, a continuación, muestra la respuesta del servidor; se espera que esta respuesta contenga información útil, como un valor de correlación calculado y cualquier comentario generado por el motor de análisis de Python.

El servidor de análisis de Python

Entorno del servidor

El sistema está construido sobre un servidor basado en Flask que escucha las solicitudes POST. Al iniciarse, el servidor se inicializa utilizando la configuración predeterminada de Flask y establece el nivel de registro en DEBUG. Esta configuración garantiza que todas las solicitudes entrantes y los pasos de procesamiento se registren detalladamente. El servidor está diseñado para recibir datos JSON, procesarlos, realizar el análisis y devolver los resultados en formato JSON. Al utilizar Flask, el servidor se mantiene ligero y eficiente, capaz de gestionar solicitudes web en un entorno sin interfaz gráfica, ideal para aplicaciones de negociación automatizadas.

import matplotlib
matplotlib.use("Agg")  # Use non-interactive backend to avoid GUI overhead
import matplotlib.pyplot as plt
from flask import Flask, request, jsonify
import logging

app = Flask(__name__)
logging.basicConfig(level=logging.DEBUG)

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000)

Análisis y procesamiento de datos

Una vez que el servidor recibe una solicitud POST, comienza intentando analizar la carga útil JSON entrante. Si el analizador predeterminado falla, el código decodifica los datos de la solicitud sin procesar, elimina los caracteres superfluos que se encuentren más allá de la última llave de cierre y, a continuación, carga el JSON. A continuación, los datos analizados se convierten en dos DataFrames de Pandas independientes, uno para cada par de divisas. El campo "hora" de la carga útil se analiza y se convierte en objetos de fecha y hora para facilitar la fusión precisa y el análisis de series temporales. Tras fusionar los dos DataFrames en la columna compartida «Time», el servidor calcula dos métricas de correlación clave. En primer lugar, calcula la correlación general entre los precios de cierre de los dos símbolos. En segundo lugar, calcula una correlación móvil con una ventana de 50 barras. Esta correlación dinámica proporciona información sobre cómo cambia la correlación entre los pares a lo largo del tiempo, lo cual es crucial para comprender la dinámica del mercado e identificar períodos en los que la relación se fortalece o se debilita.

import pandas as pd
import json

@app.route('/analyze', methods=['POST'])
def analyze():
    # Parse JSON payload
    data = request.get_json(silent=True)
    if not data:
        raw_data = request.data.decode('utf-8').strip()
        app.logger.debug("Raw request data: %s", raw_data)
        try:
            end_index = raw_data.rfind("}")
            trimmed_data = raw_data[:end_index+1] if end_index != -1 else raw_data
            data = json.loads(trimmed_data)
        except Exception as e:
            app.logger.error("Failed to parse JSON: %s", str(e))
            return jsonify({"error": "Invalid JSON received"}), 400

    # Convert incoming JSON arrays to DataFrames
    data1 = pd.DataFrame(data["data1"])
    data2 = pd.DataFrame(data["data2"])
    
    # Convert time strings to datetime objects
    data1['Time'] = pd.to_datetime(data1['time'])
    data2['Time'] = pd.to_datetime(data2['time'])
    
    # Merge DataFrames on 'Time'
    merged = pd.merge(data1, data2, on="Time", 
                      suffixes=('_' + data["symbol1"], '_' + data["symbol2"]))
    
    # Calculate overall correlation between the close prices
    correlation = merged[f'close_{data["symbol1"]}'].corr(merged[f'close_{data["symbol2"]}'])
    
    # Calculate rolling correlation with a 50-bar window
    merged['RollingCorrelation'] = merged[f'close_{data["symbol1"]}'].rolling(window=50).corr(merged[f'close_{data["symbol2"]}'])
    
    # [Graph generation and commentary code follows here, see next sections]

Generación y almacenamiento de gráficos

Para la representación gráfica, el servidor utiliza Matplotlib junto con el backend «Agg». Este sistema de backend evita la necesidad de una interfaz gráfica de usuario, lo que garantiza que el gráfico se genere en un entorno sin interfaz gráfica, sin generar ninguna sobrecarga relacionada con la GUI. El gráfico se genera con un tamaño de figura fijo de 7,5 pulgadas de ancho a 100 ppp. Esta configuración garantiza que la imagen de salida tenga un ancho fijo de 750 píxeles, lo que proporciona coherencia entre los informes y facilita la interpretación de los datos visuales de un vistazo. Una vez generado, el gráfico que muestra la correlación móvil se guarda como un archivo PNG en el mismo directorio que el script de Python. Almacenar la imagen localmente permite recuperarla fácilmente y compartirla sin necesidad de incluir el gráfico en la respuesta JSON del servidor.

import matplotlib.pyplot as plt

# Generate a rolling correlation plot
plt.figure(figsize=(7.5, 6), dpi=100)  # 7.5 inches * 100 dpi = 750 pixels width
plt.plot(merged['Time'], merged['RollingCorrelation'], label="Rolling Correlation (50 bars)")
plt.xlabel("Time")
plt.ylabel("Correlation")
plt.title(f"{data['symbol1']} and {data['symbol2']} Rolling Correlation")
plt.legend()
plt.grid(True)
plt.tight_layout()

# Save the graph as a PNG file in the same folder
plot_filename = "rolling_correlation.png"
plt.savefig(plot_filename)
plt.close()

Comentario interpretativo

Más allá de las cifras y los gráficos en bruto, el servidor mejora el análisis generando comentarios interpretativos. Este comentario se genera mediante una función específica que examina tanto los valores de correlación generales como los recientes (en movimiento). Por ejemplo, si la correlación general es muy alta (cercana a +1), el comentario explica que los dos pares de divisas generalmente se mueven al unísono, lo que podría indicar la eficacia limitada de la diversificación al operar con múltiples pares. Por otra parte, si la correlación es baja o se vuelve negativa, el comentario destaca el potencial de divergencia entre pares y las oportunidades para cubrirse o ajustar la exposición.

def generate_commentary(corr, rolling_series):
    """Generate a commentary based on overall and recent correlation values."""
    commentary = ""
    if corr >= 0.8:
        commentary += ("The currency pairs have a very strong positive correlation, meaning "
                       "they typically move together. This may support the use of hedging strategies.\n")
    elif corr >= 0.5:
        commentary += ("The pairs display a moderately strong positive correlation with some deviations, "
                       "indicating they often move in the same direction.\n")
    elif corr >= 0.0:
        commentary += ("The overall correlation is weakly positive, suggesting occasional movement together "
                       "but limited consistency, which may offer diversification opportunities.\n")
    elif corr >= -0.5:
        commentary += ("The pairs exhibit a weak to moderate negative correlation; they tend to move in opposite "
                       "directions, which can be useful for diversification.\n")
    else:
        commentary += ("The pairs have a strong negative correlation, implying they generally move in opposite "
                       "directions, a factor exploitable in hedging strategies.\n")
    
    if not rolling_series.empty:
        recent_trend = rolling_series.iloc[-1]
        commentary += f"Recently, the rolling correlation is at {recent_trend:.2f}. "
        if recent_trend > 0.8:
            commentary += ("This high correlation suggests near mirror-like movement. "
                           "Relative strength approaches may need reconsideration for diversification.")
        elif recent_trend < 0.3:
            commentary += ("A significant drop in correlation indicates potential decoupling. "
                           "This may signal opportunities in pair divergence trades.")
        else:
            commentary += ("The correlation remains moderate, meaning the pairs show some synchronization but also "
                           "retain independent movement.")
    return commentary

El análisis también ofrece información sobre las tendencias recientes en correlación, proporcionando a los operadores una guía práctica sobre lo que estas señales estadísticas podrían significar para su gestión de riesgos y su estrategia. Al combinar el análisis cuantitativo con la información cualitativa, el sistema ayuda a los operadores a comprender mejor el comportamiento del mercado y a tomar decisiones más fundamentadas.


Resultados

Antes de analizar los resultados, es necesario explicar cómo iniciar el servidor Python. En primer lugar, descarga e instala Python desde python.org y configura un entorno virtual ejecutando python -m venv venv y activándolo. A continuación, instala los paquetes necesarios ejecutando pip install Flask pandas matplotlib. Crea un script de Python (por ejemplo, server.py) que contenga el código de tu servidor Flask y los puntos finales necesarios. Por último, ve al directorio del script y ejecuta el servidor con python server.py. Para más detalles, consulte uno de mis artículos anteriores sobre el flujo externo.

A continuación se presentan los resultados de las pruebas realizadas en los pares EUR/USD y GBP/USD. Para obtener los mejores resultados, asegúrese de probar el sistema con los mismos pares especificados en su EA. Inicialmente, los registros de la línea de comandos indican que el sistema se inicializó correctamente y muestran claramente los datos transmitidos desde MetaTrader 5 por el EA MQL5 al servidor Python; esto incluye los valores de apertura, cierre y tiempo para el período del 2 al 9 de abril. La entrada del registro «POST /analyze HTTP/1.1» 200, confirma que la conexión se ha establecido correctamente y que el servidor Python ha ejecutado el procesamiento requerido según lo previsto.

DEBUG:plotter:Raw request data: {"symbol1":"EURUSD","symbol2":"GBPUSD","data1":[{"time":"2025.04.09 07:00:00"
,"close":1.10766},{"time":"2025.04.09 06:45:00","close":1.10735},{"time":"2025.04.09 06:30:00","close":1.10602}
,{"time":"2025.04.09 06:15:00","close":1.10538},{"time":"2025.04.09 06:00:00","close":1.10486},
{"time":"2025.04.09 05:45:00","close":1.10615},{"time":"2025.04.09 05:30:00","close":1.10454},
{"time":"2025.04.09 05:15:00","close":1.10402},{"time":"2025.04.09 05:00:00","close":1.10447},
{"time":"2025.04.09 04:45:00","close":1.10685},{"time":"2025.04.09 04:30:00","close":1.10582},
{"time":"2025.04.09 04:15:00","close":1.10617},{"time":"2025.04.09 04:00:00","close":1.10384},
{"time":"2025.04.09 03:45:00","close":1.10196},{"time":"2025.04.09 03:30:00","close":1.10184},
{"time":"2025.04.09 03:15:00","close":1.10339},{"time":"2025.04.09 03:00:00","close":1.10219},
{"time":"2025.04.09 02:45:00","close":1.10197},{"time":"2025.04.09 02:30:00","close":1.10130},
{"time":"2025.04.09 02:15:00","close":1.10233},{"time":"2025.04.09 02:00:00","close":1.10233},
{"time":"2025.04.09 01:45:00","close":1.10200},{"time":"2025.04.09 01:30:00","close":1.10289},
{"time":"2025.04.09 01:15:00","close":1.10382},{"time":"2025.04.09 01:00:00","close":1.10186},
{"time":"2025.04.09 00:45:00","close":1.10148},{"time":"2025.04.09 00:30:00","close":1.09985},
{"time":"2025.04.09 00:15:00","close":1.09894},{"time":"2025.04.09 00:00:00","close":1.09747},
{"time":"2025.04.08 23:45:00","close":1.09776},{"time":"2025.04.08 23:30:00","close":1.09789},
{"time":"2025.04.08 23:15:00","close":1.09793},{"time":"2025.04.08 23:00:00","close":1.09740},
{"time":"2025.04.08 22:45:00","close":1.09681},{"time":"2025.04.08 22:30:00","close":1.09718},
{"time":"2025.04.08 22:15:00","close":1.09669},{"time":"2025.04.08 22:00:00","close":1.09673},
{"time":"2025.04.08 21:45:00","close":1.09586},{"time":"2025.04.08 21:30:00","close":1.09565},
{"time":"2025.04.08 21:15:00","close":1.09507},{"time":"2025.04.08 21:00:00","close":1.09493},
{"time":"2025.04.08 20:45:00","close":1.09529},{"time":"2025.04.08 20:30:00","close":1.09442},
{"time":"2025.04.08 20:15:00","close":1.09417},{"time":"2025.04.08 20:00:00","close":1.09533},
{"time":"2025.04.08 19:45:00","close":1.09541},{"time":"2025.04.08 19:30:00","close":1.09587},
{"time":"2025.04.08 19:15:00","close":1.09684},{"time":"2025.04.08 19:00:00","close":1.09724},
{"time":"2025.04.08 18:45:00","close":1.09521},{"time":"2025.04.08 18:30:00","close":1.09551},
{"time":"2025.04.08 18:15:00","close":1.09561},{"time":"2025.04.08 18:00:00","close":1.09474},
{"time":"2025.04.08 17:45:00","close":1.09337},{"time":"2025.04.08 17:30:00","close":1.09334},
{"time":"2025.04.08 17:15:00","close":1.09421},{"time":"2025.04.08 17:00:00","close":1.09429},
{"time":"2025.04.08 16:45:00","close":1.09296},{"time":"2025.04.08 16:30:00","close":1.09210},
{"time":"2025.04.08 16:15:00","close":1.09123},{"time":"2025.04.08 16:00:00","close":1.09073},
{"time":"2025.04.08 15:45:00","close":1.09116},{"time":"2025.04.08 15:30:00","close":1.09083},
{"time":"2025.04.08 15:15:00","close":1.09119},{"time":"2025.04.08 15:00:00","close":1.08986},
{"time":"2025.04.08 14:45:00","close":1.09102},{"time":"2025.04.08 14:30:00","close":1.08954},
{"time":"2025.04.08 14:15:00","close":1.09051},{"time":"2025.04.08 14:00:00","close":1.09213},
{"time":"2025.04.08 13:45:00","close":1.09357},{"time":"2025.04.08 13:30:00","close":1.09300},
{"time":"2025.04.08 13:15:00","close":1.09548},{"time":"2025.04.08 13:00:00","close":1.09452},
{"time":"2025.04.08 12:45:00","close":1.09485},{"time":"2025.04.08 12:30:00","close":1.09585},
{"time":"2025.04.08 12:15:00","close":1.09477},{"time":"2025.04.08 12:00:00","close":1.09512},
{"time":"2025.04.08 11:45:00","close":1.09342},{"time":"2025.04.08 11:30:00","close":1.09311},
{"time":"2025.04.07 09:45:00","close":1.09627},{"time":"2025.04.07 09:30:00","close":1.09545},
{"time":"2025.04.07 09:15:00","close":1.09597},{"time":"2025.04.07 09:00:00","close":1.09729},
{"time":"2025.04.07 08:45:00","close":1.09918},{"time":"2025.04.07 08:30:00","close":1.09866},
{"time":"2025.04.07 08:15:00","close":1.09705},{"time":"2025.04.07 08:00:00","close":1.10051},
{"time":"2025.04.07 07:45:00","close":1.10006},{"time":"2025.04.07 07:30:00","close":1.10232},
{"time":"2025.04.07 07:15:00","close":1.10273},{"time":"2025.04.07 07:00:00","close":1.10397},
{"time":"2025.04.07 06:45:00","close":1.10029},{"time":"2025.04.07 06:30:00","close":1.10083},
{"time":"2025.04.07 06:15:00","close":1.10012},{"time":"2025.04.07 06:00:00","close":1.10084},
{"time":"2025.04.07 05:45:00","close":1.10183},{"time":"2025.04.07 05:30:00","close":1.09905},
{"time":"2025.04.07 05:15:00","close":1.09941},{"time":"2025.04.07 05:00:00","close":1.09826},
{"time":"2025.04.07 04:45:00","close":1.09848},{"time":"2025.04.07 04:30:00","close":1.09830},
{"time":"2025.04.07 04:15:00","close":1.09739},{"time":"2025.04.07 04:00:00","close":1.09608},
{"time":"2025.04.07 03:45:00","close":1.09503},{"time":"2025.04.07 03:30:00","close":1.09456},
{"time":"2025.04.07 03:15:00","close":1.09373},{"time":"2025.04.07 03:00:00","close":1.09343},
{"time":"2025.04.07 02:45:00","close":1.09353},{"time":"2025.04.07 02:30:00","close":1.09248},
{"time":"2025.04.07 02:15:00","close":1.09360},{"time":"2025.04.07 02:00:00","close":1.09550},
{"time":"2025.04.07 01:45:00","close":1.09673},{"time":"2025.04.07 01:30:00","close":1.09740},
{"time":"2025.04.07 01:15:00","close":1.09688},{"time":"2025.04.07 01:00:00","close":1.09649},
{"time":"2025.04.07 00:45:00","close":1.09667},{"time":"2025.04.07 00:30:00","close":1.09526},
{"time":"2025.04.07 00:15:00","close":1.09555},{"time":"2025.04.07 00:00:00","close":1.09517},
{"time":"2025.04.06 23:45:00","close":1.09825},{"time":"2025.04.06 23:30:00","close":1.09981},
{"time":"2025.04.06 23:15:00","close":1.09872},{"time":"2025.04.06 23:00:00","close":1.09981},
{"time":"2025.04.06 22:45:00","close":1.09822},{"time":"2025.04.06 22:30:00","close":1.09803},
{"time":"2025.04.06 22:15:00","close":1.09826},{"time":"2025.04.06 22:00:00","close":1.09529},
{"time":"2025.04.06 21:45:00","close":1.09147},{"time":"2025.04.06 21:30:00","close":1.09046},
{"time":"2025.04.06 21:15:00","close":1.08910},{"time":"2025.04.06 21:00:00","close":1.08818},
{"time":"2025.04.04 20:45:00","close":1.09623},{"time":"2025.04.04 20:30:00","close":1.09435},
{"time":"2025.04.04 20:15:00","close":1.09339},{"time":"2025.04.04 20:00:00","close":1.09502},
{"time":"2025.04.04 19:45:00","close":1.09436},{"time":"2025.04.04 19:30:00","close":1.09631},
{"time":"2025.04.04 19:15:00","close":1.09425},{"time":"2025.04.04 19:00:00","close":1.09358},
{"time":"2025.04.04 18:45:00","close":1.09447},{"time":"2025.04.04 18:30:00","close":1.09611},
{"time":"2025.04.04 18:15:00","close":1.09604},{"time":"2025.04.04 18:00:00","close":1.09531},
{"time":"2025.04.04 17:45:00","close":1.09472},{"time":"2025.04.04 17:30:00","close":1.09408},
{"time":"2025.04.04 17:15:00","close":1.09311},{"time":"2025.04.04 17:00:00","close":1.09407},
{"time":"2025.04.04 16:45:00","close":1.09714},{"time":"2025.04.04 16:30:00","close":1.09690},
{"time":"2025.04.04 16:15:00","close":1.09845},{"time":"2025.04.04 16:00:00","close":1.09892},
{"time":"2025.04.04 15:45:00","close":1.10139},{"time":"2025.04.04 15:30:00","close":1.09998},
{"time":"2025.04.04 15:15:00","close":1.09837},{"time":"2025.04.04 15:00:00","close":1.09970},
{"time":"2025.04.04 14:45:00","close":1.09862},{"time":"2025.04.04 14:30:00","close":1.09706},
{"time":"2025.04.04 14:15:00","close":1.09991},{"time":"2025.04.04 14:00:00","close":1.10068},
{"time":"2025.04.04 13:45:00","close":1.10057},{"time":"2025.04.04 13:30:00","close":1.10252},
{"time":"2025.04.04 13:15:00","close":1.10288},{"time":"2025.04.04 13:00:00","close":1.10358},
{"time":"2025.04.04 12:45:00","close":1.10200},{"time":"2025.04.04 12:30:00","close":1.10289},
{"time":"2025.04.04 12:15:00","close":1.10794},{"time":"2025.04.04 12:00:00","close":1.10443},
{"time":"2025.04.04 11:45:00","close":1.10601},{"time":"2025.04.04 11:30:00","close":1.10697},
{"time":"2025.04.04 11:15:00","close":1.10502},{"time":"2025.04.04 11:00:00","close":1.10517},
{"time":"2025.04.04 10:45:00","close":1.10305},{"time":"2025.04.04 10:30:00","close":1.10340},
{"time":"2025.04.04 10:15:00","close":1.10447},{"time":"2025.04.04 10:00:00","close":1.09869},
{"time":"2025.04.04 09:45:00","close":1.09844},{"time":"2025.04.04 09:30:00","close":1.09757},
{"time":"2025.04.04 09:15:00","close":1.09820},{"time":"2025.04.04 09:00:00","close":1.09786},
{"time":"2025.04.04 08:45:00","close":1.09962},{"time":"2025.04.04 08:30:00","close":1.10002},
{"time":"2025.04.04 08:15:00","close":1.10062},{"time":"2025.04.04 08:00:00","close":1.10034},
{"time":"2025.04.04 07:45:00","close":1.10042},{"time":"2025.04.04 07:30:00","close":1.10223},
{"time":"2025.04.04 07:15:00","close":1.10490},{"time":"2025.04.04 07:00:00","close":1.10641},
{"time":"2025.04.04 06:45:00","close":1.10506},{"time":"2025.04.04 06:30:00","close":1.10638},
{"time":"2025.04.04 06:15:00","close":1.10649},{"time":"2025.04.04 06:00:00","close":1.10747},
{"time":"2025.04.04 05:45:00","close":1.10843},{"time":"2025.04.04 05:30:00","close":1.10809},
{"time":"2025.04.04 05:15:00","close":1.11057},{"time":"2025.04.04 05:00:00","close":1.10984},
{"time":"2025.04.04 04:45:00","close":1.10874},{"time":"2025.04.04 04:30:00","close":1.10896},
{"time":"2025.04.04 04:15:00","close":1.10906},{"time":"2025.04.04 04:00:00","close":1.10876},
{"time":"2025.04.04 03:45:00","close":1.10937},{"time":"2025.04.04 03:30:00","close":1.10918},
{"time":"2025.04.04 03:15:00","close":1.10766},{"time":"2025.04.04 03:00:00","close":1.10695},
{"time":"2025.04.04 02:45:00","close":1.10632},{"time":"2025.04.04 02:30:00","close":1.10668},
{"time":"2025.04.04 02:15:00","close":1.10625},{"time":"2025.04.04 02:00:00","close":1.10773},
{"time":"2025.04.04 01:45:00","close":1.10677},{"time":"2025.04.04 01:30:00","close":1.10625},
{"time":"2025.04.04 01:15:00","close":1.10610},{"time":"2025.04.04 01:00:00","close":1.10589},
{"time":"2025.04.04 00:45:00","close":1.10606},{"time":"2025.04.04 00:30:00","close":1.10603},
{"time":"2025.04.04 00:15:00","close":1.10403},{"time":"2025.04.04 00:00:00","close":1.10432},
{"time":"2025.04.03 23:45:00","close":1.10452},{"time":"2025.04.03 23:30:00","close":1.10467},
{"time":"2025.04.03 23:15:00","close":1.10446},{"time":"2025.04.03 23:00:00","close":1.10524},
{"time":"2025.04.03 22:45:00","close":1.10642},{"time":"2025.04.03 22:30:00","close":1.10631},
{"time":"2025.04.03 22:15:00","close":1.10582},{"time":"2025.04.03 22:00:00","close":1.10577},
{"time":"2025.04.03 21:45:00","close":1.10515},{"time":"2025.04.03 21:30:00","close":1.10497},
{"time":"2025.04.03 21:15:00","close":1.10505},{"time":"2025.04.03 21:00:00","close":1.10488},
{"time":"2025.04.03 20:45:00","close":1.10514},{"time":"2025.04.03 20:30:00","close":1.10448},
{"time":"2025.04.03 20:15:00","close":1.10312},{"time":"2025.04.03 20:00:00","close":1.10253},
{"time":"2025.04.03 19:45:00","close":1.10275},{"time":"2025.04.03 19:30:00","close":1.10164},
{"time":"2025.04.03 19:15:00","close":1.10192},{"time":"2025.04.03 19:00:00","close":1.10320},
{"time":"2025.04.03 18:45:00","close":1.10373},{"time":"2025.04.03 18:30:00","close":1.10362},
{"time":"2025.04.03 18:15:00","close":1.10322},{"time":"2025.04.03 18:00:00","close":1.10236},
{"time":"2025.04.03 17:45:00","close":1.10245},{"time":"2025.04.03 17:30:00","close":1.10222},
{"time":"2025.04.03 17:15:00","close":1.10273},{"time":"2025.04.03 17:00:00","close":1.10267},
{"time":"2025.04.03 16:45:00","close":1.10386},{"time":"2025.04.03 16:30:00","close":1.10404},
{"time":"2025.04.03 16:15:00","close":1.10367},{"time":"2025.04.03 16:00:00","close":1.10491},
{"time":"2025.04.03 15:45:00","close":1.10506},{"time":"2025.04.03 15:30:00","close":1.10452},
{"time":"2025.04.03 15:15:00","close":1.10613},{"time":"2025.04.03 15:00:00","close":1.10922},
{"time":"2025.04.03 14:45:00","close":1.11182},{"time":"2025.04.03 14:30:00","close":1.11197},
{"time":"2025.04.03 14:15:00","close":1.10950},{"time":"2025.04.03 14:00:00","close":1.10981},
{"time":"2025.04.03 13:45:00","close":1.10784},{"time":"2025.04.03 13:30:00","close":1.10911},
{"time":"2025.04.03 13:15:00","close":1.10943},{"time":"2025.04.03 13:00:00","close":1.11064},
{"time":"2025.04.03 12:45:00","close":1.10816},{"time":"2025.04.03 12:30:00","close":1.10910},
{"time":"2025.04.03 12:15:00","close":1.10858},{"time":"2025.04.03 12:00:00","close":1.10867},
{"time":"2025.04.03 11:45:00","close":1.10876},{"time":"2025.04.03 11:30:00","close":1.10839},
{"time":"2025.04.03 11:15:00","close":1.10570},{"time":"2025.04.03 11:00:00","close":1.10596},
{"time":"2025.04.03 10:45:00","close":1.10521},{"time":"2025.04.03 10:30:00","close":1.10696},
{"time":"2025.04.03 10:15:00","close":1.10859},{"time":"2025.04.03 10:00:00","close":1.11052},
{"time":"2025.04.03 09:45:00","close":1.10305},{"time":"2025.04.03 09:30:00","close":1.10280},
{"time":"2025.04.03 09:15:00","close":1.10336},{"time":"2025.04.03 09:00:00","close":1.10304},
{"time":"2025.04.03 08:45:00","close":1.10093},{"time":"2025.04.03 08:30:00","close":1.10092},
{"time":"2025.04.03 08:15:00","close":1.09885},{"time":"2025.04.03 08:00:00","close":1.09803},
{"time":"2025.04.03 07:45:00","close":1.09707},{"time":"2025.04.03 07:30:00","close":1.09658},
{"time":"2025.04.03 07:15:00","close":1.09497},{"time":"2025.04.03 07:00:00","close":1.09733},
{"time":"2025.04.03 06:45:00","close":1.09896},{"time":"2025.04.03 06:30:00","close":1.09775},
{"time":"2025.04.03 06:15:00","close":1.09488},{"time":"2025.04.03 06:00:00","close":1.09457},
{"time":"2025.04.03 05:45:00","close":1.09444},{"time":"2025.04.03 05:30:00","close":1.09515},
{"time":"2025.04.03 05:15:00","close":1.09431},{"time":"2025.04.03 05:00:00","close":1.09171},
{"time":"2025.04.03 04:45:00","close":1.09069},{"time":"2025.04.03 04:30:00","close":1.09104},
{"time":"2025.04.03 04:15:00","close":1.09109},{"time":"2025.04.03 04:00:00","close":1.09110},
{"time":"2025.04.03 03:45:00","close":1.09148},{"time":"2025.04.03 03:30:00","close":1.09118},
{"time":"2025.04.03 03:15:00","close":1.09196},{"time":"2025.04.03 03:00:00","close":1.09115},
{"time":"2025.04.03 02:45:00","close":1.09122},{"time":"2025.04.03 02:30:00","close":1.09207},
{"time":"2025.04.03 02:15:00","close":1.09220},{"time":"2025.04.03 02:00:00","close":1.09134},
{"time":"2025.04.03 01:45:00","close":1.09132},{"time":"2025.04.03 01:30:00","close":1.09137},
{"time":"2025.04.03 01:15:00","close":1.09078},{"time":"2025.04.03 01:00:00","close":1.08970},
{"time":"2025.04.03 00:45:00","close":1.08906},{"time":"2025.04.03 00:30:00","close":1.08995},
{"time":"2025.04.03 00:15:00","close":1.08831},{"time":"2025.04.03 00:00:00","close":1.08905},
{"time":"2025.04.02 23:45:00","close":1.09044},{"time":"2025.04.02 23:30:00","close":1.09068},
{"time":"2025.04.02 23:15:00","close":1.08874},{"time":"2025.04.02 23:00:00","close":1.08552},
{"time":"2025.04.02 22:45:00","close":1.08389},{"time":"2025.04.02 22:30:00","close":1.08277},
{"time":"2025.04.02 22:15:00","close":1.08221},{"time":"2025.04.02 22:00:00","close":1.08161},
{"time":"2025.04.02 21:45:00","close":1.08274},{"time":"2025.04.02 21:30:00","close":1.08286},
{"time":"2025.04.02 21:15:00","close":1.08156},{"time":"2025.04.02 21:00:00","close":1.08350},
{"time":"2025.04.02 20:45:00","close":1.08507},{"time":"2025.04.02 20:30:00","close":1.08184},
INFO:werkzeug:127.0.0.1 - - [09/Apr/2025 09:04:18] "POST /analyze HTTP/1.1" 200 -

A continuación se muestran los registros de la pestaña Expertos de MetaTrader 5, que incluyen los comentarios del servidor Python sobre el análisis de correlación. Los registros detallan los datos recibidos desde días anteriores hasta el día actual, mostrando cómo se han movido los dos pares de divisas, EUR/USD y GBP/USD, en relación el uno con el otro. El comentario interpreta el gráfico de correlación, explicando que, durante el período registrado, los pares generalmente mantienen una fuerte correlación positiva. 

2025.04.09 00:57:33.296 Correlation Pathfinder (GBPUSD,M15)     Server response: 
{"commentary":"The overall correlation is weakly positive, suggesting occasional movement together but 
limited consistency, which may offer diversification opportunities.\nRecently, the rolling correlation is at 
0.82. Esta alta correlación sugiere un movimiento casi simétrico. Relative strength approaches may need 
reconsideration for diversification.","correlation":0.3697032305325312,"message":"Plot saved as rolling_
correlation.png"}
Esto indica que tienden a moverse al unísono, aunque en ocasiones se han producido ligeras desviaciones. Estas desviaciones pueden indicar una divergencia temporal del mercado, lo que pone de manifiesto posibles oportunidades para la diversificación de carteras o la cobertura de riesgos. En general, los registros confirman la transmisión exitosa de datos y el procesamiento preciso, lo que ofrece información que puede ayudar a perfeccionar las estrategias comerciales en función de la relación cambiante entre los pares de divisas.
2025.04.09 00:
57 :33.296 Correlation Pathfinder (EURUSD,M15)     Server response: 
{"commentary":"The overall correlation is weakly positive, suggesting occasional movement together but 
limited consistency, which may offer diversification opportunities.\nRecently, the rolling correlation is at
 0.83. Esta alta correlación sugiere un movimiento casi simétrico. Relative strength approaches may need 
reconsideration for diversification.","correlation":0.33874205977082567,"message":"Plot saved as 
rolling_correlation.png"}

A continuación se muestra nuestro análisis de correlación gráfica. Del 2 al 9 de abril, la correlación móvil entre EUR/USD y GBP/USD se mantuvo alta, cerca de 0,8 a 1,0, lo que demuestra que ambos pares generalmente se movieron en la misma dirección. Hubo momentos en que la correlación cayó bruscamente hasta aproximadamente 0,3, lo que indica una divergencia breve probablemente debida a eventos de mercado de corta duración o noticias específicas sobre divisas. La correlación se recuperó rápidamente, acercándose de nuevo a 1,0, lo que confirma que las fuerzas subyacentes del mercado realinean estos pares. Los operadores pueden utilizar estas caídas ocasionales como señales de oportunidades de divergencia y, a continuación, realizar un seguimiento hasta que se restablezcan los niveles normales de correlación.

Correlación

Figura 4. Correlación móvil


Conclusión

Este diagrama proporciona una visión general clara y visual del flujo de trabajo del sistema, mostrando el proceso desde la recuperación de datos en MetaTrader 5 hasta la generación de análisis y comentarios en el servidor Python. Los nodos etiquetados de la A a la H representan cada paso del proceso, ilustrando cómo se recopilan los datos, se empaquetan en formato JSON, se transmiten al servidor, se analizan con Pandas, se visualizan con Matplotlib y, finalmente, se acompañan de comentarios interpretativos antes de devolver los resultados del análisis.

Fecha Nombre de la herramienta  Descripción Versión  Actualizaciones  Notas
01/10/24 Chart Projector Script para superponer un efecto fantasma a la evolución del precio del día anterior. 1.0 Versión inicial Herramienta número 1
18/11/24 Analytical Comment Proporciona la información del día anterior en formato tabular, además de anticipar la dirección futura del mercado. 1.0 Versión inicial Herramienta número 2
27/11/24 Analytics Master Actualización periódica de las métricas del mercado cada dos horas.  1.01 Segundo lanzamiento Herramienta número 3
02/12/24 Analytics Forecaster  Actualización periódica de las métricas del mercado cada dos horas con integración de Telegram. 1.1 Tercera edición Herramienta número 4
09/12/24 Volatility Navigator El EA analiza las condiciones del mercado utilizando los indicadores Bandas de Bollinger, RSI y ATR. 1.0 Versión inicial Herramienta número 5
19/12/24 Mean Reversion Signal Reaper  Analiza el mercado utilizando una estrategia de reversión a la media y proporciona una señal.  1.0  Versión inicial  Herramienta número 6 
09/01/25  Signal Pulse  Analizador de múltiples marcos temporales. 1.0  Versión inicial  Herramienta número 7 
17/01/25  Metrics Board  Panel con botón para análisis.  1.0  Versión inicial Herramienta número 8 
21/01/25 External Flow Análisis a través de bibliotecas externas. 1.0  Versión inicial Herramienta número 9 
27/01/25 VWAP Volume Weighted Average Price.   1.3  Versión inicial  Herramienta número 10 
02/02/25  Heikin Ashi  Suavizado de tendencias e identificación de señales de reversión.  1.0  Versión inicial  Herramienta número 11
04/02/25  FibVWAP  Generación de señales mediante análisis con Python.  1.0  Versión inicial  Herramienta número 12
14/02/25  RSI DIVERGENCE  Divergencias entre la acción del precio y el RSI.  1.0  Versión inicial  Herramienta número 13 
17/02/25  Parabolic Stop and Reverse (PSAR)  Automatización de la estrategia PSAR. 1.0 Versión inicial  Herramienta número 14
20/02/25  Quarters Drawer Script  Niveles de cuartos de dibujo en la tabla.  1.0  Versión inicial  Herramienta número 15 
27/02/25  Intrusion Detector Detecta y alerta cuando el precio alcanza niveles de cuartos. 1.0   Versión inicial Herramienta número 16 
27/02/25  TrendLoom Tool  Panel de análisis de múltiples marcos temporales. 1.0 Versión inicial Herramienta número 17
11/03/25  Quarters Board  Panel con botones para activar o desactivar los niveles de cuartos.  1.0  Versión inicial Herramienta número 18
26/03/25  ZigZag Analyzer  Trazado de líneas de tendencia con el indicador ZigZag.  1.0  Versión inicial  Herramienta número 19 
10/04/25  Correlation Pathfinder Representación gráfica de correlaciones de divisas mediante bibliotecas de Python. 1.0 Versión inicial  Herramienta número 20 

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

Archivos adjuntos |
plotter.py (4.46 KB)
Integración de un modelo de IA en una estrategia de trading MQL5 ya existente Integración de un modelo de IA en una estrategia de trading MQL5 ya existente
Este tema se centra en la incorporación de un modelo de IA entrenado (como un modelo basado en redes LSTM o un modelo predictivo basado en aprendizaje automático) en una estrategia de trading MQL5 existente.
Indicador de pronóstico ARIMA en MQL5 Indicador de pronóstico ARIMA en MQL5
En este artículo, crearemos un indicador de pronóstico ARIMA en MQL5. El artículo analiza cómo el modelo ARIMA genera pronósticos y su aplicabilidad al mercado Forex y al mercado de valores en general. También explica qué es la autorregresión AR, cómo se utilizan los modelos autorregresivos para realizar pronósticos y cómo funciona el mecanismo autorregresivo.
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.
Ingeniería de características con Python y MQL5 (Parte IV): Reconocimiento de patrones de velas japonesas mediante regresión con UMAP Ingeniería de características con Python y MQL5 (Parte IV): Reconocimiento de patrones de velas japonesas mediante regresión con UMAP
Las técnicas de reducción de dimensiones se utilizan ampliamente para mejorar el rendimiento de los modelos de aprendizaje automático. Analicemos una técnica relativamente nueva conocida como Aproximación y Proyección de Variedades Uniformes (Uniform Manifold Approximation and Projection, UMAP). Esta nueva técnica se ha desarrollado con el objetivo expreso de superar las limitaciones de los métodos tradicionales, que generan artefactos y distorsiones en los datos. UMAP es una potente técnica de reducción de dimensionalidad que nos ayuda a agrupar velas japonesas similares de una manera novedosa y eficaz, lo que reduce el error en datos fuera de muestra y mejora nuestro rendimiento de trading.