Asesores expertos basados en sistemas de trading populares y alquimia de la optimización de robots de trading (Parte VII)
Introducción
De este modo, MetaQuotes Software Corp. dio inicio al registro para participar en el Campeonato de Trading Automatizado de 2008 el 1 de julio de 2008. Sería algo intrascendente para mi perderme esta oportunidad y no seguir con la serie de artículos de la representación de la lógica en la creación de un asesor experto que cumpla formalmente todas las Reglas del Campeonato de Trading Automatizado de 2008 y que no admitiera ningún error crítico durante el concurso, por el que podría quedar descalificado.
Es muy natural que para la realización de este evento yo use los algoritmos más sencillos para abrir posiciones cuyos factores de trading no sean realmente interesantes para nosotros en el contexto de este artículo, mientras que las pequeñas cosas más elementas pueden ser más importantes para buscar el examen, ya que pueden suponer la participación de uno en el Campeonato varios años después.
Idea general de la escritura de un asesor experto
En mi opinión, será más ilustrativo en nuestro caso esbozar dicho asesor experto con una descripción detallada de su creación que realmente proporcionara su comportamiento correcto en su interacción con el servidor de trading. Las Reglas del Campeonato determinan la cantidad de posiciones abiertas y órdenes pendientes colocadas simultáneamente, siendo estas iguales a tres. Por tanto, sería razonable usar tres estrategias en un asesor experto, una por posición.
Usaremos los mismos algoritmos con distintos parámetros para abrir posiciones largas y cortas, mientras que hacer que estos algoritmos abran solo una posición al mismo tiempo requiere que los asignemos a los mismos números mágicos. De este modo, tendremos seis algoritmos para entrar al mercado y solo tres números mágicos. Como algoritmo de entrada, uso un sistema de trading basado en el cambio de la dirección de la media móvil de mi primer artículo en esta serie. Para que el algoritmo sea distinto en cada caso, uso distintas medias móviles en ellos.
Código del asesor experto
Esta es una versión del código del asesor experto:
//+==================================================================+ //| Exp_16_Champ.mq4 | //| Copyright © 2008, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2008, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //----+ +-----------------------------------------------------------------------+ //---- EXPERT ADVISOR'S INPUTS FOR BUY TRADES extern bool Test_Up1 = true;//a filter for trades calculation direction extern int Timeframe_Up1 = 60; extern double Money_Management_Up1 = 0.1; extern int Length_Up1 = 4; // smoothing depth extern int Phase_Up1 = 100; // parameter ranging within //-100 ... +100, it affects the quality of the transient process; extern int IPC_Up1 = 0;/* Choosing prices to calculate the indicator on (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Up1 = 50; // StopLoss extern int TAKEPROFIT_Up1 = 100; // TakeProfit extern bool ClosePos_Up1 = true; // enable forcible closing the position //----+ +-----------------------------------------------------------------------+ //---- EXPERT ADVISOR'S INPUTS FOR SELL TRADES extern bool Test_Dn1 = true;//a filter for trades calculation direction extern int Timeframe_Dn1 = 60; extern double Money_Management_Dn1 = 0.1; extern int Length_Dn1 = 4; // smoothing depth extern int Phase_Dn1 = 100; // parameter ranging within // -100 ... +100, it affects the quality of the transient process; extern int IPC_Dn1 = 0;/* Choosing prices to calculate the indicator on (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Dn1 = 50; // StopLoss extern int TAKEPROFIT_Dn1 = 100; // TakeProfit extern bool ClosePos_Dn1 = true; // enable forcible closing the position //----+ +-----------------------------------------------------------------------+ //---- EXPERT ADVISOR'S INPUTS FOR BUY TRADES extern bool Test_Up2 = true;//a filter for trades calculation direction extern int Timeframe_Up2 = 60; extern double Money_Management_Up2 = 0.1; extern int Length1_Up2 = 4; // first smoothing depth extern int Phase1_Up2 = 100; // parameter of the first smoothing, //ranging within -100 ... +100, it affects the quality //of the averaging transient; extern int Length2_Up2 = 4; // second smoothing depth extern int Phase2_Up2 = 100; // parameter of the second smoothing, //ranging within -100 ... +100, it affects the quality //of the averaging transient; extern int IPC_Up2 = 0;/* Choosing prices to calculate the indicator on (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Up2 = 50; // StopLoss extern int TAKEPROFIT_Up2 = 100; // TakeProfit extern bool ClosePos_Up2 = true; // enable forcible closing the position //----+ +-----------------------------------------------------------------------+ //---- EXPERT ADVISOR'S INPUTS FOR SELL TRADES extern bool Test_Dn2 = true;//a filter for trades calculation direction extern int Timeframe_Dn2 = 60; extern double Money_Management_Dn2 = 0.1; extern int Length1_Dn2 = 4; // smoothing depth extern int Phase1_Dn2 = 100; // parameter of the first smoothing, //ranging within -100 ... +100, it affects the quality //of the averaging transient; extern int Length2_Dn2 = 4; // smoothing depth extern int Phase2_Dn2 = 100; // parameter of the second smoothing, //ranging within -100 ... +100, it affects the quality //of the averaging transient; extern int IPC_Dn2 = 0;/* Choosing prices to calculate the indicator on (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Dn2 = 50; // StopLoss extern int TAKEPROFIT_Dn2 = 100; // TakeProfit extern bool ClosePos_Dn2 = true; // enable forcible closing the position //----+ +-----------------------------------------------------------------------+ //---- EXPERT ADVISOR'S INPUTS FOR BUY TRADES extern bool Test_Up3 = true;//a filter for trades calculation direction extern int Timeframe_Up3 = 60; extern double Money_Management_Up3 = 0.1; extern int Period_Up3 = 10; // LSMA period extern int Length_Up3 = 4; // smoothing depth extern int Phase_Up3 = 100; // parameter of smoothing, //ranging within -100 ... +100, it affects the quality //of the averaging transient; extern int IPC_Up3 = 0;/* Choosing prices to calculate the indicator on (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Up3 = 50; // StopLoss extern int TAKEPROFIT_Up3 = 100; // TakeProfit extern bool ClosePos_Up3 = true; // enable forcible closing the position //----+ +-----------------------------------------------------------------------+ //---- EXPERT ADVISOR'S INPUTS FOR SELL TRADES extern bool Test_Dn3 = true;//a filter for trades calculation direction extern int Timeframe_Dn3 = 60; extern double Money_Management_Dn3 = 0.1; extern int Period_Dn3 = 10; // LSMA period extern int Length_Dn3 = 4; // smoothing depth extern int Phase_Dn3 = 100; // parameter smoothing, //ranging within -100 ... +100, it affects the quality //of the averaging transient; extern int IPC_Dn3 = 0;/* Choosing prices to calculate the indicator on (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 14-Heiken Ashi Close.) */ extern int STOPLOSS_Dn3 = 50; // StopLoss extern int TAKEPROFIT_Dn3 = 100; // TakeProfit extern bool ClosePos_Dn3 = true; // enable forcible closing the position //----+ +-----------------------------------------------------------------------+ //---- Integer variables for the minimum of estimated bars int MinBar_Up1, MinBar_Up2, MinBar_Up3; int MinBar_Dn1, MinBar_Dn2, MinBar_Dn3; //+==================================================================+ //| Custom Expert functions | //+==================================================================+ #include <Lite_EXPERT_Champ.mqh> //+==================================================================+ //| TimeframeCheck() functions | //+==================================================================+ void TimeframeCheck(string Name, int Timeframe) { //----+ //---- Checking the value of the 'Timeframe' variable for correctness if (Timeframe != 1) if (Timeframe != 5) if (Timeframe != 15) if (Timeframe != 30) if (Timeframe != 60) if (Timeframe != 240) if (Timeframe != 1440) Print(StringConcatenate("Parameter ",Name, " cannot ", "be equal to ", Timeframe, "!!!")); //----+ } //+==================================================================+ //| Custom Expert initialization function | //+==================================================================+ int init() { //---- Checking the values of short-position timeframe variables for correctness TimeframeCheck("Timeframe_Up1", Timeframe_Up1); TimeframeCheck("Timeframe_Up2", Timeframe_Up2); TimeframeCheck("Timeframe_Up3", Timeframe_Up3); //---- Checking the values of long-position timeframe variables for correctness TimeframeCheck("Timeframe_Dn1", Timeframe_Dn1); TimeframeCheck("Timeframe_Dn2", Timeframe_Dn2); TimeframeCheck("Timeframe_Dn3", Timeframe_Dn3); //---- Initialization of variables MinBar_Up1 = 4 + 39 + 30; MinBar_Up2 = 4 + 30; MinBar_Up3 = 4 + Period_Up3 + 30; MinBar_Dn1 = 4 + 39 + 30; MinBar_Dn2 = 4 + 30; MinBar_Dn3 = 4 + Period_Dn3 + 30; //---- initialization complete return(0); } //+==================================================================+ //| expert deinitialization function | //+==================================================================+ int deinit() { //----+ //---- Expert Advisor initialization complete return(0); //----+ } //+==================================================================+ //| Custom Expert iteration function | //+==================================================================+ int start() { //----+ Declaration of local variables int bar; double Mov[3], dMov12, dMov23; //----+ Declaration of static variables static int LastBars_Up1, LastBars_Dn1; static int LastBars_Up2, LastBars_Dn2; static int LastBars_Up3, LastBars_Dn3; static bool BUY_Sign1, BUY_Stop1, SELL_Sign1, SELL_Stop1; static bool BUY_Sign2, BUY_Stop2, SELL_Sign2, SELL_Stop2; static bool BUY_Sign3, BUY_Stop3, SELL_Sign3, SELL_Stop3; //+------------------------------------------------------------------------+ //----++ CODE FOR LONG POSITIONS if (Test_Up1) { int IBARS_Up1 = iBars(NULL, Timeframe_Up1); if (IBARS_Up1 >= MinBar_Up1) { if (LastBars_Up1 != IBARS_Up1) { //----+ Initialization of variables BUY_Sign1 = false; BUY_Stop1 = false; LastBars_Up1 = IBARS_Up1; //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Up1, "JFatl", Length_Up1, Phase_Up1, 0, IPC_Up1, 0, bar); //----+ DETERMINING SIGNALS FOR TRADES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 < 0) if (dMov12 > 0) BUY_Sign1 = true; if (dMov12 < 0) BUY_Stop1 = true; } //----+ MAKING TRADES if (!OpenBuyOrder_Ch(BUY_Sign1, 1, Money_Management_Up1, STOPLOSS_Up1, TAKEPROFIT_Up1)) return(-1); if (ClosePos_Up1) if (!CloseOrder_Ch(BUY_Stop1, 1)) return(-1); } } //----++ CODE FOR SHORT POSITIONS if (Test_Dn1) { int IBARS_Dn1 = iBars(NULL, Timeframe_Dn1); if (IBARS_Dn1 >= MinBar_Dn1) { if (LastBars_Dn1 != IBARS_Dn1) { //----+ Initialization of variables SELL_Sign1 = false; SELL_Stop1 = false; LastBars_Dn1 = IBARS_Dn1; //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Dn1, "JFatl", Length_Dn1, Phase_Dn1, 0, IPC_Dn1, 0, bar); //----+ DETERMINING SIGNALS FOR TRADES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 > 0) if (dMov12 < 0) SELL_Sign1 = true; if (dMov12 > 0) SELL_Stop1 = true; } //----+ MAKING TRADES if (!OpenSellOrder_Ch(SELL_Sign1, 1, Money_Management_Dn1, STOPLOSS_Dn1, TAKEPROFIT_Dn1)) return(-1); if (ClosePos_Dn1) if (!CloseOrder_Ch(SELL_Stop1, 1)) return(-1); } } //+------------------------------------------------------------------------+ //----++ CODE FOR LONG POSITIONS if (Test_Up2) { int IBARS_Up2 = iBars(NULL, Timeframe_Up2); if (IBARS_Up2 >= MinBar_Up2) { if (LastBars_Up2 != IBARS_Up2) { //----+ Initialization of variables BUY_Sign2 = false; BUY_Stop2 = false; LastBars_Up2 = IBARS_Up2; //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Up2, "J2JMA", Length1_Up2, Length2_Up2, Phase1_Up2, Phase2_Up2, 0, IPC_Up2, 0, bar); //----+ DETERMINING SIGNALS FOR TRADES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 < 0) if (dMov12 > 0) BUY_Sign2 = true; if (dMov12 < 0) BUY_Stop2 = true; } //----+ MAKING TRADES if (!OpenBuyOrder_Ch(BUY_Sign2, 2, Money_Management_Up2, STOPLOSS_Up2, TAKEPROFIT_Up2)) return(-1); if (ClosePos_Up2) if (!CloseOrder_Ch(BUY_Stop2, 2)) return(-1); } } //----++ CODE FOR SHORT POSITIONS if (Test_Dn2) { int IBARS_Dn2 = iBars(NULL, Timeframe_Dn2); if (IBARS_Dn2 >= MinBar_Dn2) { if (LastBars_Dn2 != IBARS_Dn2) { //----+ Initialization of variables SELL_Sign2 = false; SELL_Stop2 = false; LastBars_Dn2 = IBARS_Dn2; //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Dn2, "J2JMA", Length1_Dn2, Length2_Dn2, Phase1_Dn2, Phase2_Dn2, 0, IPC_Dn2, 0, bar); //----+ DETERMINING SIGNALS FOR TRADES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 > 0) if (dMov12 < 0) SELL_Sign2 = true; if (dMov12 > 0) SELL_Stop2 = true; } //----+ MAKING TRADES if (!OpenSellOrder_Ch(SELL_Sign2, 2, Money_Management_Dn2, STOPLOSS_Dn2, TAKEPROFIT_Dn2)) return(-1); if (ClosePos_Dn2) if (!CloseOrder_Ch(SELL_Stop2, 2)) return(-1); } } //+------------------------------------------------------------------------+ //----++ CODE FOR LONG POSITIONS if (Test_Up3) { int IBARS_Up3 = iBars(NULL, Timeframe_Up3); if (IBARS_Up3 >= MinBar_Up3) { if (LastBars_Up3 != IBARS_Up3) { //----+ Initialization of variables BUY_Sign3 = false; BUY_Stop3 = false; LastBars_Up3 = IBARS_Up3; //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Up3, "JLSMA", Period_Up3, Length_Up3, Phase_Up3, 0, IPC_Up3, 0, bar); //----+ DETERMINING SIGNALS FOR TRADES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 < 0) if (dMov12 > 0) BUY_Sign3 = true; if (dMov12 < 0) BUY_Stop3 = true; } //----+ MAKING TRADES if (!OpenBuyOrder_Ch(BUY_Sign3, 3, Money_Management_Up3, STOPLOSS_Up3, TAKEPROFIT_Up3)) return(-1); if (ClosePos_Up3) if (!CloseOrder_Ch(BUY_Stop3, 3)) return(-1); } } //----++ CODE FOR SHORT POSITIONS if (Test_Dn3) { int IBARS_Dn3 = iBars(NULL, Timeframe_Dn3); if (IBARS_Dn3 >= MinBar_Dn3) { if (LastBars_Dn3 != IBARS_Dn3) { //----+ Initialization of variables SELL_Sign3 = false; SELL_Stop3 = false; LastBars_Dn3 = IBARS_Dn3; //----+ CALCULATING THE INDICATORS' VALUES AND LOADING THEM TO BUFFERS for(bar = 1; bar <= 3; bar++) Mov[bar - 1]= iCustom(NULL, Timeframe_Dn3, "JLSMA", Period_Dn3, Length_Dn3, Phase_Dn3, 0, IPC_Dn3, 0, bar); //----+ DETERMINING SIGNALS FOR TRADES dMov12 = Mov[0] - Mov[1]; dMov23 = Mov[1] - Mov[2]; if (dMov23 > 0) if (dMov12 < 0) SELL_Sign3 = true; if (dMov12 > 0) SELL_Stop3 = true; } //----+ MAKING TRADES if (!OpenSellOrder_Ch(SELL_Sign3, 3, Money_Management_Dn3, STOPLOSS_Dn3, TAKEPROFIT_Dn3)) return(-1); if (ClosePos_Dn3) if (!CloseOrder_Ch(SELL_Stop3, 3)) return(-1); } } //+------------------------------------------------------------------------+ //----+ return(0); } //+------------------------------------------------------------------+
Aquellos que quieran tener un asesor experto sin las limitaciones indicadas en el Campeonato, pueden optar por Exp_16.mq4. De hecho, podemos ver la variedad de estrategias de trading entre tres algoritmos distintos entre sí de cierta manera. En general, tenemos tres estrategias de trading automatizado absolutamente independientes en un asesor experto. Cuando escribí el código, modifiqué los nombres de las variables en cada estrategia de trading automatizado para evitar coincidencias.
Para hacer transacciones, usé funciones similares a las del archivo Lite_EXPERT1.mqh, que vienen representadas en el archivo Lite_EXPERT_Champ.mqh. Estas funciones requirieron cambios y correcciones mínimos en sus códigos para cumplir los requisitos del Campeonato. Solo usar el código de dichas funciones en los códigos de los asesores expertos de otros participantes es completamente legal, ya que son solo elementos ejecutivos del asesor experto, que no guardan relación con el aspecto intelectual que realmente controla estos elementos.
Por tanto, no hay ninguna necesidad especial de entrar en los detalles de estas funciones o crear algo similar. Sería suficiente leer mis artículos anteriores de esta serie para poder usarlas. En general, el uso de estas funciones en la escritura de asesores expertos es tan efectivo como el uso de chips en el desarrollo y fabricación de dispositivos electrónicos.
A continuación se indica una breve descripción de que se ha considerado en la construcción de estas funciones.
1. Todas las funciones para abrir posiciones y colocar órdenes pendientes detectan la cantidad de posiciones ya abiertas y órdenes pendientes colocadas y, si su cantidad supera las dos, no realiza ninguna acción
2. La distancia mínima desde el precio de apertura de la orden en el que las funciones OpenBuyOrder_Ch(), OpenSellOrder_Ch(), OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() y OpenSellStopOrder_Ch() colocan TakeProfit, siempre es superior que la definida por las Reglas del Campeonato como una especulación. La distancia mínima a StopLoss viene determinada por las propiedades del símbolo de la transacción y es solicitada desde el servidor. Esto también se refiere a las órdenes pendientes. No obstante, debemos tener en cuenta el hecho de que las órdenes pendientes se procesan algunas veces en precios que resultan ser peores que los solicitados. Nuestras TakeProfits pueden entrar en el 'rango' de una estrategia de especulación en este caso. Por tanto, sería mejor apartarse de las estrategias de especulación. De lo contrario, en una buena cantidad de espacios (lo que es bastante posible al final del año) podemos descubrir que nuestro asesor experto ha aparecido bajo la definición de una estrategia especulativa.
No obstante, sería instructivo recordar que, si las TakeProfits son demasiado grandes, el asesor experto puede que realice muy pocas transacciones, lo que puede provocar también su descalificación.
3. El tamaño menor y mayor de una posición a abrir, así como el paso mínimo de los cambios determinados por las reglas del Campeonato se escriben en todas estas funciones con los valores de las variables a inicializar. Por tanto, dichos errores ya han sido evitados.
4. Antes de abrir una posición, las funciones OpenBuyOrder_Ch() y OpenSellOrder_Ch() comprueban el tamaño de esta posición y la propia posición por si hubiera el dinero suficiente en el depósito para dicho tamaño y reducir la cantidad de lotes a valores aceptables. Por tanto, cuando trabaja con estas funciones, nuestro asesor experto está exento de errores como "volumen de transacciones no válido" en cualquier caso. Por desgracia, es imposible corregir el tamaño del lote en las órdenes pendientes de esta forma, ya que es imposible predecir la cantidad de activos libres en el depósito en el momento de activarse la orden pendiente. Por tanto, un escritor de asesores expertos puede estar muy atento cuando se inicializan las variables externas 'Money_Management' de las funciones OpenBuyLimitOrder_Ch(), OpenBuyStopOrder_Ch(), OpenSellLimitOrder_Ch() y OpenSellStopOrder_Ch(), especialmente por los grandes valores de las StopLoss.
5. Todas las funciones para la gestión de posiciones mantienen pausas correctas entre transacciones de acuerdo con los códigos de error que se producen.
6. Antes de cerrar una posición o borrar una orden pendiente, o desplazar las StopLoss, las funciones CloseOrder_Ch(), CloseOrder_Ch() y Make_TreilingStop_Ch() comprueban que la posición esté bloqueada, si está bloqueada, no realizan ninguna acción.
7. Antes de cerrar una posición, la función CloseOrder_Ch() comprueba su ganancia neta para que no sea de tipo especulativa. Si las posiciones resultan estar dentro del rango de especulación, no realiza ninguna acción.
8. La función Make_TreilingStop_Ch() no mueve a StopLoss en el rango de precio en el que el beneficio de la posición cerrada por esta StopLoss pueda quedar dentro del 'rango de especulación'.
Conclusión
Bueno, ahí está todo lo que quería decir sobre el comportamiento ejemplar de un asesor experto en el Campeonato de Trading Automatizado. Por supuesto, hay un problema más, uno más real que tiene que ver con el exuberante consumo de recursos de la CPU. No obstante, en la mayoría de casos, este problema suele depender de indicadores escritos de forma poco eficaz a los que llama el asesor experto durante su funcionamiento. Y este es un par de zapatos completamente distinto.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/1542
- 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