Recetas MQL5 - procesamiento del evento BookEvent
Introducción
El terminal comercial MetaTrader 5, como ya se sabe, es una plataforma multimercado. Con su ayuda se puede comerciar en los mercados: Forex (Forex), mercados de fondos (bolsas), Futuros y Contratos por diferencia. A juzgar por los encargos en el apartado Freelance, la cantidad de traders que comercia no solo en Forex está creciendo.
En este artículo me gustaría ayudar al programador principiante de MQL5 a familiarizarse con el procesador de evento BookEvent. Este evento está relacionado con la profundidad de la bolsa, que más bien se constituye como un instrumento del trader que comercia con activos de fondos y sus derivados. Sin embargo, para los traders de Forex, la profundidad también puede resultar útil. En la actualidad están adquiriendo mayor popularidad las así llamadas cuentas ECN, donde los suministradores de liquidez proporcionan información sobre las solicitudes, aunque sea solo en el marco de su modelo de agregador.
1. Evento BookEvent
De acuerdo con la Documentación, este evento aparece al cambiar el estado de la profundidad de mercado. Supongamos que el evento BookEvent es un "evento de profundidad".
La propia profundidad es una matriz de solicitudes que se distinguen por su dirección (sell y buy), por su precio y por su volumen. Los precios en la profundidad están distribuidos junto a los de mercado, por eso se consideran mejores.
Fig.1 Profundidad de mercado en MetaTrader 5
En MetaTrader 5 la profundidad se llama «Profundidad de mercado» (fig.1). Puede obtener mayor información sobre la profundidad de mercado en la Guía del usuario del terminal de cliente.
Merece la pena decir unas cuantas palabras sobre la estructura informativa en la profundidad de mercado.
struct MqlBookInfo { ENUM_BOOK_TYPE type; // tipo de solicitud de la enumeración ENUM_BOOK_TYPE double price; // precio long volume; // volumen };
Contiene 3 campos. Tras procesar la estructura de la solicitud se puede obtener los datos sobre el tipo de solicitud, el precio de la solicitud y su volumen.
2. Procesamiento del evento BookEvent
La función-procesador OnBookEvent() adopta como parámetros una constante: la referencia al parámetro de línea.
void OnBookEvent (const string& symbol)
El parámetro de línea contiene el nombre del símbolo para el cual ha tenido lugar el evento de profundidad.
El propio procesador exige una preparación previa. Para que el asesor puede procesar los eventos de la profundidad, hay que suscribirse a este evento. Esto se hace con la ayuda de la función incorporada MarketBookAdd(). Normalmente se encuentra en el bloque de inicialización de funcionamiento del asesor. De no realizarse la suscripción al evento de profundidad, el asesor no reaccionará a él en manera alguna.
Resulta muy útil disponer de la desinscripción de un evento. Al llevar a cabo la desinicialización hay que desinscribirse de la recepción de estos datos, llamando la función MarketBookRelease().
El mecanismo de inscripción-desinscripción recuerda la creación y el procesamiento del temporizador, antes de procesar el temporizador, es necesario activarlo.
3. Platilla de procesamiento del evento BookEvent
Vamos a crear una plantilla simple, un asesor que llama a la función OnBookEvent(). Lo llamaremos BookEventProcessor1.mq5.
En la plantilla se dispone de un kit mínimo: los procesadores de la inicialización y la desinicialización del asesor, así como el procesador del evento de la profundidad.
El propio procesador del evento de profundidad tiene un aspecto extremadamente sencillo:
//+------------------------------------------------------------------+ //| BookEvent function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { Print("Book event for: "+symbol); //--- select the symbol if(symbol==_Symbol) { //--- array of the DOM structures MqlBookInfo last_bookArray[]; //--- get the book if(MarketBookGet(_Symbol,last_bookArray)) { //--- process book data for(int idx=0;idx<ArraySize(last_bookArray);idx++) { MqlBookInfo curr_info=last_bookArray[idx]; //--- print PrintFormat("Type: %s",EnumToString(curr_info.type)); PrintFormat("Price: %0."+IntegerToString(_Digits)+"f",curr_info.price); PrintFormat("Volume: %d",curr_info.volume); } } } }
Dado que el evento de la profundidad tiene un gran volumen (después de la suscripción aparecerá para todos los instrumentos), hay que elegir solo nuestro propio instrumento.
Sin embargo, hago notar que en los últimos builds ha habido cambios en el funcionamiento de la profundidad. En la versión actual, el Build 975, no he encontrado una gran voluminosidad, pues el procesador era llamado solo para "su propio" instrumento. Para confirmar este hecho, simplemente he añadido la representación de la información en el registro "Expertos".
Después de esto, recurrimos a la función incorporada MarketBookGet(). Esta retornará aquí la "distribución" por la profundidad, la matriz de estructuras MqlBookInfo, que contiene las anotaciones sobre la profundidad de mercado del símbolo indicado. Llamo la atención sobre el hecho de que esta matriz tendrá dimensiones diferentes, dependiendo del bróker.
La plantilla permite imprimir en el registro el valor de las estructuras de la matriz.
He puesto en marcha el asesor en régimen de depuración para el futuro SBRF-12.14. Obtendremos la siguiente secuencia de entradas en el registro:
EL 0 11:24:32.250 BookEventProcessor1 (SBRF-12.14,M1) Book event for: SBRF-12.14 MF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7708 LJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 6 MP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL HF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7705 LP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 6 MJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL GL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7704 ON 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 MD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL FR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7703 PD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 MN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL DH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7701 QQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 10 GH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL QM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7700 OK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1011 ER 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7698 EE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 50 OM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7696 IO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 21 QG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL LO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7695 MK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1 QQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL KE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7694 QQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 5 QK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL PK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7691 LO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 QE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL HQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7688 OE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 106 MO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL RG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7686 IP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 18 GI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL FL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7684 QI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 GS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL IR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7681 LG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 4 GM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL JH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7680 RM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 GG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL DN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7679 HH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 19 IQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL ED 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7678 EQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1 IK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL OJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7676 DO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 IE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_SELL RP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7675 EE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 1 QR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY LF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7671 LP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 40 QD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY KL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7670 QJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 21 QN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY CR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7669 RD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 20 QP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY DH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7668 NN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 17 QJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY QN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7667 RK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 OL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY DE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7666 MQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 151 QF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY OJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7665 RO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 OH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY FQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7664 EF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 49 OR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY GG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7663 OS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 ED 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY JM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7662 PI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 4 CN 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY ES 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7661 LD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 13 CP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY FI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7660 LM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 2 IJ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7659 II 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 12 IL 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY ME 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7658 IP 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 3 GF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7657 FM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 15 GH 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY MQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7656 DD 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 6 MS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NG 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7655 KR 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 9 KE 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY OM 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7654 IK 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 14 KO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY NS 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7653 DF 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 534 MQ 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Type: BOOK_TYPE_BUY OI 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Price: 7652 IO 0 11:24:33.812 BookEventProcessor1 (SBRF-12.14,M1) Volume: 25
Esta es la forma de la profundidad en un momento dado. El primer elemento de la matriz de estructuras es la solicitud de venta al precio más alto (7708 rub.). El último elemento es la solicitud de venta al precio más bajo (7652 rub.). De esta forma, los datos de la profundidad se calculan en la matriz de arriba hacia abajo.
Para visualizarlo todo mejor, reuniré estos datos en el recuadro 1.
Recuadro 1. Profundidad de mercado para SBRF-12.14
El bloque rojo superior es la solicitud de venta (sell-limits). El bloque verde inferior es la solicitud de compra (buy-limits).
Podemos notar que entre las solicitudes de venta, la más grande por volumen era la número 6, con un precio de 7700 rub. y un volumen de 1011 lotes. La solicitud de compra más grande por volumen fue la número 39, con un precio de 7653 rub. y 534 lotes.
Los datos de origen en la profundidad pueden representar el alimento para la reflexión que el trader "mastica" a la hora de crear su estrategia. La idea comercial más sencilla consiste en que las desviaciones y agrupamientos de las solitudes con un gran volumen crean zonas de resistencia y apoyo en los niveles de precios colindantes. En el siguiente apartado probaremos a crear un indicador que realizará un seguimiento de los cambios en la profundidad.
4. Profundidad de mercado
Quiero destacar que hay una gran cantidad de indicadores de diferente naturaleza que funcionan conforme a los datos de la profundidad. Por ejemplo, en el Mercado para MetaTrader 5 existen también varios programas interesantes. Me ha gustado en especial el panel IShift. Su autor, Yury Kulikov, logró crear un instrumento bastante compacto e informativo.
Todos los programas que trabajen según los datos del fondo de mercado, serán por su forma o bien asesores, o bien indicadores, dado que el procesador de eventos BookEvent existe solo en estos programas MQL5.
Vamos a probar a crear un pequeño programa que comience a visualizar la profundidad de mercado en régimen de tiempo real.
¿Qué se debe mostrar en la pantalla? Pues un panel donde las filas horizontales mostrarán la magnitud del volumen de la solicitud. Además, su tamaño tendrá un carácter relativo. Por el 100% se toma el volumen máximo según todas las solicitudes en el momento actual. En la fig. 2 el volumen mayor los posee la solicitud al precio 7507 rub. (519 lotes).
Para que la inicialización del panel sea correcta, hay que inidicar exactamente la profundidad, el número de niveles (parámetro "DOM depth"). Este parámetro puede diferenciarse, dependiendo del bróker.
Fig. 2 Panel de la profundidad de mercado
El código del programa para el panel se ha escrito utilizando la POO. La clase responsable del funcionamiento del panel se llama CBookBarsPanel.
//+------------------------------------------------------------------+ //| Book bars class | //+------------------------------------------------------------------+ class CBookBarsPanel { private: //--- Data members CArrayObj m_obj_arr; uint m_arr_size; //--- uint m_width; uint m_height; //--- Methods public: void CBookBarsPanel(const uint _arr_size); void ~CBookBarsPanel(void){}; //--- bool Init(const uint _width,const uint _height); void Deinit(void){this.m_obj_arr.Clear();}; void Refresh(const MqlBookInfo &_bookArray[]); };
En la clase hay 4 miembros-datos.
El atributo m_obj_arr es el container para el índice a los objetos del tipo CObject. Es necesario para guardar las entradas sobre la profundidad. Para ellos se creará una clase por separado.
El atributo m_arr_size es responsable del número de niveles de la profundidad.
Los atributos m_width y m_height se encargan de guardar las dimensiones del panel (anchura y altura en píxeles).
En lo que respecta a los métodos, a excepción del constructor y el destructor estándar, su conjunto es el siguiente:
- Método de inicialización;
- Método de desinicialización;
- Método de actualización.
Para cada línea del panel (nivel de la profundidad), donde se indica el precio, una fila horizontal y el volumen, crearemos su propia clase CBookRecord.
En ella habrá 3 índices: uno al objeto del tipo CChartObjectRectLabel (una marca rectangular para trabajar con la fila) y dos índices para el tipo CChartObjectLabel (marcas de texto para el precio y el volumen).
//+------------------------------------------------------------------+ //| Book record class | //+------------------------------------------------------------------+ class CBookRecord : public CObject { private: //--- Data members CChartObjectRectLabel *m_rect; CChartObjectLabel *m_price; CChartObjectLabel *m_vol; //--- color m_color; //--- Methods public: void CBookRecord(void); void ~CBookRecord(void); bool Create(const string _name,const color _color,const int _X, const int _Y,const int _X_size,const int _Y_size); //--- data bool DataSet(const long _vol,const double _pr,const uint _len); bool DataGet(long &_vol,double &_pr) const; private: string StringVolumeFormat(const long _vol); };
Entre los métodos hay:
- un método para crear entradas;
- un método para establecer datos;
- un método para obtener datos;
- un método para formatear grandes cifras.
Entonces, el procesador BookEvent, para el propio asesor, y en cierta manera para el indicador, tendrá el código siguiente:
//+------------------------------------------------------------------+ //| BookEvent function | //+------------------------------------------------------------------+ void OnBookEvent(const string &symbol) { //--- select the symbol if(symbol==_Symbol) { //--- array of the DOM structures MqlBookInfo last_bookArray[]; //--- get the book if(MarketBookGet(_Symbol,last_bookArray)) //--- refresh panel myPanel.Refresh(last_bookArray); } }
De esta forma, cada vez que se active BookEvent, el panel actualizará sus datos. Llamaremos a la nueva versión del programa BookEventProcessor2.mq5.
El funcionamiento del asesor en movimiento se muestra en el vídeo.
Conclusión
Este artículo se ha dedicado al siguiente evento del terminal, el evento de la profundidad. A él recurren con frecuencia los algoritmos comerciales, cuya naturaleza está más relacionada con el comercio de alta frecuencia (HFT). Este va cobrando cada vez más popularidad entre los traders.
Espero que el material con ejemplos del procesamiento del evento de profundidad le sea útil a los programadores principiantes en el lenguaje MQL5.
Es cómodo distribuir los archivos de origen del archivo general en la carpeta de proyectos. En mi caso, se trata de la carpeta %MQL5\Projects\BookEvent.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/1179
- 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