Obtenga una ventaja sobre cualquier mercado
Contenido
- Sinopsis
- Introducción
- Visión general de la estrategia: Fuentes de datos alternativas
- Técnicas de aprendizaje automático
- Construir la estrategia
- Conclusión
- Recomendaciones
Sinopsis
Hoy elaboraremos una sólida estrategia de negociación diseñada para proporcionar a los operadores una ventaja competitiva significativa en diversos mercados. Mientras que los participantes convencionales en el mercado se basan exclusivamente en una combinación de datos relacionados con los precios, indicadores técnicos y anuncios de noticias públicas para la toma de decisiones, nuestra estrategia adopta un enfoque pionero al aprovechar fuentes de datos alternativas que siguen siendo en gran medida inexploradas por la mayoría.
La premisa de nuestra estrategia radica en la integración de datos alternativos, una opción que los principales participantes en el mercado suelen pasar por alto. Aprovechando estas fuentes de datos sin explotar y aplicando técnicas de aprendizaje automático, podemos posicionarnos para obtener ideas y perspectivas únicas y exclusivas de nuestra estrategia.
En nuestra exploración, examinaremos los datos proporcionados por el Banco de la Reserva Federal de San Luis, concretamente aprovechando su completa base de datos econométricos de series temporales conocida como FRED. FRED es accesible al público en todo momento, y sin duda ofrece datos cruciales para la toma de decisiones informadas en el comercio. Además, los datos procedentes de bancos centrales como la Fed de St. Louis suelen servir de indicadores adelantados, lo que mejora nuestra capacidad para programar eficazmente las entradas y salidas.
Además, estos datos son inmunes a la manipulación externa, lo que los convierte en un candidato ideal para integrarlos en nuestra estrategia de negociación.
Este artículo pretende servir de guía práctica, demostrando la fácil utilización de Python y MetaTrader 5 para construir estrategias de trading de vanguardia. Nuestro compromiso con la claridad y la simplicidad asegura que cada aspecto esté explicado de manera clara, permitiendo a los lectores comprender nuestro enfoque sin dificultad y comenzar hoy mismo.
Introducción: Este artículo pretende demostrar cómo aplicar fácilmente datos alternativos en las estrategias de negociación.
Al final de este artículo, los lectores obtendrán información sobre las siguientes áreas clave:- Cómo los datos alternativos pueden ayudar a tomar decisiones en medio del ruido y la incertidumbre.
- Técnicas de selección e identificación de fuentes fiables de datos alternativos.
- Mejores prácticas de análisis y preprocesamiento de datos alternativos para el análisis.
- Creación de estrategias de negociación sólidas que integren fuentes de datos alternativas para mejorar el proceso de toma de decisiones.
Un ejemplo que ilustra el impacto de los datos alternativos es el uso estratégico de imágenes satelitales. Los operadores avanzados aprovechan las imágenes de satélite para seguir las pautas del tráfico marítimo u observar los niveles de inventario de los petroleros. Estos datos exclusivos permiten a los operadores descubrir oportunidades de negociación rentables que, de otro modo, permanecerían ocultas.
Aunque el uso de imágenes por satélite puede ser más común entre los operadores adinerados, este artículo muestra cómo cualquier operador puede emplear datos alternativos de libre acceso para adelantarse al mercado. Además, mediante el uso de modelos de aprendizaje automático, podemos analizar múltiples fuentes de datos simultáneamente, mejorando aún más su capacidad de toma de decisiones.
Visión general de la estrategia de negociación: Fuentes de datos alternativas.
Nuestra estrategia de negociación está diseñada para ser fácilmente comprensible. Integraremos datos de mercado convencionales de nuestro terminal MetaTrader 5 con datos alternativos procedentes del Banco de la Reserva Federal de St. Louis, centrándonos específicamente en la previsión de los futuros movimientos de precios del par GBPUSD.
Para lograrlo, utilizaremos dos conjuntos de datos económicos clave como fuentes de datos alternativas. El primer conjunto de datos proporciona información sobre la libra esterlina, ofreciendo una serie temporal de los tipos de interés aplicados a las transacciones bancarias fuera de hora en el mercado de la libra esterlina británica. Estas fluctuaciones de los tipos de interés sirven para calibrar el nivel de demanda institucional de libras esterlinas, proporcionando valiosos indicadores para nuestros modelos de previsión.
Del mismo modo, el segundo conjunto de datos contiene información sobre el dólar estadounidense y comprende una serie temporal de los tipos de interés aplicados a los préstamos a un día a los bancos estadounidenses, regidos por la Reserva Federal. El control que ejerce la Reserva Federal sobre estos tipos de interés a través de los ajustes de la política monetaria ofrece perspectivas alternativas sobre las tendencias económicas que pueden repercutir en el dólar.
Analizando e interpretando estos datos de series temporales económicas y empleando técnicas de aprendizaje automático, es de esperar que podamos hacer realidad nuestro objetivo de descubrir indicadores adelantados que nos otorguen una ventaja competitiva en el mercado.
La piedra angular de la eficacia de nuestra estrategia depende de garantizar una fuente fiable de datos alternativos. La disponibilidad de fuentes de datos alternativas fiables varía en función de los mercados en los que se opere. Los mercados sintéticos, generados por generadores de números aleatorios, carecen prácticamente de fuentes de datos alternativas. Esto se debe a que los mercados sintéticos son independientes del mundo exterior.
- Credibilidad: ¿De qué manera obtiene tu fuente de datos alternativos la información en primer lugar? Examina la fiabilidad de los canales de información de los que dependen. Preguntas como "¿Cómo acceden a la información?" y "¿Son fiables sus canales de información?" son cruciales para evaluar la credibilidad. Cualquier duda sobre estos aspectos indica la necesidad de una evaluación más exhaustiva.
- Frecuencia de actualización: Nos centramos en fuentes de datos alternativas actualizadas diariamente, en consonancia con nuestro marco temporal de negociación. Sin embargo, hay que tener en cuenta que no todas las fuentes ofrecen actualizaciones diarias; algunas se actualizan mensual o anualmente.
- Reputación: Más allá de la credibilidad, dé prioridad a las fuentes con un historial reputado y un interés demostrado por mantener la exactitud. Un proveedor acreditado no sólo añade credibilidad a nuestros datos, sino que también demuestra responsabilidad.
- Presentación transparente: Opte por proveedores que presenten los datos de forma transparente y fácil de usar. La claridad y la sencillez en la presentación de los datos son primordiales para una toma de decisiones eficaz, sobre todo teniendo en cuenta la carga cognitiva asociada a los datos complejos.
- Estructura de precios: Evaluar los modelos de precios de fuentes de datos alternativas, equilibrando nuestras necesidades y las limitaciones presupuestarias. Mientras que algunas fuentes pueden ser gratuitas, otras pueden exigir un pago. Nuestra elección debe ajustarse a la propuesta de valor ofrecida por cada fuente.
- Términos y condiciones: Revise detenidamente y comprenda los términos y condiciones asociados a las fuentes de datos alternativas, en particular las que exigen un pago. Una comprensión clara de las restricciones y limitaciones de uso garantiza una toma de decisiones informada y evita cualquier problema de cumplimiento involuntario.
En resumen, una evaluación rigurosa de las fuentes de datos alternativas basada en la credibilidad, la frecuencia de actualización, la reputación, la transparencia, el precio y los términos y condiciones es esencial para aprovechar los datos con eficacia dentro de nuestra estrategia de negociación.
Empezaremos ahora a examinar algunos datos alternativos procedentes del Banco de la Reserva Federal de San Luis. Hay dos formas de obtener datos de la Reserva Federal de San Luis:
- De manera programática utilizando la biblioteca FRED para Python.
- Manualmente en el sitio web de FRED.
Si es la primera vez que utiliza estos conjuntos de datos, le aconsejo que primero los recopile manualmente. Esto es aconsejable porque el sitio web de FRED tiene notas e información útiles sobre cada conjunto de datos, cómo se registraron, qué representan los datos, si están o no ajustados estacionalmente, las unidades y escalas de las mediciones y otros detalles de esa naturaleza. Una vez que esté familiarizado con la naturaleza de los datos, puede pasar a recopilarlos mediante programación. Así pues, para nuestra primera demostración, los conjuntos de datos se descargaron manualmente del sitio web de la Reserva Federal de San Luis. Pasaremos al enfoque programático cuando estemos elaborando la estrategia.
Lo primero que vamos a hacer es recoger los datos de mercado de nuestro MetaTrader 5 utilizando un script MQL5, yo prefiero recoger los datos de esta manera porque puedes realizar cualquier preprocesamiento que necesites en el lado MQL5 donde tienes acceso ilimitado a los datos. Nuestro script es modestamente sencillo.
- Comenzamos declarando manejadores para nuestros indicadores técnicos, utilizaremos 4 medias móviles.
- Luego declaramos buffers para almacenar las lecturas de nuestras medias móviles, los buffers en nuestro caso son arrays dinámicos.
- A continuación, necesitamos un nombre para nuestro archivo, el nuestro será el nombre del par que estamos negociando seguido de la cadena "Market Data As Series", y tendrá formato CSV.
- A continuación, declaramos cuántos datos queremos recopilar.
- Tenga en cuenta que el script funciona con el marco temporal actual del gráfico al que se aplica.
- Hemos llegado a nuestro manejador de eventos OnStart(), aquí es donde se encuentra el corazón de nuestro script.
- Comenzamos inicializando los 4 indicadores técnicos.
- A continuación, copiamos los valores de los indicadores en las matrices que hemos creado anteriormente.
- Una vez hecho esto, creamos un manejador de archivos para crear, escribir y cerrar nuestro archivo.
- A continuación, utilizamos un simple bucle 'for' para recorrer las matrices y escribirlas en nuestro archivo CSV. Tenga en cuenta que en la primera iteración de nuestro bucle, escribimos las cabeceras de las columnas, después escribimos los valores reales que queremos.
- Una vez completado el bucle, cerramos nuestro fichero, utilizando el manejador de ficheros y ya estamos listos para fusionar los datos de nuestro terminal MetaTrader 5 con nuestros datos alternativos.
#property copyright "Gamuchirai Zororo Ndawana" #property link "https://www.mql5.com" #property version "1.00" //---Our handlers for our indicators int ma_handle_5; int ma_handle_15; int ma_handle_30; int ma_handle_150; //---Data structures to store the readings from our indicators double ma_reading_5[]; double ma_reading_15[]; double ma_reading_30[]; double ma_reading_150[]; //---File name string file_name = _Symbol + " " + " Market Data As Series.csv"; //---Amount of data requested int size = 1000000; int size_fetch = size + 100; void OnStart() { //---Setup our technical indicators ma_handle_5 = iMA(_Symbol,PERIOD_CURRENT,5,0,MODE_EMA,PRICE_CLOSE); ma_handle_15 = iMA(_Symbol,PERIOD_CURRENT,15,0,MODE_EMA,PRICE_CLOSE); ma_handle_30 = iMA(_Symbol,PERIOD_CURRENT,30,0,MODE_EMA,PRICE_CLOSE); ma_handle_150 = iMA(_Symbol,PERIOD_CURRENT,150,0,MODE_EMA,PRICE_CLOSE); //---Copy indicator values CopyBuffer(ma_handle_5,0,0,size_fetch,ma_reading_5); ArraySetAsSeries(ma_reading_5,true); CopyBuffer(ma_handle_15,0,0,size_fetch,ma_reading_15); ArraySetAsSeries(ma_reading_15,true); CopyBuffer(ma_handle_30,0,0,size_fetch,ma_reading_30); ArraySetAsSeries(ma_reading_30,true); CopyBuffer(ma_handle_150,0,0,size_fetch,ma_reading_150); ArraySetAsSeries(ma_reading_150,true); //---Write to file int file_handle=FileOpen(file_name,FILE_WRITE|FILE_ANSI|FILE_CSV,","); for(int i=-1;i<=size;i++){ if(i == -1){ FileWrite(file_handle,"Time","Open","High","Low","Close","MA 5","MA 15","MA 30","MA 150"); } else{ FileWrite(file_handle,iTime(_Symbol,PERIOD_CURRENT,i), iOpen(_Symbol,PERIOD_CURRENT,i), iHigh(_Symbol,PERIOD_CURRENT,i), iLow(_Symbol,PERIOD_CURRENT,i), iClose(_Symbol,PERIOD_CURRENT,i), ma_reading_5[i], ma_reading_15[i], ma_reading_30[i], ma_reading_150[i] ); } } } //+------------------------------------------------------------------+
Ahora estamos preparados para empezar a explorar nuestros datos alternativos junto con nuestros datos de mercado.
Como siempre, empezaremos por importar los paquetes necesarios.
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns
Ahora leemos los datos que exportamos de nuestro script MQL5.
GBPUSD = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\MetaQuotes\\Terminal\\NVUSDVJSNDU3483408FVKDL\\MQL5\\Files\\GBPUSD Market Data As Series.csv")
Al preparar los datos de mercado para el aprendizaje automático, asegúrese de que el precio de hoy es el último y el más antiguo el primero.
GBPUSD = GBPUSD[::-1]
A continuación, tenemos que restablecer el índice.
GBPUSD.reset_index(inplace=True)
Definamos con cuánta antelación queremos hacer la previsión.
look_ahead = 30 splits = 30
Ahora tenemos que preparar el objetivo.
GBPUSD["Target"] = GBPUSD["Close"].shift(-look_ahead) GBPUSD.dropna(inplace=True)
Ahora tenemos que hacer que la fecha sea el índice, esto nos ayudará a alinear fácilmente nuestros datos de mercado con nuestros datos alternativos más adelante.
GBPUSD["Time"] = pd.to_datetime(GBPUSD["Time"]) GBPUSD.set_index("Time",inplace=True)
El primer conjunto de datos alternativo que vamos a considerar es la media diaria del índice Sterling Overnight (SOIA, Sterling Overnight Index Average). Es un promedio de los tipos de interés que cobran los bancos por prestar libras esterlinas fuera del horario comercial habitual.
Si la media de los tipos de interés de la libra esterlina aumenta mientras que la media de los tipos de interés del dólar disminuye, esto podría indicar que la libra esterlina se está fortaleciendo frente al dólar a nivel institucional.
SOIA = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Downloads\\FED Data\\Daily Sterling Overnight Index Average\\IUDSOIA.csv")
Limpiemos los datos alternativos. Primero haz que la columna de fecha sea un objeto de fecha.
SOIA["DATE"] = pd.to_datetime(SOIA["DATE"])
Nuestro conjunto de datos contiene puntos, presumiblemente para representar la falta de observación. Sustituiremos todos los puntos por ceros y, a continuación, sustituiremos los ceros por el valor medio de la columna.
SOIA["IUDSOIA"] = SOIA["IUDSOIA"].replace(".","0") SOIA["IUDSOIA"] = pd.to_numeric(SOIA["IUDSOIA"]) non_zero_mean = SOIA.loc[SOIA['IUDSOIA'] != 0, 'IUDSOIA'].mean() SOIA['IUDSOIA'] = SOIA['IUDSOIA'].replace(0, non_zero_mean)
A continuación hacemos que la fecha sea el índice.
SOIA.set_index("DATE",inplace=True)
La siguiente fuente de datos alternativa que consideraremos será el Tipo de Financiación a un Día Garantizado (SOFR, Secured Overnight Financing Rate). Es el coste de los préstamos a un día garantizados, y lo publica diariamente el Banco de la Reserva Federal de Nueva York.
SOFR = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Downloads\\FED Data\\Secured Overnight Financing Rate\\SOFR.csv")
Tenga en cuenta que los pasos de preprocesamiento aplicados al conjunto de datos SOFR son idénticos a los aplicados al conjunto de datos SOIA, por lo que, para facilitar la lectura del artículo de principio a fin, omitiremos estos pasos.
Fusionemos ahora los 3 marcos de datos que tenemos. Al establecer 'left_index' y 'right_index' en 'true' nos aseguramos de que ambos conjuntos de datos se alinean sólo en los días en que tenemos observaciones completas para cada uno de ellos. Por ejemplo, el conjunto de datos GBPUSD no tiene registros durante el fin de semana, por lo que todos los puntos de datos alternativos observados durante el fin de semana no se incluyen en nuestro marco de datos fusionado final.
merged_df = SOIA.merge(SOFR,left_index=True,right_index=True) merged_df = merged_df.merge(GBPUSD,left_index=True,right_index=True)
A continuación, tenemos que restablecer nuestro índice.
merged_df.reset_index(inplace=True)
merged_df.drop(columns=["index"],inplace=True)
Definamos nuestros predictores.
normal_predictors = ['Open', 'High', 'Low', 'Close', 'MA 5', 'MA 15','MA 30', 'MA 150'] alternative_predictors = ['IUDSOIA', 'SOFR'] all_predictors = normal_predictors + alternative_predictors
A continuación, crearemos un marco de datos para almacenar los niveles de error de cada combinación de predictores.
accuracy = pd.DataFrame(columns=["Normal","Alternative","All"],index=np.arange(0,splits))
Este es el aspecto que tiene ahora nuestro marco de datos.
merged_df
Fig. 1: Nuestro conjunto de datos que contiene tanto nuestros datos normales como nuestros datos alternativos.
La primera columna es el tipo de interés medio de la libra esterlina, la segunda contiene el tipo de interés medio del dólar estadounidense. A partir de ahí, las siguientes columnas ya deberían resultarte familiares. Recuerde que el objetivo es el precio de cierre a 30 días vista.
Por último, exportaremos nuestro marco de datos fusionado a un archivo CSV para su uso posterior.
merged_df.to_csv('Alternative Data Target Look Ahead 30.csv')
Escalemos nuestros datos.
from sklearn.preprocessing import StandardScaler scaled_data = merged_df.loc[:,all_predictors] scaler = StandardScaler() scaler.fit(scaled_data) scaled_data = pd.DataFrame(scaler.transform(scaled_data),index=merged_df.index,columns=all_predictors)
Preparémonos ahora para entrenar nuestro modelo y ver si nuestros datos alternativos nos ayudan o nos frenan.
from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error from sklearn.model_selection import TimeSeriesSplit
Dividamos los datos en entrenamiento y prueba.
tscv = TimeSeriesSplit(gap=look_ahead+10,n_splits=splits)
for i,(train,test) in enumerate(tscv.split(merged_df)):
model = LinearRegression()
model.fit(scaled_data.loc[train[0]:train[-1],all_predictors],merged_df.loc[train[0]:train[-1],"Target"])
accuracy["All"][i] = mean_squared_error(merged_df.loc[test[0]:test[-1],"Target"],model.predict(scaled_data.loc[test[0]:test[-1],all_predictors]))
Ahora estamos graficando los resultados como diagramas de caja.
fig,axs = plt.subplots(1,3,sharex=True,sharey=True,figsize=(16,4)) for i,ax in enumerate(axs.flat): ax.boxplot(merged_df.iloc[:,i]) ax.set_title(accuracy.columns[i])
Fig. 2: Análisis de los valores de error obtenidos al utilizar datos normales (izquierda), datos alternativos (centro) y todos los datos disponibles (derecha).
Interpretemos los resultados: podemos ver claramente que tanto el conjunto normal de predictores como el conjunto alternativo de predictores tienen colas largas que llegan hasta la parte superior del gráfico. Sin embargo, el último gráfico, el que tiene tanto los predictores normales como los alternativos, tiene una forma aplastada. Esta forma aplastada es deseable porque muestra que cuando utilizamos ambos conjuntos de predictores juntos, obtenemos menos variación en nuestros errores. Nuestra precisión es estable en el último gráfico, pero en los dos primeros, en los que nos basamos totalmente en datos normales o en datos alternativos, nuestra precisión no es tan estable.
También podemos comprobar si existen efectos de interacción en nuestros datos. Crearemos un gráfico de dispersión con el objetivo en el eje Y y el tipo de interés de la libra esterlina en el eje X.
sns.scatterplot(x=merged_df["IUDSOIA"],y=merged_df["Target"])
Fig. 3: Análisis de la relación entre el tipo de interés aplicado a los Sterlings y el valor futuro del par GBPUSD.
He aquí una forma de interpretar este gráfico: cada línea que va desde la parte superior del gráfico hasta la parte inferior representa cómo cambia el objetivo cuando se fija el tipo de interés de la libra esterlina. El hecho de que podamos observar valores objetivo variables aunque el tipo de interés de la libra esterlina sea fijo es un indicio claro de la existencia de efectos de interacción en nuestros datos. Esto puede ser un indicador de que hay otras fuerzas poderosas en juego que influyen en el objetivo más allá de los datos alternativos que hemos recogido.
Técnicas de aprendizaje automático
La selección de una técnica de aprendizaje automático adecuada depende de la naturaleza de los datos de que se disponga. Considere lo siguiente:
- Tamaño del conjunto de datos: Para conjuntos de datos pequeños con menos de diez mil filas o menos de 30 columnas, es aconsejable emplear modelos más sencillos para mitigar el riesgo de sobreajuste. Los modelos complejos, como las redes neuronales profundas, pueden tener dificultades para aprender eficazmente con datos tan limitados.
- Ruido de datos: Los conjuntos de datos ruidosos, es decir, con puntos de datos que faltan o fluctuaciones aleatorias inexplicables, son más adecuados para modelos más sencillos. Los modelos complejos tienden a presentar una varianza elevada, por lo que es más probable que se ajusten en exceso a datos ruidosos y, además, en días de mercado especialmente ruidosos, puede que incluso estemos mejor sin ellos.
- Dimensionalidad de los datos: En los casos en los que el conjunto de datos tiene un elevado número de columnas, las técnicas de preprocesamiento pueden ser beneficiosas. Emplear modelos que sean eficaces en el manejo de datos de alta dimensión y aplicar la selección de características y la reducción de la dimensionalidad.
- Tamaño de los datos y potencia computacional: Si dispone de grandes conjuntos de datos con niveles de ruido aceptables y, además, tiene acceso a recursos computacionales suficientes, entonces puede estar justificado el uso de modelos sofisticados como las redes neuronales profundas. Estos modelos pueden captar con eficacia pautas y relaciones complejas dentro de los datos si se dispone de las capacidades informáticas adecuadas y de datos limpios.
A continuación le mostraremos cómo puede seleccionar un buen modelo para sus datos.
Empezaremos importando las bibliotecas que necesitamos.
import statistics as st import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from sklearn.linear_model import Lasso,Ridge,LinearRegression from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import TimeSeriesSplit from sklearn.metrics import mean_squared_error from sklearn.svm import SVR from sklearn.preprocessing import StandardScaler from xgboost import XGBRegressor
Ahora leeremos los datos del CSV que hemos exportado. El CSV contenía todos nuestros datos fusionados.
csv = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Alternative Data.csv")
Preparémonos para escalar los datos.
predictors = ['IUDSOIA', 'SOFR', 'Open', 'High', 'Low', 'Close'] target = 'Target' scaled_data = csv.loc[:,predictors] scaler = StandardScaler() scaler.fit(scaled_data) scaled_data = scaler.transform(scaled_data)
Entrenemos nuestros modelos.
splits = 10 gap = 30 models = ['Linear','Lasso','Ridge','Random Forest','Linear SVR','Sigmoid SVR','RBF SVR','2 Poly SVR','3 Poly SVR','XGB']
Prepararemos nuestra división de entrenamiento/prueba y luego crearemos un marco de datos para almacenar las métricas de error.
tscv = TimeSeriesSplit(n_splits=splits,gap=gap) error_df = pd.DataFrame(index=np.arange(0,splits),columns=models)
Ahora podemos observar las métricas de error de nuestro modelo.
for i,(train,test) in enumerate(tscv.split(csv)): model=XGBRegressor() model.fit(scaled_data.loc[train[0]:train[-1],predictors],csv.loc[train[0]:train[-1],target]) error_df.iloc[i,9] =mean_squared_error(csv.loc[test[0]:test[-1],target],model.predict(scaled_data.loc[test[0]:test[-1],predictors])) error_df
Fig. 4: Valores de error obtenidos de cada uno de los modelos ajustados.
Visualicemos algunos de los datos en forma de gráficos de caja.
fig , axs = plt.subplots(2,5,figsize=(20,20),sharex=True) for i,ax in enumerate(axs.flat): ax.boxplot(error_df.iloc[:,i]) ax.set_title(error_df.columns[i])
Fig. 5: Valores de error de algunos de los modelos lineales utilizados.
Fig. 6: Valores de error de algunos de los modelos no lineales utilizados.
Mostraremos algunas de las estadísticas resumidas obtenidas.
Variación | Error |
---|---|
Varianza lineal: 1.3365981802501968e-06 | Error cuadrático medio lineal: 0.0022242681292296462 |
Varianza de Lasso: 3.0466413126186177e-05 | Error cuadrático medio de Lasso: 0.004995731270431843 |
Varianza de cresta: 2.5678314939547713e-06 | Error cuadrático medio de la cresta: 0.002467126140156681 |
Varianza de Random Forest: 2.607918492340197e-06 | Error cuadrático medio de Random Forest: 0.002632579355696408 |
Varianza lineal SVR: 3.825627012092798e-05 | Error cuadrático medio SVR lineal: 0.004484702122899226 |
Varianza SVR sigmoidea: 27.654341711864102 | Error cuadrático medio de SVR sigmoide: 1.6693947903605928 |
Varianza RBF SVR: 4.1654658535332505e-05 | Error cuadrático medio RBF SVR: 0.004992333849448852 |
2 Varianza Poly SVR: 6.739873404310582e-05 | 2 Poly SVR error cuadrático medio: 0.008163708245600027 |
3 Varianza Poly SVR: 0.0005393054392191576 | 3 Poly SVR error cuadrático medio: 0.018431036676781344 |
Varianza XGB: 7.053078880392137e-06 | Error cuadrático medio XGB: 0.003163819414983548 |
Obsérvese que ninguno de los modelos tiene un rendimiento sobresaliente, sino que todos se encuentran más o menos dentro de la misma banda de rendimiento. En tales circunstancias, el modelo más sencillo puede ser la mejor opción porque es menos probable que se ajuste en exceso. Por lo tanto, en este ejemplo utilizaremos la regresión lineal como modelo de elección para nuestra estrategia de negociación. Optamos por él porque su nivel de error es tan bueno como el de cualquier otro modelo que hubiéramos podido elegir y, además, su varianza es baja. Por tanto, es menos probable que el modelo lineal se ajuste en exceso y más probable que sea estable a lo largo del tiempo.
Construir la estrategia
Ahora estamos listos para aplicar todo lo que hemos discutido en las secciones anteriores en una estrategia comercial robusta utilizando la biblioteca de MetaTrader 5 para Python.Se darán explicaciones en cada paso del camino para garantizar que todo el código sea fácil de seguir.
Primero importamos los paquetes que necesitamos.
from fredapi import Fred import MetaTrader5 as mt5 import pandas as pd import numpy as np import time from datetime import datetime import matplotlib.pyplot as plt
El paquete 'fredapi' nos permite extraer datos mediante programación de la base de datos FRED. Sin embargo, antes de poder utilizar la biblioteca, debe crear una clave API. Las claves API son gratuitas, pero solo puedes obtener una después de crear una cuenta de usuario gratuita en la Reserva Federal de St. Louis.
Ahora definiremos las variables globales.
LOGIN = ENTER_YOUR_LOGIN PASSWORD = 'ENTER_YOUR_PASSWORD' SERVER = 'ENTER_YOUR_SERVER' SYMBOL = 'GBPUSD' TIMEFRAME = mt5.TIMEFRAME_D1 DEVIATION = 1000 VOLUME = 0 LOT_MULTIPLE = 1 FRED = Fred(api_key='ENTER_YOUR_API_KEY')
Ahora iniciaremos sesión en nuestra cuenta de operaciones.
if mt5.initialize(login=LOGIN,password=PASSWORD,server=SERVER): print('Logged in successfully') else: print('Failed To Log in')
Conectado correctamente
Let's define our trading volume.
for index,symbol in enumerate(mt5.symbols_get()): if symbol.name == SYMBOL: print(f"{symbol.name} has minimum volume: {symbol.volume_min}") VOLUME = symbol.volume_min * LOT_MULTIPLE
GBPUSD tiene un volumen mínimo: 0.01
Vamos a definir las funciones que vamos a utilizar a lo largo de nuestro programa.
Primero necesitamos una función para obtener el precio actual del mercado desde nuestro terminal MetaTrader 5.
def get_prices(): start = datetime(2024,3,20) end = datetime.now() data = pd.DataFrame(mt5.copy_rates_range(SYMBOL,TIMEFRAME,start,end)) data['time'] = pd.to_datetime(data['time'],unit='s') data.set_index('time',inplace=True) return(data.iloc[-1,:])
Ahora necesitamos una función para solicitar datos alternativos a la Reserva Federal de St. Louis.
def get_alternative_data(): SOFR = FRED.get_series_as_of_date('SOFR',datetime.now()) SOFR = SOFR.iloc[-1,-1] SOIA = FRED.get_series_as_of_date('IUDSOIA',datetime.now()) SOIA = SOIA.iloc[-1,-1] return(SOFR,SOIA)
A continuación, necesitamos una función que prepare las entradas para nuestro modelo.
def get_model_inputs(): LAST_OHLC = get_prices() SOFR , SOIA = get_alternative_data() MODEL_INPUT_DF = pd.DataFrame(index=np.arange(0,1),columns=predictors) MODEL_INPUT_DF['Open'] = LAST_OHLC['open'] MODEL_INPUT_DF['High'] = LAST_OHLC['high'] MODEL_INPUT_DF['Low'] = LAST_OHLC['low'] MODEL_INPUT_DF['Close'] = LAST_OHLC['close'] MODEL_INPUT_DF['IUDSOIA'] = SOIA MODEL_INPUT_DF['SOFR'] = SOFR model_input_array = np.array([[MODEL_INPUT_DF.iloc[0,0],MODEL_INPUT_DF.iloc[0,1],MODEL_INPUT_DF.iloc[0,2],MODEL_INPUT_DF.iloc[0,3],MODEL_INPUT_DF.iloc[0,4],MODEL_INPUT_DF.iloc[0,5]]]) return(model_input_array,MODEL_INPUT_DF.loc[0,'Close'])
Entonces necesitamos una función que nos ayude a hacer una previsión utilizando nuestro modelo.
def ai_forecast(): model_inputs,current_price = get_model_inputs() prediction = model.predict(model_inputs) return(prediction[0],current_price)
Entrenemos nuestro modelo.
training_data = pd.read_csv('C:\\Enter\\Your\\Path\\Here\\Alternative Data.csv')
Configuración de nuestro modelo.
from sklearn.linear_model import LinearRegression model = LinearRegression()
Definir nuestros predictores y nuestro objetivo.
predictors = ['Open','High','Low','Close','IUDSOIA','SOFR'] target = 'Target'
Ajuste de nuestro modelo.
model.fit(training_data.loc[:,predictors],training_data.loc[:,target])
Ahora hemos llegado al corazón de nuestro algoritmo de negociación:
- Primero definimos un bucle infinito para mantener nuestra estrategia en marcha.
- A continuación, obtenemos los datos actuales del mercado y los utilizamos para realizar una previsión.
- Después tendremos banderas booleanas para representar las expectativas de nuestro modelo. Si nuestro modelo espera que el precio suba, 'BUY_STATE' es 'true', de lo contrario, si nuestro modelo espera que el precio baje, 'SELL_STATE' es 'false'.
- Si no tenemos posiciones abiertas, seguiremos la previsión de nuestro modelo.
- Si tenemos posiciones abiertas, comprobaremos si la previsión de nuestro modelo va en contra de nuestra posición abierta. Si lo es, entonces cerraremos la posición. De lo contrario, podemos dejar el puesto vacante.
- Por último, una vez completados todos los pasos anteriores, pondremos el algoritmo a dormir durante un día y recuperaremos los datos actualizados al día siguiente.
while True: #Get data on the current state of our terminal and our portfolio positions = mt5.positions_total() forecast , current_price = ai_forecast() BUY_STATE , SELL_STATE = False , False #Interpret the model's forecast if(current_price > forecast): SELL_STATE = True BUY_STATE = False elif(current_price > forecast): SELL_STATE = False BUY_STATE = True print(f"Current price is {current_price} , our forecast is {forecast}") #If we have no open positions let's open them if(positions == 0): print(f"We have {positions} open trade(s)") if(SELL_STATE): print("Opening a sell position") mt5.Sell(SYMBOL,VOLUME) elif(BUY_STATE): print("Opening a buy position") mt5.Buy(SYMBOL,VOLUME) #If we have open positions let's manage them if(positions > 0): print(f"We have {positions} open trade(s)") for pos in mt5.positions_get(): if(pos.type == 1): if(BUY_STATE): print("Closing all sell positions") mt5.Close(SYMBOL) if(pos.type == 0): if(SELL_STATE): print("Closing all buy positions") mt5.Close(SYMBOL) #If we have finished all checks then we can wait for one day before checking our positions again time.sleep(24 * 60 * 60)
Fig. 7: Nuestra operación el primer día que la abrimos.
Fig. 8: Nuestra operación del día siguiente.
Conclusión
Los datos alternativos tienen un enorme potencial para cambiar nuestra forma de ver los mercados financieros. Si elegimos con cuidado las fuentes de datos adecuadas, es posible que nos encontremos en el lado correcto de la mayoría de las operaciones en las que participamos. El componente más importante de esta estrategia es disponer de una fuente fiable de datos alternativos; de lo contrario, da igual que utilices datos normales. Tómese su tiempo e investigue por su cuenta, llegue a sus propias conclusiones y siga su instinto. Recuerde que, al fin y al cabo, crear estrategias es tanto una ciencia como un arte. Por lo tanto, aplica tu capacidad de razonamiento con criterio a la hora de seleccionar qué fuentes de datos alternativas serían útiles y, además, deja que tu imaginación encuentre aplicaciones y casos de uso novedosos en los que la mayoría de la gente no pensaría, y estarás en una liga propia.
Recomendaciones
A los futuros lectores les puede resultar provechoso buscar más fuentes de conjuntos de datos alternativos y utilizar técnicas de aprendizaje automático, como la selección del mejor subconjunto, para escoger fuentes útiles de datos alternativos. Además, recuerde que el modelo lineal que utilizamos en nuestra demostración hace fuertes suposiciones sobre el proceso que generó los datos, si estas suposiciones se violan entonces la precisión de nuestro modelo se deteriorará con el tiempo.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/14441
- 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