![Comercio algorítmico con MetaTrader 5 y R para principiantes](https://c.mql5.com/2/64/Algorithmic_Trading_With_MetaTrader_5_And_R_For_Beginners_600x314.jpg)
Comercio algorítmico con MetaTrader 5 y R para principiantes
Introducción
MetaTrader es un referente mundial en el ámbito de las plataformas de negociación. Reconocido por su calidad industrial, este software se ofrece gratuitamente, lo que lo hace accesible a un amplio espectro de usuarios. En consecuencia, la comunidad MetaTrader ha sido testigo de un crecimiento constante año tras año. La comunidad, ahora más diversa que nunca en su historia, está formada por personas de orígenes culturales variados y con distintos conocimientos de lenguajes de programación. Cabe destacar que, junto con MetaQuotes Language 5 (el lenguaje oficial de la plataforma), Python es el único lenguaje de programación totalmente compatible con la plataforma MetaTrader.
Para los miembros de la comunidad en transición desde R, independientemente de su experiencia en el mundo académico o la computación científica, la comunidad MetaQuotes le da la bienvenida con los brazos abiertos. A pesar de los avances en Python, y la integración exclusiva de Python como el único otro lenguaje totalmente compatible con el terminal MetaTrader, las personas que dominan R no tienen por qué percibir sus conocimientos de programación como obsoletos. Este artículo desafía cualquier noción que sugiera obsolescencia al ilustrar que, con la aplicación de la creatividad y un poco de ingenio, sigue siendo totalmente factible construir un asesor de trading algorítmico completo utilizando R y MetaTrader 5.
Es imperativo notar, basado en la experiencia del autor, que los paquetes discutidos en este artículo exhiben interacciones imperfectas cuando se emplean individualmente dentro de la Terminal MetaTrader 5. Cada paquete presenta sus propias limitaciones. Sin embargo, cuando se emplean al unísono, estos paquetes compensan eficazmente las deficiencias de los demás, formando colectivamente un marco sólido propicio para el desarrollo de algoritmos de negociación utilizando R y MetaTrader.
Tenga en cuenta lo siguiente:
1. Consideración del sistema operativo:
Esta demostración se llevó a cabo en un equipo con Windows 11 OS Build 22621.1848. Estos pasos no se han probado en sistemas operativos alternativos.
2. Compatibilidad con la versión R:
Esta demostración utiliza la versión 4.3.2 de R. Es imprescindible que los participantes utilicen la misma versión de R, dado que algunos paquetes que se presentan en esta ponencia no son compatibles con versiones anteriores del lenguaje R.
3. Integración de RStudio:
Esta demostración se integra con RStudio, un sofisticado entorno de desarrollo integrado diseñado para escribir código R. Se recomienda a los participantes que utilicen RStudio para una experiencia de codificación óptima durante el transcurso de esta demostración.
Configuración del entorno
Lo primero es lo primero: vamos a configurar nuestro entorno.
Empieza por asegurarte de que tienes la versión 4.3.2 de R en tu ordenador. Si no estás seguro o no tienes R instalado, seguiremos los pasos juntos.
Para comprobar si R está instalado, busque el icono R en su escritorio. Si no está ahí, puedes buscar "R" - eso debería hacer aparecer el terminal R si ya está instalado. Si necesita instalar R o tiene una versión anterior, puede obtener la configuración del repositorio oficial de R en The Comprehensive R Archive Network. Este enlace le llevará siempre a la última versión de R, que ahora es la 4.3.2. Una vez descargado el archivo de instalación, sólo tienes que seguir las instrucciones que aparecen, empezando por elegir tu idioma.
Ahora que tienes R instalado, vamos a confirmar la versión que estás ejecutando. Abra el terminal R, y verá la versión mostrada en la parte superior del mensaje de bienvenida cada vez que inicie una nueva sesión. Si quieres información más detallada, siempre puedes utilizar el comando "versión" en el terminal.
Fig 1: Comprobación de la versión de R
Ahora, vamos a configurar RStudio. Si no tienes RStudio instalado, puedes descargarlo desde este enlace: RStudio Desktop - Posit. Sólo tienes que seguir las instrucciones que aparecen en pantalla, de forma similar al proceso de configuración de R del que hemos hablado antes.
Una vez completada la instalación, vamos a validar la versión de R a la que apunta tu instalación de R studio.
Primero abre R Studio.
A continuación, selecciona “tools” y “global options”.
Fig 2: Comprobación de la versión de R que se está ejecutando en RStudio
Desde allí verá la versión de R que está ejecutando.
Si tiene dos o más versiones de R instaladas en su máquina, la versión 4.3.2 que instalamos juntos y cualquier versión que ya tuviera antes, haga clic en "cambiar".
Fig 3: Comprobación de la versión de R que se está ejecutando en RStudio
Desde allí, seleccione "choose a specific version of R" (elegir una versión específica de R), y seleccione la versión 4.3.2, luego haga clic en "OK" y reinicie RStudio para que los cambios surtan efecto.
Fig 4: Elección de una versión diferente de R
Una vez que haya reiniciado RStudio tenemos que instalar algunas dependencias.
#Algorithmic Trading With RStudio And MetaTrader 5 #Gamuchirai Zororo Ndawana #This script will help you get your environment setup and test that everything is working fine #Sunday 17 December 2023 #Installing Dependencies install.packages("stringi") #This package is a dependency for devtools install.packages("devtools") #We will use this package to install R packages hosted on github install.packages("xts") #We will use this package to plot data fetched from the MetaTrader 5 Terminal install.packages("quantmod") #We will use this package to plot data fetched from the MetaTrader 5 Terminal install.packages("ttr") #We will use this package to calculate technical indicator values install.packages("reticulate") #We will use this package to call Python libraries in R devtools::install_github("Kinzel/mt5R") #We will use this open source package to interact with the MetaTrader 5 Terminal
Empecemos importando la primera librería, que es "reticulate". Esta librería nos permite ejecutar código Python dentro de R. Utilizaremos "reticulate" para instalar la librería de Python para MT5 en un entorno virtual. Una vez instalada la librería MT5, podemos utilizar "reticulate" como puente entre nuestra sesión de RStudio y el entorno virtual de Python. Esta conexión intermediaria nos permite enviar órdenes a nuestro terminal MetaTrader 5, facilitando la ejecución de las operaciones.
Empezamos cargando la biblioteca "reticulate".
#Libraries #Importing reticulate library(reticulate)A continuación, crearemos un entorno virtual utilizando la función `virtualenv_create()` de la biblioteca "reticulate". Esta función toma un parámetro de cadena, que representa el nombre de nuestro entorno virtual. En programación, los entornos virtuales ofrecen un método para construir espacios aislados y autónomos para proyectos individuales. La razón fundamental para emplear entornos virtuales es gestionar eficazmente las dependencias, mitigar los conflictos y mantener la reproducibilidad del proyecto. Esto resulta especialmente importante cuando varios proyectos o paquetes comparten dependencias comunes pero necesitan versiones diferentes de las mismas dependencias.
#Create a virtual environment virtualenv_create("rstudio-metatrader5")
Una vez establecido el entorno virtual, el siguiente paso es activarlo y utilizarlo. Esto se consigue empleando la función `use_virtualenv()` dentro de la librería "reticulate". La activación del entorno virtual garantiza que las operaciones posteriores con Python se ejecuten en el contexto aislado de este entorno, lo que nos permite gestionar dependencias y configuraciones específicas de nuestro proyecto.
#Use the virtual environemnt use_virtualenv("rstudio-metatrader5")
Avanzando, vamos a instalar la librería Python de MetaTrader 5 utilizando la función `py_install()` dentro de la librería "reticulate". Proporcionamos a la función el nombre de la librería que pretendemos instalar, que, en este caso, es "MetaTrader5".
#Install metatrader5 python library py_install("MetaTrader5")
Después de instalar la librería, el siguiente paso consiste en importar la librería "MetaTrader5" y almacenarla en una variable llamada `MT5`. Para ello se utiliza la función `import()` de la biblioteca "reticulate". La variable `MT5` nos servirá como interfaz para interactuar con la librería MetaTrader 5 en pasos posteriores.
#Import MetaTrader 5 MT5 <- import("MetaTrader5")
Antes de continuar, asegúrese de que el terminal MetaTrader 5 no se está ejecutando en ese momento. Si está en marcha, por favor, ciérrelo.
Ahora vamos a lanzar el Terminal MetaTrader 5 directamente desde nuestra sesión de RStudio. Podemos conseguirlo invocando la función `initialize` de la librería Python "MetaTrader5". Si la inicialización tiene éxito, la función devolverá "TRUE", indicando que el terminal MetaTrader 5 ha sido lanzado con éxito.
#Initialize the MetaTrader 5 Terminal MT5$initialize()
[1] TRUE
Aunque tenemos la capacidad de acceder a la información de la cuenta, los detalles del terminal y los detalles de los símbolos, nos encontramos con nuestra primera limitación: la imposibilidad de iniciar sesión mediante programación en una cuenta diferente. La cuenta que está activa durante la inicialización del terminal se convierte en la única cuenta accesible a menos que el usuario la cambie manualmente. Si bien es factible crear un script en Python para iniciar sesión en una cuenta diferente utilizando las bibliotecas de MetaTrader 5 y ejecutarlas desde R utilizando "reticulate", este artículo asume que los lectores poseen sólo conocimientos de programación en R junto con una comprensión básica de la programación MQL5.
La siguiente limitación gira en torno a la imposibilidad de solicitar información histórica sobre precios mediante reticulado. Esta restricción puede deberse a que "reticulate" convierte automáticamente los tipos de datos entre bastidores cuando los objetos pasan de R a Python. En consecuencia, parece encontrar dificultades para manejar el objeto devuelto cuando solicita datos históricos de precios al terminal. Aquí es donde hacemos uso de un segundo paquete para parchear las carencias de "reticulate".
#Get account information
account_info <- MT5$account_info()
#Print account information
account_info$company
account_info$balance
account_info$name
#Get terminal information
terminal_info <- MT5$terminal_info()
terminal_info$build
terminal_info$company
terminal_info$name
[1]"Deriv.com Limited"
[1]868.51
[1]"Gamuchirai Ndawana"
[1]4094
[1]"MetaQuotes Software Corp."
[1]"MetaTrader 5"
#Requesting price data price_data <- MT5$copy_rates_from_pos("Boom 1000 Index",MT5$TIMEFRAME_M1,0,10)
Error in py_call_impl(callable, call_args$unnamed, call_args$named) :
SystemError: <built-in function copy_rates_from_pos> returned a result with an exception set
Run `reticulate::py_last_error()` for details.
Utilizaremos MT5R para resolver estos problemas. Pero primero entendamos cómo funciona MT5R bajo el capó.
El paquete MT5R establece una conexión WebSocket entre RStudio y el terminal MetaTrader 5 creando un canal de comunicación full-duplex. En un sistema full-duplex, los datos pueden enviarse y recibirse simultáneamente. Para que este canal sea efectivo, el terminal MetaTrader 5 necesita estar escuchando en un puerto específico, que utilizaremos para transmitir instrucciones. Además, debe comunicarse con nuestra sesión de RStudio en el mismo puerto. Afortunadamente, MT5R incluye un asesor experto escrito en MetaQuotes Language 5 (MQL5) que escucha nuestras órdenes. Este asesor es de código abierto, lo que proporciona flexibilidad para incorporar funcionalidades adicionales si es necesario. Además, si desea el código fuente puede descargarlo aquí. Por favor, ten en cuenta que hemos adjuntado una versión personalizada del asesor experto junto con el artículo. Nuestra versión personalizada incluye una función adicional para colocar automáticamente Stop Loss dinámicos (Trailing Stop) y tomar ganancias (Take Profit).
Fig 5: Diagrama MT5R
Una vez que haya descargado el asesor experto debe colocarlo junto los archivos de sus otros asesores expertos. Simplemente abra su terminal MetaTrader 5, pulse "Archivo" y luego "Abrir carpeta de datos".
Fig 6: Encontrar la carpeta de datos
A continuación, vaya a "\MQL5\experts\" y coloque el Asesor en su carpeta de expertos. Una vez completado, abra el símbolo que desea operar y coloque el asesor experto MT5R en el gráfico. Su ordenador puede preguntarle si desea conceder permiso para permitir que MetaTrader 5 pueda hacer uso de la red. Concédale permiso. Una vez hecho esto, estamos listos para volver a RStudio y seguir construyendo nuestro algoritmo de negociación.
Abra RStudio e importe la biblioteca MT5R, xts y quantmod.
#Import the MT5R Library library(mt5R) #Import xts to help us plot library(xts) #Import quantmod to help us plot library(quantmod)
A continuación, comprobamos si se ha establecido la conexión con el terminal mediante la función Ping() del paquete MT5R. La función devuelve TRUE si ha podido comunicarse con el asesor experto.
#Check if our connection is established MT5.Ping() #Global variables MARKET_SYMBOL <- "Volatility 75 Index"
[1] TRUE
MT5R no aborda el problema de inicio de sesión que hemos discutido anteriormente, sin embargo, sí aborda la cuestión de la solicitud de datos de precios.
Para solicitar datos de precios desde nuestro terminal MetaTrader 5 llamamos a la función GetSymbol de nuestra librería MT5R. La función espera el nombre del símbolo, seguido del marco temporal en minutos, por lo que los datos diarios serían 1440, y por último el número de filas. Los datos se devuelven con los datos más antiguos en la parte superior y el precio actual en la parte inferior.
Tenga en cuenta que hemos establecido el parámetro xts en true. Esto convertirá el marco de datos en un objeto de serie temporal de R y formateará automáticamente las fechas de su gráfico entre bastidores. También nos permite añadir fácilmente valores de indicadores técnicos a nuestro marco de datos.
#Request historical price data price_data <- MT5.GetSymbol(MARKET_SYMBOL, iTF = 1, iRows=5000,xts = TRUE)Podemos trazar fácilmente los datos de precios utilizando una función de quantmod llamada lineChart()
#Plotting a line chart
lineChart(price_data, name = MARKET_SYMBOL)
Fig 7: Trazado de datos de precios en RStudio
También podemos añadir indicadores técnicos a nuestro gráfico utilizando la función addIndicator en quantmod, por ejemplo añadiremos un RSI (Relative Strength Index / Índice de fuerza relativa) de 60 periodos a nuestro gráfico.
#We can also add technical indicators to the plot
addRSI(n=60)
Fig 8: Añadir indicadores técnicos a nuestro gráfico
Tratamiento de sus datos
Cuando añadimos el indicador RSI y el Aroon, sólo los añadimos al gráfico, para añadir valores de indicadores técnicos a nuestro marco de datos, debemos llamar al indicador desde el paquete quantmod y luego pasarle las columnas correspondientes necesarias para los cálculos. Las columnas correspondientes se especifican en la documentación, en este ejemplo añadiremos una media móvil simple de 20 periodos, un RSI de 20 periodos y un indicador ATR (Average True Range / Rango medio verdadero) de 20 periodos al marco de datos.
#Add moving average price_data$SMA_20 <- SMA(price_data$Close,n = 20) #Add RSI to the dataframe price_data$RSI_20 <- RSI(price_data$Close,n=20) #Add ATR to the dataframe price_data$ATR_20 <- ATR(price_data[,c("High","Low","Close")], n=20)
Una vez hecho esto, eliminaremos todas las filas con valores perdidos.
#Drop missing values
price_data <- na.omit(price_data)
Añadiremos una función llamada "next close" (próximo cierre) que contiene el precio del próximo cierre. Si el próximo cierre es mayor que el cierre nuestro objetivo será uno, de lo contrario cero. Para ello se utiliza la función "if else" de R.
#Next close price price_data$Next_Close <- lag(price_data$Close,-1) #Setting up our target price_data$Target <- ifelse( ( (price_data$Next_Close) > price_data$Close) , 1 , 0)
Después estamos listos para realizar nuestra división de entrenamiento y prueba. Utilizaremos las primeras 4000 filas para el entrenamiento y el resto para las pruebas. Cuando trabajamos con datos de series temporales, evitamos las prácticas de división aleatoria para evitar la fuga de datos, una situación en la que el modelo aprende involuntariamente de la información futura para predecir el pasado. En su lugar, damos prioridad al mantenimiento del orden temporal natural de los datos. En la práctica, seleccionamos las 4000 filas iniciales en su secuencia cronológica y seguimos con las filas restantes. Este enfoque garantiza que nuestro modelo aprenda de los datos pasados para predecir el futuro, manteniendo las mejores prácticas en el análisis de series temporales.
#Train test split train_set <- price_data[1:4000,] train_y <- price_data[1:4000,c("Target")] test_set <- price_data[4001:4980,] test_y <- price_data[4001:4980,c("Target")]
Ahora que hemos dividido nuestros datos en conjuntos de entrenamiento y de prueba, el siguiente paso es entrenar el modelo elegido. En este caso, optamos por el análisis discriminante cuadrático (QDA, Quadratic Discriminant Analysis). QDA está orientado a maximizar la distinción entre dos clases, lo que facilita una clasificación más eficaz de los datos. Para ello, maximiza la separación entre las medias de las dos clases y minimiza la dispersión respecto a la media dentro de cada clase. Para aplicar QDA utilizamos la biblioteca MASS que alberga el modelo QDA. Por lo tanto, importamos la biblioteca MASS para acceder al modelo QDA y emplearlo en nuestro análisis.
#Fitting models library(MASS) #Quadratic Discriminant Analysis #Using OHLC Data qda <- qda(Target ~ Open+High+Low+Close,data = train_set) qda
Call:
qda(Target ~ Open + High + Low + Close, data = train_set)
Prior probabilities of groups:
0 1
0.49925 0.50075
Group means:
Open High Low Close
0 365424.6 365677.8 365159.9 365420.5
1 365125.4 365384.0 364866.6 365131.4
Podemos ver en la matriz de confusión que nuestro modelo predice mejor los movimientos alcistas que los bajistas del mercado.
#Evaluating model performance #Custom Quadratic Discriminant Analysis qda_predictionts <- predict(qda,test_set) qda_predictionts <- qda_predictionts$class #Confusion matrix table(qda_predictionts,test_y)
Fig 9: Matriz de confusión
Implementación de la lógica de negociación
Hemos llegado a la esencia fundamental de nuestro algoritmo de negociación, donde el imperativo inicial es el establecimiento de una variable designada como last_trade. Esta variable adquiere importancia, ya que cumple la función fundamental de controlar la última operación iniciada. Su importancia radica en facilitar el cierre oportuno de posiciones cuando nuestro modelo predice un movimiento adverso del mercado que podría socavar potencialmente nuestra exposición global al mercado. Es pertinente recordar nuestro sencillo sistema de codificación, en el que un valor de 1 significa una compra (BUY), mientras que un valor de 0 denota una venta (SELL).
#Keeping track of the last trade last_trade <- -1
Al poner en práctica nuestro algoritmo, es imperativo iniciar un bucle infinito, dentro del cual se anida intrincadamente nuestra lógica de negociación. Este bucle perpetuo se consigue mediante la incorporación de una función de tiempo de espera, regulando así la frecuencia de las iteraciones. Alineados con la generación de nuevas velas, aspiramos a ciclos de iteración sincrónicos. La integración de la función Sys.sleep garantiza que nuestras acciones de negociación se ajusten al ritmo de los cambios del mercado minuto a minuto.
Nuestro primer paso es obtener información actual sobre el mercado.
A continuación, pasamos los datos a nuestro modelo y obtenemos una previsión.
Una vez que nuestro modelo ha realizado una previsión, comprobamos si tenemos alguna posición abierta utilizando el paquete MT5 que instalamos con "reticulate". Si no tenemos posiciones abiertas, entonces procedemos a abrir una posición en la dirección de la previsión del mercado y luego actualizamos nuestra variable last_trade.
De lo contrario, si tenemos una posición abierta, comprobaremos si nuestro modelo prevé un movimiento adverso contra ella y, en caso afirmativo, cerraremos la posición.
Por último, tenemos que añadir un tiempo de espera para que nuestro algoritmo compruebe nuestra posición una vez cada barra.
while(TRUE){ #Fetching current market data print("Fetching market information") data <- MT5.GetSymbol(MARKET_SYMBOL,iTF=1, iRows = 2) data <- data[1,] #Forecasting market move qda_forecast <- predict(qda,data) qda_forecast <- qda_forecast$class print("Model forecast: ") print(qda_forecast) #Checking if we have no open positions current_positions <- MT5$positions_total() #If we have no open positions, open a position following the model forecast if(current_positions == 0){ print("We have no open positions. Opening a new position") #A Forecast of 1 means buy if(qda_forecast == 1){ print("Opening Buy Position") MT5$Buy(MARKET_SYMBOL,symbol_info$volume_min) last_trade <- 1 } #A Forecast of 0 means sell if (qda_forecast == 0){ print("Opening Sell Position") MT5$Sell(MARKET_SYMBOL,symbol_info$volume_min) last_trade <- 0 } } else{ #Are we anticipating a move against our open position? if(last_trade != qda_forecast){ #If we are, let's close our position print("Closing open position") MT5$Close(MARKET_SYMBOL) #Reset last trade last_trade <- -1 } else{ #Otherwise everything is expected to be fine print("The current position is aligned with the market") info <- MT5$account_info() print("Current Profit") print(info$profit) } } #Wait for a new candle to form Sys.sleep(60) }
Fig 10: Modelo de análisis discriminante cuadrático (QDA, Quadratic Discriminant Analysis) en R operando en MetaTrader 5 en tiempo real.
Conclusión
En conclusión, a pesar de los desafíos encontrados en el desarrollo de un algoritmo de negociación en tiempo real utilizando R y MetaTrader 5, este artículo demuestra que la tarea es más accesible de lo que puede parecer inicialmente. Incluso las personas con conocimientos básicos de R pueden lograr avances significativos. Las limitaciones de los paquetes individuales se mitigan eficazmente con paquetes complementarios y, sobre todo, el enfoque adoptado minimiza las dependencias. En general, presenta un marco viable y robusto accesible a cualquier usuario de R.
Además, una versión personalizada del asesor experto MT5R, que se adjunta al presente documento, está diseñada para incorporar de forma autónoma Trailing Stop y Take Profit, ayudando en la gestión de las operaciones. Se anima a los usuarios a mejorar su funcionalidad según sea necesario. Les deseo paz, prosperidad y operaciones rentables hasta que nuestros caminos vuelvan a cruzarse.
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/13941
![Técnicas del Asistente MQL5 (MQL5 Wizard) que debe conocer (Parte 10). El RBM no convencional](https://c.mql5.com/2/64/MQL5_Wizard_Techniques_you_should_know_cPart_10e_The_Unconventional_RBM___LOGO.png)
![Trailing stop en el trading](https://c.mql5.com/2/67/Trailing_stop_in_trading___LOGO.png)
![Marcado de datos en el análisis de series temporales (Parte 6): Aplicación y prueba en EA utilizando ONNX](https://c.mql5.com/2/64/Data_label_for_time_series_mining_1Part_60_Apply_and_Test_in_EA_Using_ONNX____LOGO.png)
![Ciencia de datos y aprendizaje automático (Parte 18): La batalla de dominar la complejidad del mercado, SVD truncado frente a NMF](https://c.mql5.com/2/64/Data_Science_and_Machine_Learning_pPart_183_Truncated_SVD_Versus_NMF__LOGO.png)
![MQL5 - Lenguaje de estrategias comerciales para el terminal de cliente MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- 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