![Un Ejemplo de Estrategia de Trading Basada en Diferencias de Zona Horaria en Continentes Distintos](https://c.mql5.com/i/articles/overlay.png)
Un Ejemplo de Estrategia de Trading Basada en Diferencias de Zona Horaria en Continentes Distintos
Introducción
Tenía algo de tiempo libre, y estaba claro que esta vez lo iba a aprovechar para estudiar los mercados e investigar la divergencia de ciclos económicos e indicadores técnicos. Puede ver los resultados de la investigación en el siguiente artículo: Creating an Indicator with Graphical Control Options (Crear un Indicador con Opciones de Control Gráficas). ¡Pero no realicé solo estos descubrimientos! He encontrado un fenómeno de escala aún mayor, pero para entenderlo, echemos un vistazo a nuestro mundo en términos de zonas horarias (Fig. 1).
Figura 1. Zonas horarias
Como pueden ver, el día empieza de forma diferente en cada país, y continúa con varias zonas horarias. Nuestro gran país tiene casi 10 zonas horarias distintas, mientras que el océano Atlántico solo alcanza 6 zonas horarias.
¿Qué patrón se sigue aquí? Veamos el orden de apertura de los mercados en los siguientes países: Japón, Australia, China, Rusia. Para cuando los primeros trabajadores rusos llegan a sus oficinas y comienzan sus operaciones de trading, en Asia ya es de noche, y sus mercados ya han cerrado para cuando se abren las sesiones en Europa.
Aquí es donde comienza la diversión. Una vez que el mercado se ha abierto, los brokers y gestores de fondos de cobertura europeos ponen sus servicios en el mercado, y llevan a cabo acciones especulativas o concurrentes con los intereses de sus inversores. No, todavía es demasiado pronto para la parte más interesante, que comienza con el amanecer en Chicago junto con el extremo menor del océano Atlántico: este es el momento en el que los gestores de la bolsa de Chicago abren sus terminales de trading y comienzan a gestionar su capital.
Hagamos una pausa en este momento, junto con el extremo menor del océano Atlántico. La sesión europea todavía no ha finalizado (Fig. 1). A Londres le separan de Chicago 8 zonas horarias, suponiendo que el día laborable es de 8 horas más otros 45 minutos para pausas y descansos y una hora para comer, lo que prolonga el tiempo entre una hora y media y dos horas adicionales (los que trabajan en una oficina ya saben todo esto).
Este es el momento en el que ganamos los bienes de mercado de gestores europeos y americanos. Me temo que debo alistar todos los ceros como bienes en este momento: los gestores europeos y americanos comienzan su lucha por el precio de los intercambios bursátiles, y ahora se da el fenómeno que se muestra en la Figura 2.
Figura 2. Pulso de Mercado
Las batallas financieras llenan el mercado, los bienes cambian de dueño a cada segundo, ¡pero esto no lo es todo en el mercado! Tras acabar este período, comienza un proceso más tranquilo, y se mueve en la dirección de la tendencia actual. En este momento, el margen expande sus límites, después los vuelve a estrechar de nuevo y así continúa moviéndose en la dirección de la tendencia principal.
Estoy seguro de que ha notado que el precio de mercado puede ir hacia arriba o hacia abajo, pero siempre va hacia la derecha.
2. Gráficos de flujo como método principal para desarrollar un algoritmo
El primer bloque del programa "Start-Stop" se demuestra en la Figura 3:
Figura 3. Bloque "Start-Stop"
Este bloque se usa para señalar el comienzo del programa o el inicio y final de una función u otro procedimiento, como por ejemplo una inicialización y desinicialización. El siguiente bloque que veremos se ha llamado "Data", y se muestra en la Figura 4.
Figura 4. Bloque "Data"
El bloque "Data" se usa para determinar los parámetros específicos al inicio del programa, o las variables de salida en el caso de MQL5. Esta unidad también establece el destino de las variables globales.
A continuación, pensemos en un bloque usado frecuentemente (99% de los programas en MQL utilizan este método). Se muestra en dos partes, que marcan los límites de un ciclo. Piense en la Fig. 5:
Figura 5. Bloques de ciclo
Los procesos como la atribución o contabilidad normalmente se llevan a cabo dentro de estos ciclos. Puede ver algunos ejemplos en la Figura 6.
Figura 6. Acciones
Y no debemos olvidarnos de los bloques de lógica: en la Fig. 7 se muestra el bloque "Solution".
Figura 7. El bloque "Solution"
El bloque "Solution" puede tener más de dos salidas si se localiza dentro del operador del tipo "interruptor que depende del número de posicionamientos". Esta unidad tendrá un número de salidas correspondiente.
El siguiente bloque introduce funciones predefinidas, como iMACD o iRSA, así como funciones personalizadas, definidas en otro sitio del programa o la biblioteca (Fig. 8).
Figura 8. Función
Y los últimos dos bloques implementan solo funciones de servicio, tales como comentarios y el incumplimiento (Fig. 9).
Figura 9. Bloques de servicio
Estos son todos los tipos de bloque que se pueden usar para describir cualquier programa escrito para una máquina. Son claros, sencillos y fáciles de usar en la primera fase de desarrollo, y también revelan los puntos débiles del sistema y sugieren métodos para eliminarlos.
Ahora ya conoce este método. No obstante, no le estoy pidiendo que actúe exactamente de acuerdo con estas instrucciones; pero sabiendo los valores iniciales de los gráficos de flujo es más fácil entender algunos tipos de métodos de cálculo. Este método me ayuda a formular rápidamente una idea que me vino de repente al hemisferio izquierdo de mi cerebro, lista para escaparse de mi hemisferio derecho.
3. Construcción del algoritmo
Por tanto, continuemos con la preparación del Asesor Experto basado en la estrategia del gráfico de flujo.
El primer bloque pedirá los parámetros de entrada. Tal y como hemos determinado, es esencial esperar hasta el momento de las batallas principales, es decir, dos horas tras la apertura de sesión en Estados Unidos, cuando cierran los mercados europeos. Siempre vigilaremos esto con el reloj global, es decir, con la hora terminal, y así calcularemos la hora de apertura nosotros mismos.
A continuación, determinaremos el tamaño de las posiciones y los niveles de beneficios y pérdidas, que en el futuro tendrán el potencial para optimizarse. Pondremos especial atención en el parámetro Número Mágico, puesto que lo usará nuestro Asesor Experto para determinar su orden y operaciones comerciales abiertas. Más adelante haremos un rastreo de stop para limitar el riesgo de nuestras posiciones con el objetivo de observar la situación.
Hay otro parámetro interesante que necesitaremos: un nivel de seguridad, según el cual vigilaremos la presencia de noticias económicas importantes en todo momento, y si suponen o no una amenaza teniendo en cuenta que la reacción principal en los mercados surge dentro de estas dos horas.
Figura 10. Parámetros de entrada
//--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100;
Procedamos con la siguiente parte de la formación de la estrategia.
Debemos determinar si la sesión fue un cruce, y si las órdenes han sido o están siendo establecidas. (Fig. 11).
Figura 11. Hora de trading
Como puede ver, el algoritmo dado es un programa cerrado con parámetros de entrada, cálculos completos y resultados de salida. Estos mini-programas se llaman funciones, y se protegen del programa principal por encapsulación.
La encapsulación es una barrera entre los programas o partes del programa que se separan con métodos, tal como Get y Set (obtener y establecer), para prevenir que vayan al territorio de otros Gets y Sets. La esencia de este proceso radica en el hecho de que los nombres de las variables pueden ser iguales dentro de las funciones y dentro del mismo programa, pero cuando el método Get intenta tomar algo de una celda con un nombre de variable, se enfrentará a la encapsulación, que solo le dará acceso a un sector particular de celdas de memoria localizadas para esta función o programa.
Lo mismo vale para el método Set, pero a diferencia de Get, establece el valor en la memoria de la celda en el nombre de la variable, y si los nombres de variables dentro del programa y dentro de la función coinciden, entonces la encapsulación no permitirá que el método Set asigne valores de variables dentro de otro programa o función.
bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); }
Hemos identificado la sesión requerida y determinado si tenemos órdenes establecidas o no. Consideremos qué debemos hacer a continuación.
Anteriormente, notamos que las mayores fluctuaciones ocurren 2 horas después de la sesión de apertura en Estados Unidos. Obtenemos 9 barras de quince minutos tras la apertura de la sesión americana. Encontramos el margen máximo para este período y lo consideramos con atención: si esta variación es lo suficientemente grande, entonces lo más seguro es que haya un pánico general en el mercado, y las tendencias futuras serán difícil de predecir. Por tanto, necesitaremos restricciones.
Cuando el mercado se haya calmado, la sesión aumentará en volatilidad. Esto nos dará la oportunidad de determinar la máxima desviación de la tendencia principal, y colocar órdenes-trampa a una distancia segura, lo que funcionará bien porque la tendencia principal continuará. Tal y como notamos antes, el precio podría ir hacia arriba o hacia abajo, pero siembre va hacia la derecha. (Fig. 12).
Figura 12. Algoritmo de orden establecida
Al diseñar el código del programa, ponga atención al hecho de que el terminal de trading MetaTrader 5 no permite el establecimiento de una orden cercana al precio de la última transacción. Si en este momento el precio alcanza un nuevo mínimo o máximo, defenderemos nuestra posición dando un paso atrás a una distancia mínima del precio de la última transacción para determinar una orden con seguridad. Asimismo, estableceremos el período de duración de nuestras órdenes antes de que acabe el día, puesto que más tarde no serán efectivas.
void OnTick() { //--- if(time2trade(America+2,MagicNumber)) { int i; double Highest = 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high;//MathMax(,Highest); if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); // add to the current prices parameters of the minimum distance possible for the setting of orders Lowest=Lowest-StopLevel*Point(); // to ensure the maximum probability of the acceptance of our order 30> if((Higest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; BigDogBuy.action=TRADE_ACTION_PENDING; // Set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //if the stop loss is not set, then set by the strategy /s39> BigDogBuy.tp=Highest+TakeProfit*Point(); //set the take profit/s41> BigDogBuy.deviation=dev; //minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts //with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; // Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //Price, by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //set the take profit BigDogSell.deviation=dev; //Minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts ///with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } }
Las órdenes y las trampas están establecidas. Ahora es el momento de reducir los riesgos de nuestras posiciones, aplicando la tecnología "trailing stop" (stop de rastreo).
Para identificar nuestra posición usaremos el Número Mágico (MagicNumber), y cambiaremos el nivel de stop-loss cuando llegue a un cierto nivel de rentabilidad con cambios de precio mínimos (Figura 13).
Figura 13. Implementación de stop de rastreo
Para las diferentes estrategias, el stop de rastreo se implementa usando el método más simple, aunque en algunas estrategias se recomienda no usar un stop de rastreo para no evitar que el precio alcance su objetivo o use este mecanismo solo para transferir posiciones a no-loss. Pero en esta estrategia aplicaremos el mecanismo clásico para mover el stop protector, en caso de cambios en el precio, en nuestra dirección para un determinado número de cambios de precio mínimos.
//--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } }
Lo siguiente es recopilar nuestro algoritmo (Fig. 14).
Fig. 14. Recopilar un algoritmo
//+------------------------------------------------------------------+ //| BigDog_By_CoreWinTT.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100; int dev=30; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(time2trade(America+2,int(MagicNumber))) { int i; double Highest= 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high; if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); //--- add to the current prices the parameters of a minimum possible distance for the order set. Lowest=Lowest-StopLevel*Point(); //--- to ensure the maximum probability of the acceptance of our order. if((Highest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; ZeroMemory(BigDogBuy); ZeroMemory(BigDogSell); BigDogBuy.action=TRADE_ACTION_PENDING; //--- set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //--- Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //--- if the stop loss is not established, then we set by the strategy BigDogBuy.tp=Highest+TakeProfit*Point(); //--- set the take profit BigDogBuy.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //--- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; //-- Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //--- Price by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //-- Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //--- Set take profit BigDogSell.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //-- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; ZeroMemory(ResultBuy); ZeroMemory(ResultSell); OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } } //--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } } //+------------------------------------------------------------------+
Conclusión
Hay muchos fenómenos de mercado que ocurren periódica y regularmente, y cuando se investigan, nos pueden reportar ciertas ventajas. También, quizás, traders experimentados pueden notar algunas coincidencias en la conocida estrategia "BigDog". El artículo no menciona esto, y yo lo he hecho así a propósito, para que el lector mismo piense en cómo se preparan realmente.
En Internet podrá familiarizarse con las diferentes variaciones de esta estrategia. Este artículo solo trata el fenómeno en el que se basa la estrategia.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/59
![Crear y Publicar Informes de Trading y Notificaciones SMS](https://c.mql5.com/2/0/trade_reports_SMS_MQL5.png)
![Algoritmos Genéticos: ¡Es fácil!](https://c.mql5.com/2/0/genetic_algorithms_MQL5.png)
![La estrategia "Todo o Nada" en Forex](https://c.mql5.com/2/0/allVSzero.png)
![MQL para "Dummies": Cómo Diseñar y Construir Clases de Objetos](https://c.mql5.com/2/0/cube__1.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