MQL prácticamente. Parte de Algo Trader I [Curso de programación]

MQL Praktycznie. Algo Trader cz. I [Kurs programowania]

En el episodio de hoy, comenzaremos a trabajar en un software que le permitirá aprovechar las oportunidades que ofrece el comercio algorítmico mientras mantiene el máximo control sobre el curso de los eventos. Nos centraremos en ideas que le permitan participar en operaciones reales maximizando la intuición de uso y la flexibilidad de las funciones. El software utilizará una interfaz cuyo formato es considerado por muchos como un estándar en la industria del comercio diario y a menudo se denomina escalera de precios

algotrader
Comerciante de Algo – Interfaz

Plan de proyecto

Dividiremos el trabajo en varias etapas, porque además del procesamiento amplio de órdenes, Algo Trader le permitirá ejecutar algoritmos que gestionarán automáticamente la posición según varias combinaciones que podrá crear dependiendo de la situación que encuentre en el mercado. mercado.

En la parte de hoy daremos el primer paso en el mundo de la programación orientada a objetos y lanzaremos la parte elemental de nuestro proyecto relacionada con la interfaz y el soporte para operaciones básicas.

En los próximos episodios empezaremos a trabajar en los primeros algoritmos. Primero, crearemos un algoritmo GTP que asegurará que la posición se cierre con el beneficio esperado, independientemente de cuántas órdenes conste. A continuación, crearemos un algoritmo OOO (uno abre el otro, para ser precisos, nunca antes existió) y, finalmente, un algoritmo que permita el scalping al presentar datos macro importantes. Junto con los algoritmos, agregaremos algunos gadgets interesantes aquí y allá.

Experiencia técnica

Puedes encontrar el paquete con los archivos que necesitas para hoy en este enlace:

El uso del software constituye la aceptación de la licencia incluida con el conjunto de archivos.

Para que el software funcione correctamente, necesita la versión mínima de Microsoft NET Framework. 4.6.1 Runtime que se puede descargar aquí:

Programación orientada a objetos

Crearemos nuestro software usando programación orientada a objetos, es decir, un método de programación que permite la disposición lógica de fragmentos del algoritmo en el llamado objetos cuya tarea es implementar funciones separadas y comunicarse con otros objetos para implementar la tarea del programa en su conjunto. Para seguir adelante, necesitaremos comprender qué objetos existen en la práctica y cómo se crean. Para ello, eche un vistazo al siguiente artículo de Wikilibros, que, utilizando el ejemplo del lenguaje C++ en el que se basa MQL4, le permitirá comprender los conceptos básicos necesarios.

LEER EL ARTÍCULO

Primera clase

Como puedes ver, todo gira en torno a la palabra clave. clase. Nos permite definir un objeto, que luego podemos crear usando una palabra clave. new. Abra el archivo que contiene la definición de una de las clases que usaremos hoy, archivo OperacionesGráficas.mqh, que encontrarás en el catálogo MQL4\Incluir\AlgoTrader_v10.

clase cOperacionesGráficas { pública: cOperacionesGráficas(int anchura, int altura) { // ... } vacío Onclick(int x, int y) { // ... } vacío En cambio de gráfico() { // ... } privada: int Ancho_gráfico; int Altura_gráfico; uint último_clic; int último_clic_x, último_clic_y; bool esdoble clic(int x, int y) { // ... } };

 

 

Cada clase tiene un constructor, que en la práctica es una función que se llama automáticamente cuando se crea el objeto. El constructor tiene el mismo nombre que el objeto y puede tomar parámetros. En nuestro fragmento de código anterior, creamos el constructor de la siguiente manera:

cOperacionesGráficas(int anchura, int altura) { }

 

Después de crear el constructor, podemos definir los componentes de la clase, es decir, funciones y variables. Se definen exactamente como en el caso de las funciones y variables regulares, con la diferencia de que se definen en el cuerpo de la clase. Presta atención a las palabras clave pública: oraz privada:. Todas las funciones y variables que vienen después de la palabra. pública: estará disponible para funciones que residen en otras partes del software, p. Al marcar() u otros objetos. Privado sin embargo, informa al compilador que los elementos que se definen en esta parte son de alto secreto y nadie, excepto el objeto dado, puede tener acceso a ellos bajo ninguna circunstancia.

Usos de los objetos

¿Qué hace que los objetos sean tan útiles? Entre otras cosas, el hecho de que una vez definido un objeto, podemos crear cualquier cantidad de copias y, dependiendo de los parámetros que se les proporcionen, se comportarán de manera diferente, pero de una manera que podamos analizar y controlar. Además, los objetos permiten una organización clara del código al dividir los componentes del algoritmo en elementos separados, y un objeto diseñado correctamente se puede utilizar en software completamente diferente, lo que permite una creación más efectiva de aplicaciones complejas.


asesores expertos


Lanzamos el primer objeto.

Vayamos al archivo principal de nuestro software, archivo AlgoTrader_v10.mq4, que encontrarás en el catálogo MQL4\Expertos\.

Echemos un vistazo a la definición de la función API a continuación. Al iniciar():

cOperacionesGráficas* GráficoOperaciones = NULL; int OnInit() { //(…) int ancho_del gráfico = (int)GráficoGetInteger(0, CHART_WIDTH_IN_PIXELS); int altura_del gráfico = (int)GráficoGetInteger(0, CHART_HEIGHT_IN_PIXELS); GráficoOperaciones = new cOperacionesGráficas(ancho_gráfico, altura_del gráfico); volvemos(INIT_SUCCEEDED); }

puntero

En la parte del archivo responsable de definir variables globales usando un fragmento de código...

cOperacionesGráficas* GráficoOperaciones = NULL;

 

...creamos el llamado puntero es decir, un puntero que contendrá la dirección del lugar en la memoria del ordenador donde posteriormente se creará nuestro objeto. Usando un puntero, podremos referirnos a un objeto y llamar a sus funciones. Consejos Lo definimos de manera similar a las variables, el primer elemento de la notación es el tipo de objeto, luego ponemos un asterisco * , después de lo cual establecemos un nombre único para el objeto, que luego usaremos como referencia. Para nuestro puntero asignamos una variable NULL, que dice que en esta etapa aún no apunta a ningún objeto.

constructor

Más adelante en el código, en el cuerpo de la función. Al iniciar() Creamos el objeto real usando la palabra clave. new.

GráficoOperaciones = new cOperacionesGráficas(ancho_gráfico, altura_del gráfico);

 

Po new llamamos al constructor del objeto, que en nuestro caso acepta dos variables que informan al objeto sobre las dimensiones de nuestro gráfico, porque lo necesitamos para ubicar adecuadamente nuestra interfaz. El constructor llamado pasa la dirección del objeto recién creado en la memoria de la computadora a la nuestra. puntero llamado GráficoOperaciones.

destructor

Los objetos son un tipo especial de datos que, si los creamos, debemos asegurarnos de que finalmente sean eliminados de la memoria del ordenador. Todo ello para que no sea necesario tener un gran servidor al lado de tu portátil recopilando datos creados previamente que ya no son necesarios para nadie.

Usamos una palabra clave para eliminar objetos. borrar, después del cual ponemos nuestro nombre puntero indicando a qué objeto nos referimos. Eliminamos nuestro objeto solo en la función API. EnDeinit(…), porque lo necesitamos durante todo el ciclo de vida de la aplicación, hasta que se apaga el software.

vacío OnDeinit(const int razón) { //(…) borrar Operaciones gráficas; }

Trabajar con objetos

Ahora veamos cómo podemos usar nuestro objeto creado para las necesidades de nuestra aplicación. Para ello en el cuerpo de la clase cOperacionesGráficas Hemos definido varias funciones. Veamos uno de ellos:

vacío Onclick(int x, int y) { if(esdoble clic(x, y)) Ir al precio(x, y); }

 

función Al hacer clic(…) lo necesitamos para comunicar a nuestra interfaz qué niveles de precios nos interesan actualmente. Al hacer doble clic en el gráfico, el algoritmo colocará nuestra escala de precios en el lugar indicado. Para que nuestra función funcione, necesitamos detectar el momento en el que hacemos clic en el gráfico, y aquí es donde la función API resulta útil En el evento del gráfico(…)

vacío En el evento del gráfico(const int carné de identidad, const long &lparam, const doble &dparam, const cadena &sparam) { //(…) if(id == CHARTEVENT_CLICK) ChartOperations.OnClick((int)lparam, (int)param); }

 

El fragmento de código anterior reconoce el momento en que el usuario hace clic en el gráfico y luego llama a la función que está dentro de nuestro objeto creado previamente. Llamar a una función implica colocar un punto después de nuestro nombre puntero al objeto, y luego pasando el nombre de la función que nos interesa junto con los parámetros que necesita, que en nuestro caso significan las coordenadas xey del lugar del gráfico donde hicimos clic.

Primeros efectos

Los procedimientos que creamos lanzaron la primera funcionalidad del software, que podemos probar compilando nuestro programa y haciendo clic en diferentes lugares del gráfico. A continuación encontrará un gráfico que presenta varias funciones que le permiten manipular los niveles de precios que se muestran en nuestra interfaz gráfica.

programación mql
Algo Trader: mouse y niveles de precios

Segunda clase

Ya que has ascendido a segunda clase y para que nuestros clics no sean en vano, diseñaremos un segundo objeto que te permitirá realizar pedidos desde nuestra escalera. Para ello hemos preparado una clase adecuada, que se puede encontrar en el archivo MQL4\Include\AlgoTrader_v10\OrderOperations.mqh

clase cOrdenOperaciones { pública: cOrdenOperaciones(int position_id) { ID_posición = posición_id; } vacío OnTimer200ms() { Procesar solicitudes de pedidos(); } privada: int Posición_id; vacío Procesar solicitudes de pedidos() { sSolicitud de pedido solicita = LeerSolicitud de pedido(); if(solicitud.Request_id <= 0) volver; if(solicitud.Símbolo_pedido != Símbolo() || solicitud.Position_id != ID_posición) { solicitud.Request_status = ORDER_REQUEST_STATUS_FAILED; solicitud.Request_error = ORDER_REQUEST_ERROR_WRONG_POSITION; volver; } if(OrdenEnviar(solicitud.Símbolo_pedido, solicitud.Tipo_pedido, solicitud.Order_volume, solicitud.Pedido_precio, 0, 0, 0, solicitud.Orden_comentario, solicitud.Position_id) > 0) { solicitud.Request_status = ORDER_REQUEST_STATUS_COMPLETED; } más { solicitud.Request_status = ORDER_REQUEST_STATUS_FAILED; solicitud.Request_error = _ÚltimoError; } ActualizarSolicitud de pedido(solicita); } };

En el código anterior puedes ver la definición completa del objeto. cOrdenOperaciones, que se utilizará para gestionar los pedidos que colocaremos en nuestra escala de precios. Presta atención a la función. Solicitudes de pedido de proceso(), en el que nuestro programa se comunica con la biblioteca DLL usando funciones Solicitud de pedido de lectura().

Estructuras

función Solicitud de pedido de lectura() devuelve una estructura de tipos como resultado de su operación sSolicitud de pedido, que es un conjunto de datos definidos por nosotros sobre el pedido enviado a través de la interfaz.

vacío Procesar solicitudes de pedidos() { sSolicitud de pedido solicita = LeerSolicitud de pedido(); //(…) }

Las estructuras son las hermanas menores de las clases que te permiten crear un bloque de datos que contiene muchas variables. Esto permite la organización lógica de la información relacionada con un tema determinado. En nuestro caso, la estructura recopila datos sobre la orden enviada a través de nuestra interfaz gráfica, como el precio de apertura o el volumen. Definimos una estructura precediendo su nombre con una palabra clave. struct, y luego establecemos una lista de los datos que necesitamos.

struct sSolicitud de pedido { int solicitud_id; int Posición_id; int tipo de orden; doble volumen_pedido; doble precio del pedido; doble rango_orden; cadena símbolo_pedido; cadena comentario_pedido; int estado de la solicitud; int solicitud de error; };

 

La definición anterior se puede encontrar en el archivo. MQL4\Include\AlgoTrader_v10\Definitions.mqh.

Usamos estructuras de manera similar a las variables, es decir, en el primer paso debemos crearlas especificando el tipo de estructura y luego darle un nombre único al que podamos referirnos más adelante. En el siguiente ejemplo, creamos una estructura de tipos. sSolicitud de pedido y darle un nombre único solicita, y luego le asignamos datos desde nuestra interfaz usando una función Solicitud de pedido de lectura().

vacío Procesar solicitudes de pedidos() { sSolicitud de pedido solicita = LeerSolicitud de pedido(); //(…) }

 

Acceder a los datos almacenados en una estructura es análogo a usar variables, porque en la práctica la estructura es solo un conjunto de variables ocultas bajo un identificador común. Para leer o guardar datos en una estructura, simplemente coloca un punto después del nombre que le diste y luego indica el nombre de la variable que te interesa. En el siguiente fragmento de código leemos los datos almacenados en la estructura para enviar la orden y luego escribimos información sobre el resultado de la operación.

if(OrdenEnviar(solicitud.Símbolo_pedido, solicitud.Tipo_pedido, solicitud.Order_volume, solicitud.Pedido_precio, 0, 0, 0, solicitud.Orden_comentario, solicitud.Position_id) > 0) { solicitud.Request_status = ORDER_REQUEST_STATUS_COMPLETED; }

Ejecución de órdenes

Para que nuestro software pueda realizar pedidos, debemos implementar un objeto creado en base a la clase cOrdenOperaciones. Dado que necesitaremos el objeto desde el momento en que ejecutamos nuestro programa, lo creamos en la función API. Al iniciar().

Las opciones de entrada int ID_posición = 8821; //Identificador único del artículo cOrdenOperaciones* OrdenOperaciones = NULL; int OnInit() { EventSetMilisegundoTemporizador(200); //(…) OrdenOperaciones = new cOrdenOperaciones(ID_posición); volvemos(INIT_SUCCEEDED); }

 

en el constructor cOrdenOperaciones ponemos una variable ID_posición, que forma parte de la configuración de nuestra aplicación disponible en la ventana predeterminada de la plataforma MetaTrader. El identificador permite que nuestro software reconozca sus propios pedidos para que no se confundan con pedidos de otras fuentes.

En el código anterior también ejecutamos Minutero con un intervalo de 200 ms, porque nuestro objeto debe verificar periódicamente si la interfaz no envía información sobre el próximo pedido.

vacío A tiempo() { //(…) Operaciones de pedido.OnTimer200ms(); }

 

Función de objeto OnTimer200ms() llamará a la función Solicitudes de pedido de proceso(), que realizará el pedido cuando reciba los datos adecuados de la interfaz.

clase cOrdenOperaciones { pública: cOrdenOperaciones(int position_id) { ID_posición = posición_id; } vacío OnTimer200ms() { Procesar solicitudes de pedidos(); } //(…) };

efectos

Nuestro software ahora puede comunicarse con la interfaz gráfica y podemos hacer lo que más nos guste, es decir, compilar el algoritmo y realizar un nuevo pedido. Para facilitar sus primeros pasos, a continuación encontrará algunos consejos que ilustran qué funciones se esconden bajo varias teclas.

Control del volumen

volumen de divisas
Algo Trader: soporte de volumen

tipos de pedidos

algo comercial
Algo Trader – Procesamiento de pedidos

Podsumowanie

Eso es todo por hoy, pero esto es sólo el comienzo de la aventura. Comerciante de algo. En el próximo episodio, pasaremos a implementar funciones avanzadas relacionadas con la compatibilidad con algoritmos. Algo Trader se creará junto con usted y estaremos agradecidos por cualquier idea y comentario que pueda mejorarlo para usted. Estaremos encantados de saber de usted en: famecos-pg@pucrs.br .