![Lite_EXPERT2.mqh: Ejemplos de implementación de Asesores Expertos](https://c.mql5.com/i/articles/overlay.png)
Lite_EXPERT2.mqh: Ejemplos de implementación de Asesores Expertos
Introducción
En mi artículo anterior "Lite_EXPERT2.mqh: Un conjunto operativo para los desarrolladores de Asesores Expertos", he familiarizado los lectores con las funciones de Lite_EXPERT2.mqh. En este artículo, voy a proporcionar ejemplos reales de implementación de Asesores Expertos que usan estas funciones. Creo que el funcionamiento de las funciones de trading
OpenBuyOrder1_() OpenSellOrder1_() OpenBuyOrder2_() OpenSellOrder2_() OpenBuyLimitOrder1_() OpenBuyStopOrder1_() OpenSellLimitOrder1_() OpenSellStopOrder1_() Make_BuyTrailingStop_() Make_SellTrailingStop_()
no es muy distinto al de las funciones similares del archivo Lite_EXPERT1.mqh.
La inicialización de las variables externas adicionales no puede crear ninguna confusión (ver Exp_0_1.mq4 y Exp_0.mq4, Exp_1.mq4 y EXP_1_1.mq4). Así que no hace falta volver a este punto. Voy a pasar directamente a los ejemplos implementados mediante las funciones de trading que utilizan los valores absolutos de los niveles del gráfico de precios como variables externas para las órdenes pendientes.
ddOpenBuyOrder1_() dOpenSellOrder1_() dOpenBuyOrder2_() dOpenSellOrder2_() dOpenBuyLimitOrder1_() dOpenBuyStopOrder1_() dOpenSellLimitOrder1_() dOpenSellStopOrder1_() dModifyOpenBuyOrder_() dModifyOpenSellOrder_() dModifyOpenBuyOrderS() dModifyOpenSellOrderS() dMake_BuyTrailingStop_() dMake_SellTrailingStop_()
Voy a comenzar este artículo con el indicador Average True Range (rango verdadero medio), en el cual están basadas las estrategias de trading que vamos a ver más adelante.
El uso del indicador Average True Range en los sistemas de trading automatizado
El indicador Average True Range (en adelante, ATR o rango verdadero medio) fue desarrollado por Welles Wilder y se menciona por primera vez en su libro "New Concepts in Technical Trading Systems" (Nuevos conceptos en los sistemas técnicos de trading) en 1978. Posteriormente, este indicador se hizo muy famoso y se incluye todavía en muchos paquetes de programas de análisis técnico. El indicador ATR en sí no indica la dirección de la tendencia actual, pero proporciona una imagen gráfica de la volatilidad o actividad del mercado.
En general, existen dos maneras de utilizar este indicador en los sistemas de trading automatizado:
1. Filtrar las señales del sistema de trading para identificar las condiciones de presencia de tendencia o no en el mercado.
En este caso, la dirección de la tendencia y las señales de entrada proceden de otro indicador, mientras que el indicador ATR sólo proporciona una condición adicional de entrada. Esta condición puede ser, por ejemplo, la ruptura del valor promedio del indicador por el propio indicador. Para obtener el valor promedio del indicador ATR, se recomienda utilizar la línea del promedio de la señal basada en ATR.
2. Órdenes pendientes adaptativas.
El valor absoluto de este indicador determina las distancias desde el precio de apertura de la barra, más allá de las cuales es muy probable que el precio empiece a fluctuar con fuerza. Por lo tanto, es muy recomendable establecer las órdenes pendientes en estos niveles para la apertura de posiciones y detener las pérdidas (niveles Stop Loss). En este caso, tenemos la posibilidad de utilizar el indicador ATR para establecer una orden a una determinada distancia del precio que se adaptaría a la volatilidad actual del mercado en cada transacción. Establecer una distancia fija en un mercado real es parecido a un viejo general del ejército, siempre listo para el combate en una guerra que ya ha pasado a la historia. Esto resulta a menudo en sistemas de trading mucho más interesantes en las condiciones reales del mercado y siempre cambiantes. De manera muy similar, se puede utilizar la distancia ATR para desplazar los niveles Trailing Stop al precio en cada cambio de barra.
Podemos pasar ahora a desarrollar Asesores Expertos mediante el archivo Lite_EXPERT2.mqh. Lo mejor es comenzar con la actualización de los Asesores Expertos de Lite_EXPERT1.mqh para que tengan mayor versatilidad en el trading.
Un sistema de trading que usa los cambios de dirección del promedio móvil como señales para entrar y salir del mercado
He descrito en detalle este tipo de sistemas en mi artículo "Asesores expertos basados en sistemas populares de trading, y un poco de alquimia en la optimización de robots" dedicado a sistemas de trading muy sencillos.
Es hora de hacerlo más complejo. Se desarrolla un sistema de trading casi igual en el Asesor Experto Exp_1_1.mq4 (Exp_1.mq4), en base a las funciones de Lite_EXPERT2.mqh. Sólo tenemos que sustituir los valores fijos de Stop Loss y Take Profit por los valores que se calculan de nuevo en el indicador ATR y añadir los niveles similares de Trailing Stop que se desplazarán con cada cambio de barra. Es mejor hacerlo en dos etapas. Primero sustituimos Stop Loss y Take Profit (el Asesor Experto Exp_17_A.mq4) y después de comprobar los errores del código y de acuerdo con la estrategia de trading seleccionada, añadimos los niveles Trailing Stop (el Asesor Experto Exp_17.mq4). En este artículo, sólo voy a proporcionar la versión final y con unas descripciones más detalladas de los cambios en el código.
//+X================================================================X+ //| Exp_17.mq4 | //| Copyright © 2009, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+X================================================================X+ #property copyright "Copyright © 2009, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //+--------------------------------------------------------+ //| INPUT PARAMETERS OF THE EXPERT ADVISOR FOR BUY DEALS | //+--------------------------------------------------------+ extern bool Test_Up = true; // filter of direction of deal calculations extern int Timeframe_Up = 240; extern double Money_Management_Up = 0.1; extern int Length_Up = 4; // depth of smoothing extern int Phase_Up = 100; // parameter varying within the range (-100..+100), impacts the transitional process quality; extern int IPC_Up = 0; extern int ATR_Period_Up = 14; // True Range averaging period extern int LevMinimum_Up = 40; // Minimum value in points below // which pending order values cannot fall extern int STOPLOSS_Up = 100; // Stop Loss expressed as percentage of ATR extern int TAKEPROFIT_Up = 200; // Take Profit expressed as percentage of ATR extern int TRAILINGSTOP_Up = 100; // Trailing Stop expressed as percentage of ATR extern bool ClosePos_Up = true; // permission to forcibly close a position //+--------------------------------------------------------+ //| INPUT PARAMETERS OF THE EXPERT ADVISOR FOR SELL DEALS | //+--------------------------------------------------------+ extern bool Test_Dn = true; // filter of direction of deal calculations extern int Timeframe_Dn = 240; extern double Money_Management_Dn = 0.1; extern int Length_Dn = 4; // depth of smoothing extern int Phase_Dn = 100; // parameter varying within the range (-100..+100), impacts the transitional process quality; extern int IPC_Dn = 0; extern int ATR_Period_Dn = 14; // True Range averaging period extern int LevMinimum_Dn = 40; // Minimum value in points below // which pending order values cannot fall extern int STOPLOSS_Dn = 100; // Stop Loss expressed as percentage of ATR extern int TAKEPROFIT_Dn = 200; // Take Profit expressed as percentage of ATR extern int TRAILINGSTOP_Dn = 100; // Trailing Stop expressed as percentage of ATR extern bool ClosePos_Dn = true; // permission to forcibly close a position //+---------------------------------------------+ //---- declaration of integer variables for the minimum calculation bars int MinBar_Up, MinBar_Dn; //---- declaration of integer variables for chart time frames in seconds int Period_Up, Period_Dn; //---- declaration of floating point variables for pending orders double _STOPLOSS_Up, _TAKEPROFIT_Up, _LevMinimum_Up, _TRAILINGSTOP_Up; double _STOPLOSS_Dn, _TAKEPROFIT_Dn, _LevMinimum_Dn, _TRAILINGSTOP_Dn; //+X================================================================X+ //| Custom Expert functions | //+X================================================================X+ #include <Lite_EXPERT2.mqh> //+X================================================================X+ //| Custom Expert initialization function | //+X================================================================X+ int init() { //---- Checking correctness of the Timeframe_Up variable value TimeframeCheck("Timeframe_Up", Timeframe_Up); //---- Checking correctness of the Timeframe_Dn variable value TimeframeCheck("Timeframe_Dn", Timeframe_Dn); //---- Initialization of variables MinBar_Up = 4 + 39 + 30;// four bars for entry signals + FATL filter length + JMA filter length MinBar_Up = MathMax(MinBar_Up, ATR_Period_Up + 1); MinBar_Dn = 4 + 39 + 30;// four bars for entry signals + FATL filter length + JMA filter length MinBar_Dn = MathMax(MinBar_Dn, ATR_Period_Dn + 1); //---- Period_Up = Timeframe_Up * 60; // chart time frame for long positions in seconds Period_Dn = Timeframe_Dn * 60; // chart time frame for short positions in seconds //---- Conversion of percent to fraction _STOPLOSS_Up = STOPLOSS_Up / 100.0; _TAKEPROFIT_Up = TAKEPROFIT_Up / 100.0; _TRAILINGSTOP_Up = TRAILINGSTOP_Up / 100.0; //---- Conversion of percent to fraction _STOPLOSS_Dn = STOPLOSS_Dn / 100.0; _TAKEPROFIT_Dn = TAKEPROFIT_Dn / 100.0; _TRAILINGSTOP_Dn = TRAILINGSTOP_Dn / 100.0; //---- Conversion of the minimum points to the price distance minimum _LevMinimum_Up = LevMinimum_Up * Point; _LevMinimum_Dn = LevMinimum_Dn * Point; //---- initialization complete return(0); } //+X================================================================X+ //| expert deinitialization function | //+X================================================================X+ int deinit() { //----+ Deleting global variables after testing and optimizations TimeLevelGlobalVariableDel(Symbol(), 1); TimeLevelGlobalVariableDel(Symbol(), 2); //---- Expert Advisor deinitialization complete return(0); //----+ } //+X================================================================X+ //| Custom Expert iteration function | //+X================================================================X+ int start() { //----+ //----+ Declaration of local variables int bar; double Mov[3], dMov12, dMov23, ATR, Level, open; //----+ Declaration of static variables static datetime TradeTimeLevel_Up, TradeTimeLevel_Dn; //---- static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop; static bool TrailSignal_Up, TrailSignal_Dn; //---- static double dStopLoss_Up, dTakeProfit_Up, dTrailingStop_Up; static double dStopLoss_Dn, dTakeProfit_Dn, dTrailingStop_Dn; //+---------------------------+ //| CODE FOR LONG POSITIONS | //+---------------------------+ if (Test_Up) if (MinBarCheck(Symbol(), Timeframe_Up, MinBar_Up)) { if (IsNewBar(0, Symbol(), Timeframe_Up)) { //----+ Zeroing out trading signals BUY_Sign = false; BUY_Stop = false; //---- Getting the time limit for disabling // the next trading operation TradeTimeLevel_Up = iTime(NULL, Timeframe_Up, 0); if (TradeTimeLevel_Up == 0) return(-1); TradeTimeLevel_Up += Period_Up; //----+ CALCULATING AND LOADING INDICATOR VALUES TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Up, "JFatl", Length_Up, Phase_Up, 0, IPC_Up, 0, bar); //----+ DETERMINING SIGNALS FOR DEALS dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; //---- Getting a signal for opening a position if (dMov23 < 0) if (dMov12 > 0) BUY_Sign = true; //---- Getting a signal for closing a position if (dMov12 < 0) if (ClosePos_Up) BUY_Stop = true; //----+ CALCULATION OF PENDING ORDERS FOR LONG POSITIONS // Make order calculation only if the trading signal is available if (BUY_Sign) { //---- Getting the initial ATR value ATR = iATR(NULL, Timeframe_Up, ATR_Period_Up, 1); //---- Getting the current price open = iOpen(Symbol(), Timeframe_Up, 0); //---- Calculating the distance to the Stop Loss Level = ATR * _STOPLOSS_Up; //---- Checking the distance to the Stop Loss against the minimum value if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- Determining the absolute Stop Loss value dStopLoss_Up = open - Level; //---- Calculating the distance to the Take Profit Level = ATR * _TAKEPROFIT_Up; //---- Checking the distance to the Take Profit against the minimum value if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- Determining the absolute Take Profit value dTakeProfit_Up = open + Level; //---- Correcting values of pending // orders, given the direction of the trade dGhartVelueCorrect(OP_BUY, dStopLoss_Up); dGhartVelueCorrect(OP_BUY, dTakeProfit_Up); } //----+ CALCULATION OF TRAILING STOPS FOR LONG POSITIONS dTrailingStop_Up = 0; TrailSignal_Up = false; //---- if (TRAILINGSTOP_Up > 0) // Calculate the Trailing Stop only if the necessary position exists if (OrderSelect_(Symbol(), OP_BUY, 1, MODE_TRADES)) // Move Trailing Stop if the position is opened on a non-zero bar if (iBarShift(NULL, Timeframe_Up, OrderOpenTime(), false) > 0) { TrailSignal_Up = true; //---- Getting the initial ATR value ATR = iATR(NULL, Timeframe_Up, ATR_Period_Up, 1); //---- Getting the current price open = iOpen(Symbol(), Timeframe_Up, 0); //---- Calculating the distance to the Stop Loss Level = ATR * _TRAILINGSTOP_Up; //---- Checking the distance to the Stop Loss against the minimum value if (Level < _LevMinimum_Up) Level = _LevMinimum_Up; //---- Getting the absolute Trailing Stop value dTrailingStop_Up = open - Level; //---- Correcting the absolute Trailing Stop value, // given the direction of the trade (for position // modification functions the value of the cmd variable is inverse!) dGhartVelueCorrect(OP_SELL, dTrailingStop_Up); } } //----+ DEAL EXECUTION if (!dOpenBuyOrder1_(BUY_Sign, 1, TradeTimeLevel_Up, Money_Management_Up, 5, dStopLoss_Up, dTakeProfit_Up)) return(-1); //---- if (!CloseBuyOrder1_(BUY_Stop, 1)) return(-1); //---- if (!dMake_BuyTrailingStop_(TrailSignal_Up, 1, TradeTimeLevel_Up, dTrailingStop_Up)) return(-1); } //+---------------------------+ //| CODE FOR SHORT POSITIONS | //+---------------------------+ if (Test_Dn) if (MinBarCheck(Symbol(), Timeframe_Dn, MinBar_Dn)) { if (IsNewBar(1, Symbol(), Timeframe_Dn)) { //----+ Zeroing out trading signals SELL_Sign = false; SELL_Stop = false; //---- Getting the time limit for disabling // the next trading operation TradeTimeLevel_Dn = iTime(NULL, Timeframe_Dn, 0); if (TradeTimeLevel_Dn == 0) return(-1); TradeTimeLevel_Dn += Period_Dn; //----+ CALCULATING AND LOADING INDICATOR VALUES TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Dn, "JFatl", Length_Dn, Phase_Dn, 0, IPC_Dn, 0, bar); //----+ DETERMINING SIGNALS FOR DEALS dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; //---- Getting a signal for opening a position if (dMov23 > 0) if (dMov12 < 0) SELL_Sign = true; //---- Getting a signal for closing a position if (dMov12 > 0) if (ClosePos_Dn) SELL_Stop = true; //----+ CALCULATION OF PENDING ORDERS FOR SHORT POSITIONS // Make order calculation only if the trading signal is available if (SELL_Sign) { //---- Getting the initial ATR value ATR = iATR(NULL, Timeframe_Dn, ATR_Period_Dn, 1); //---- Getting the current price open = iOpen(Symbol(), Timeframe_Dn, 0); //---- Calculating the distance to the Stop Loss Level = ATR * _STOPLOSS_Dn; //---- Checking the distance to the Stop Loss against the minimum value if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- Determining the absolute Stop Loss value dStopLoss_Dn = open + Level; //---- Calculating the distance to the Take Profit Level = ATR * _TAKEPROFIT_Dn; //---- Checking the distance to the Take Profit against the minimum value if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- Determining the absolute Take Profit value dTakeProfit_Dn = open - Level; //---- Correcting values of pending orders, given the direction of the trade dGhartVelueCorrect(OP_SELL, dStopLoss_Dn); dGhartVelueCorrect(OP_SELL, dTakeProfit_Dn); } //----+ CALCULATION OF TRAILING STOPS FOR SHORT POSITIONS dTrailingStop_Dn = 0; TrailSignal_Dn = false; //---- if (TRAILINGSTOP_Dn > 0) // Calculate the Trailing Stop only if the necessary position exists if (OrderSelect_(Symbol(), OP_SELL, 2, MODE_TRADES)) // Move Trailing Stop if the position is opened on a non-zero bar if (iBarShift(NULL, Timeframe_Dn, OrderOpenTime(), false) > 0) { TrailSignal_Dn = true; //---- Getting the initial ATR value ATR = iATR(NULL, Timeframe_Dn, ATR_Period_Dn, 1); //---- Getting the current price open = iOpen(Symbol(), Timeframe_Dn, 0); //---- Calculating the distance to the Stop Loss Level = ATR * _TRAILINGSTOP_Dn; //---- Checking the distance to the Stop Loss against the minimum value if (Level < _LevMinimum_Dn) Level = _LevMinimum_Dn; //---- Getting the absolute Trailing Stop value dTrailingStop_Dn = open + Level; //---- Correcting the absolute Trailing Stop value, // given the direction of the trade (for position // modification functions the value of the cmd variable is inverse!) dGhartVelueCorrect(OP_BUY, dTrailingStop_Dn); } } //----+ DEAL EXECUTION if (!dOpenSellOrder1_(SELL_Sign, 2, TradeTimeLevel_Dn, Money_Management_Dn, 5, dStopLoss_Dn, dTakeProfit_Dn)) return(-1); //---- if (!CloseSellOrder1_(SELL_Stop, 2)) return(-1); //---- if (!dMake_SellTrailingStop_(TrailSignal_Dn, 2, TradeTimeLevel_Dn, dTrailingStop_Dn)) return(-1); } return(0); //----+ } //+X----------------------+ <<< The End >>> +-----------------------X+
En el bloque de las variables externas del Asesor Experto tenemos dos nuevas variables, son ATR_Period_Up y ATR_Period_Dn que se pueden utilizar para cambiar los valores del indicador ATR implicados en el cálculo de las órdenes pendientes. El sentido de los valores de las variables externas para Stop Loss, Take Profit y Trailing Stop es algo distinto. Se usan estos valores para representar la distancia relativa en puntos entre la orden y el precio actual. Ahora representan el porcentaje del valor del indicador ATR en la primera barra. En otras palabras, para calcular la orden tomamos el porcentaje del indicador ATR y lo añadimos al valor del precio de apertura de la barra cero. Para convertir un porcentaje en un valor de punto flotante lo mejor es utilizar el bloque init() del Asesor Experto donde se harán estos cálculos una vez sólo y se almacenarán los valores calculados en las variables declaradas a nivel global.
Debido a la presencia del nuevo indicador ATR, han cambiado las fórmulas para inicializar las variables LevMinimum_Up y LevMinimum_Dn en el bloque init(). El bloque start() del Asesor Experto cuenta con nuevas variables estáticas para almacenar los valores entre los ticks del terminal. El código para calcular las órdenes pendientes y los niveles Trailing Stop está dispuesto en pequeños módulos dentro de los bloques que reciben las señales de las transacciones. Para ejecutar una transacción ahora, usamos distintas funciones donde se inicializa la variable Margin_Mode con cinco, siendo el valor más lógico en las condiciones del Stop Loss flotante.
Para demostrar las posibilidades que ofrece el uso de las funciones IndicatorCounted_() y ReSetAsIndexBuffer(), hemos sustituido el indicador personalizado JFatl.mq4 por la función JFATL() insertada en el código del Asesor Experto.
bool JFATL(int Number, string symbol, int timeframe, int Length, int Phase, int IPC, double& Buffer[])
La función recibe los parámetros de entrada del indicador y la matriz Buffer[]. Si los cálculos son correctos la función devuelve true, de lo contrario devuelve false. Se convierte la matriz en un buffer análogo del indicador relleno con los valores del indicador JFATL. En la función, se sustituye la función JJMASeries() por JJMASeries1() que no lleva a cabo ningún cálculo en la barra cero. Hemos sustituido también la función PriceSeries() por la función iPriceSeries(). Se ha movido el bloque de inicialización del indicador al bloque de "inicialización cero". Tenga en cuenta que la función JJMASeries1() se usa solamente en esta función en el Asesor Experto de modo que la variable Number no se vuelve a calcular y se pasa directamente a la función JJMASeries1(). Ocurre lo mismo con la función IndicatorCounted_().
Ya había mencionado estas sustituciones de indicadores en la función en mis otros artículos dedicados a este tema: 1, 2 y 3. El Asesor Experto que contiene estas sustituciones es el archivo Exp_17_.mq4. Hay que mencionar que el algoritmo de suavizado JMA empleado en el indicador JFatl.mq4 consume muchos recursos y la sustitución del indicador por la función de indicador permite acelerar de manera significativa la optimización en este Asesor Experto en comparación con la versión anterior. Y por último, se ha desarrollado el mismo Asesor Experto (Exp_17R.mq4) para los más perezosos que incluye todas las funciones necesarias en su código y no se requiere ningún archivo de inclusión o indicador adicional para su compilación y funcionamiento. ¡El funcionamiento de estos tres Asesores Expertos es idéntico! Excepto quizás por el hecho de que los valores de las variables IPC_Up y IPC_Dn en el último Asesor Experto están en un rango algo más pequeño (0-10) debido a la falta de llamada al indicador Heiken Ashi#.mq4.
En el foro, puede encontrar a veces algunos genios en programación MQL4 que no aprueban la idea de escribir estas funciones de indicadores, que según ellos es como ponerse los pantalones por la cabeza. Personalmente, he tardado quince minutes en escribir esta función basada en un código bastante fácil de entender. Así que si alguien puede ir seis veces más rápido en una maratón de optimización con los pantalones al revés, ¡apuesto por él!
Sistema de arranque par el trading con noticias
Ya se ha abordado esta versión de sistemas de trading en mi artículo mediante el Asesor Experto Exp_10.mq4. El Asesor Experto Exp_10_1.mq4 basado en las funciones Lite_EXPERT2.mqh es completamente análogo. Esta versión es un poco más compleja que la original, pero mucho más estable, ya que no le afecta el reinicio del Asesor Experto, ni del terminal ni del sistema operativo. Este Asesor Experto utiliza la función TradeTimeLevelCheck() para determinar el momento de cierre de una posición:
Esta función devuelve true después del punto cuyo valor se toma como parámetro de entrada de la función que lleva a cabo la colocación de órdenes pendientes o la apertura de posiciones. Se obtiene este valor a partir de la variable global mediante la función.
Ahora tenemos que cambiar el algoritmo de cálculo de las órdenes pendientes. Pero en este caso, además de Stop Loss y Take Profit hay que calcular las órdenes Stop de manera dinámica. En general, esto no cambia nada y todo se implementa del mismo modo. Por otra parte, el Trailing Stop en el Asesor Experto original funciona con cada tick y tenemos que desplazarlo en cada cambio de barra. Está claro que el código final del Asesor Experto (Exp_18.mq4) no es tan sencillo como el original, pero la lógica del programa es bastante precisa y clara. Exp_18R.mq4 es idéntico al último Asesor Experto implementado en forma de un archivo terminado e independiente.
Conclusión
Desde el planteamiento de la programación, creo que no hay nada nuevo en las funciones personalizadas de Lite_EXPERT2.mqh en comparación con las funciones de Lite_EXPERT1.mqh.
Simplemente mejoran la funcionalidad de la programación, pero su utilización sigue siendo básicamente la misma. Así que después de estudiar atentamente las funciones de Lite_EXPERT1.mqh, va a poder aprender la funcionalidad de Lite_EXPERT2.mqh de manera rápida y sencilla.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/1384
![Interacción entre MetaTrader 4 y Matlab mediante DDE](https://c.mql5.com/2/16/609_29.gif)
![Análisis avanzado de una cuenta de trading](https://c.mql5.com/2/17/830_31.png)
![Asesores Expertos basados en estrategias populares de trading, y un poco de alquimia en la optimización de robots (Parte VI)](https://c.mql5.com/2/16/633_39.gif)
![Optimización visual de la rentabilidad de indicadores y señales](https://c.mql5.com/2/17/820_9.gif)
![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