Português
preview
Desarrollo de un sistema de repetición (Parte 78): Un nuevo Chart Trade (V)

Desarrollo de un sistema de repetición (Parte 78): Un nuevo Chart Trade (V)

MetaTrader 5Ejemplos |
196 0
Daniel Jose
Daniel Jose

Introducción

En el artículo anterior «Desarrollo de un sistema de repetición (Parte 77): Un nuevo Chart Trade (IV), expliqué con todo detalle, y tratando de no complicar lo que, en muchos casos, es bastante complicado, cómo desarrollar un protocolo de comunicación. De este modo, podrás transferir información entre aplicaciones o programas distintos, estén estos en el mismo entorno o no. En este caso, queremos hacer que el indicador Chart Trade le diga al Asesor Experto lo que debe hacer. Es decir, cuando el usuario diga a Chart Trade que desea vender, el Asesor Experto venderá. Cuando el usuario diga que desea comprar, el Asesor Experto comprará a precio de mercado.

Así pues, en estos últimos artículos, me he centrado básicamente en presentar los motivos por los cuales deberíamos crear el indicador Chart Trade. Pero, principalmente, en cómo preparar un protocolo de mensajes incluso antes de intentar codificar cualquier otra cosa. Aunque, hasta ahora sólo nos hemos centrado en la parte del indicador.

Sin embargo, la explicación no estará completa sin que primero conozcas la parte del receptor, que se encuentra presente en el Asesor Experto. Esto se debe a que MetaTrader 5 prohíbe a cualquier indicador enviar órdenes, manipular posiciones o hacer cualquier cosa que esté directamente relacionada con el sistema responsable de comunicar al servidor de trading que algo debe ocurrir. Esto se debe a que esa acción podría ser la apertura, el cierre o incluso el cambio en la composición de una posición u orden.

Aunque aquí hay algo que algunos podrían considerar una brecha, en realidad se trata de otra cosa que exploraremos en el futuro. Esto para desarrollar otra herramienta que realmente necesitaremos y que será muy útil. Pero este será tema de algunos artículos más adelante, ya que todavía estamos en las primeras etapas del sistema de órdenes.

En este momento, nuestra preocupación es otra. En este caso, nuestra principal preocupación es tratar de entender cómo el Asesor Experto logra saber lo que está ocurriendo. Esto se debe a que el usuario no interactuará de ninguna manera con el Asesor Experto. En otras palabras, el usuario realmente va a interactuar con el indicador Chart Trade para decirle al Asesor Experto lo que debe hacer. Pues de nada sirve tener el indicador Chart Trade si el responsable de enviar las órdenes al mercado, ya sea para abrir o cerrar una posición, no consigue saber lo que está pasando. Recuerda que quien realmente tiene el permiso para hacer esto es el Asesor Experto. Ningún otro programa puede hacer esto en MetaTrader 5.

Así que, en este artículo, el enfoque principal será: 


¿Cómo el Asesor Experto logra entender el Chart Trade?

Empecemos este tema con esta pregunta en mente. Si no tienes claro cómo ocurre esto, te aconsejo que primero entiendas el artículo anterior, donde explico cómo diseñar un protocolo de mensajes. Pues aquí vamos a ver cómo hacer que funcione la magia. Esto se debe a que ni el indicador Chart Trade ni el Asesor Experto saben de la existencia uno del otro. Y ni siquiera necesitan saberlo; basta con que ambos confíen en que el mensaje será entregado y comprendido. 

Sin embargo, incluso sin saber que hay un Asesor Experto en el gráfico, el indicador Chart Trade logra que el Asesor Experto llegue a saber lo que el usuario desea hacer. Este tipo de cosa es bastante interesante de observar.

Pero, sobre todo, si logras entender esto, conseguirás que tus programas o aplicaciones que se ejecuten en MetaTrader 5 sean mucho más versátiles. Además, este conocimiento va mucho más allá de MetaTrader 5.

Sí, mi querido lector. Este tipo de cosa —que es el intercambio de mensajes entre programas o procesos— también se utiliza en sistemas operativos, tales como Windows, Linux y MacOS. Todos, y absolutamente todos los sistemas modernos, se basan en esta premisa, en la que tú desarrollas diversos programas más simples, pero capaces de comunicarse entre sí. Con esto, tú consigues crear un ecosistema bastante amplio y sostenible.

Esto se debe a que cada aplicación puede estar optimizada para una tarea concreta. Pero, al colocarlas en conjunto, pueden ejecutar cualquier tipo de tarea imaginable con un coste bastante bajo, tanto en implementación como en mantenimiento o perfeccionamiento.

Así que, a partir de este punto, empieza a olvidar esa idea de crear programas o aplicaciones complejas y llenas de cosas que necesitarán, o que con el tiempo llegarán a necesitar, ser modificadas. Comienza a pensar en crear programas más sencillos. Sin embargo, esta simplicidad siempre conlleva una mayor agilidad para mejorar la propia aplicación. Sé que esto puede resultar novedoso para muchos. Pero créanme, gran parte de la industria realmente trabaja así. Nadie crea algo completamente monolítico, pues hacerlo supone un gran coste y es muy exigente, especialmente a la hora de hacer modificaciones o mejorar el sistema.

Si la aplicación es más simple, será mucho más fácil resolver cualquier problema, e incluso hacer algunos ajustes u optimizar la forma en que estará siendo ejecutada. Por esta razón, el Asesor Experto será programado de forma que haga únicamente lo que MetaTrader 5 exige que solo él haga. Es decir, enviar y modificar órdenes y posiciones. Todo lo demás será ejecutado por otros tipos de programas y aplicaciones.

Para comprender cómo el Asesor Experto entiende el Chart Trade, primero construiremos un código muy sencillo. Créanme, será realmente muy sencillo. En este primer momento, no haremos ningún envío de órdenes, cierre de posición ni cambio de dirección. Insisto, no haremos esto aún, pues solo complicaría las cosas y la explicación en sí.

Necesitamos algo lo más simple posible para que tú, estimado lector y aspirante a programador profesional, entiendas cómo funciona la parte del receptor. Así, lograrás comprender mejor cómo el protocolo de mensajes consigue que el indicador Chart Trade —que no sabe de la existencia del Asesor Experto— haga que este realice alguna acción.

Al mismo tiempo, el Asesor Experto, que desconoce totalmente la existencia del Chart Trade, consigue responder a una solicitud del usuario. Recordando que el usuario no interactuará, en ningún momento, directamente con el Asesor Experto.

Entonces, el código más simple para hacer esto puede verse justo a continuación. Este código se presenta en su totalidad.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Demo version between interaction"
04. #property description "of Chart Trade and Expert Advisor"
05. #property version   "1.78"
06. #property link "https://www.mql5.com/pt/articles/11760"
07. //+------------------------------------------------------------------+
08. #include <Market Replay\Defines.mqh>
09. //+------------------------------------------------------------------+
10. class C_Decode
11. {
12.    private   :
13.       struct stInfoEvent
14.       {
15.          EnumEvents ev;
16.          string     szSymbol;
17.          bool       IsDayTrade;
18.          ushort     Leverange;
19.          double     PointsTake,
20.                     PointsStop;
21.       }info[1];
22.    public   :
23. //+------------------------------------------------------------------+
24.       C_Decode()
25.          {
26.             info[0].szSymbol = _Symbol;
27.          }
28. //+------------------------------------------------------------------+   
29.       bool Decode(const int id, const string sparam)
30.       {
31.          string Res[];
32.       
33.          if (StringSplit(sparam, '?', Res) != 6) return false;
34.          stInfoEvent loc = {(EnumEvents) StringToInteger(Res[0]), Res[1], (bool)(Res[2] == "D"), (ushort) StringToInteger(Res[3]), StringToDouble(Res[4]), StringToDouble(Res[5])};
35.          if ((id == loc.ev) && (loc.szSymbol == info[0].szSymbol)) info[0] = loc;
36.          
37.          ArrayPrint(info, 2);
38.       
39.          return true;
40.       }
41. //+------------------------------------------------------------------+   
42. }*GL_Decode;
43. //+------------------------------------------------------------------+
44. int OnInit()
45. {
46.    GL_Decode = new C_Decode;
47.    
48.    return INIT_SUCCEEDED;
49. }
50. //+------------------------------------------------------------------+
51. void OnTick() {}
52. //+------------------------------------------------------------------+
53. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
54. {
55.    switch (id)
56.    {
57.       case CHARTEVENT_CUSTOM + evChartTradeBuy     :
58.       case CHARTEVENT_CUSTOM + evChartTradeSell    :
59.       case CHARTEVENT_CUSTOM + evChartTradeCloseAll:
60.          (*GL_Decode).Decode(id - CHARTEVENT_CUSTOM, sparam);
61.          break;
62.    }
63. }
64. //+------------------------------------------------------------------+
65. void OnDeinit(const int reason)
66. {
67.    delete GL_Decode;
68. }
69. //+------------------------------------------------------------------+

Código fuente del EA

Caramba, ¿me estás diciendo que este código de arriba es simple? Amigo, no te estoy entendiendo. Este código, para mí, parece muy complicado. No estoy logrando entender prácticamente nada de él. Estoy más perdido que nunca. Si este código es simple, ¿imagina entonces algo complicado? Sí, este código realmente es bastante simple. Sin embargo, está haciendo uso de algunas cosas que muchos de ustedes no usan normalmente. O mejor dicho, muchos ni siquiera saben que es posible usar en MQL5. Entonces, si este es tu caso, y tú pretendes convertirte en un programador profesional en el futuro, sigue la explicación que voy a darte, porque las cosas aquí son mucho más simples de lo que puedan parecer, y el código es bastante directo y objetivo en lo que tiene que hacer.

Pero este conocimiento puede ayudarte a pensar las cosas con más calma. Además, por supuesto, es una forma de divertirse mientras programas. Porque programar es divertido. Si lo ves como un trabajo aburrido, sin gracia, difícil y complicado, te sugiero que empieces a pensar en hacer otra cosa con tu vida y olvides definitivamente el área de programación y desarrollo. Porque, cuando se está programando o desarrollando algo, realmente debes sentirte como un niño en una tienda de dulces. Nunca sabes qué dulce vas a pedir primero.

Pero basta de divagaciones y veamos cómo funciona este código. Las primeras siete líneas no deberían suponer un problema para nadie. Incluso quien esté comenzando no tendrá dificultades para entenderlas. La línea ocho ya es una vieja conocida. Aquí estamos agregando —o, mejor dicho, incluyendo— un archivo en nuestro código. Este archivo es una cabecera, donde se encuentran las definiciones que necesitaremos pronto. ero, en este primer momento, vamos a saltarnos el código que se encuentra entre las líneas 10 y 42. Esto se debe a que ese código se explicará con más calma un poco más adelante. Primero, necesitamos entender algunos detalles pequeños, pero importantes.

Con esto, vamos a la primera función que realmente necesitamos para nuestro código. Se trata de la OnInit, que comienza en la línea 44. Debido a la línea 42, las cosas pueden funcionar de una forma ligeramente diferente a la que muchos imaginan. En la línea 46, hacemos uso del operador new para asignar memoria e inicializar la clase C_Decode. Pero ¿por qué asignar memoria para esto? ¿No sería más sencillo dejar que el compilador se encargara de todo? Sí, en efecto, sería más sencillo dejar que el compilador lo hiciera. Sin embargo, debes acostumbrarte a controlar cuándo y hasta dónde se utilizará una clase. Si lo dejas en manos del compilador, en algunos momentos podrías usar la clase con valores diferentes a los esperados.

Créeme, no es raro que uses una clase con valores diferentes, sobre todo cuando el código es bastante extenso y la clase está declarada en varios puntos distintos. Antes o después, terminas enredándote. Pero, haciendo uso del conjunto de operadores new y delete, podrás definir con toda certeza dónde empieza y dónde termina tu código. Muchos programadores principiantes no consiguen hacerlo. Por extraño que parezca, no saben decir dónde termina el código. Casi siempre, muchos ni siquiera saben dónde comienza. Es extraño, pero sucede.

Entonces, cuando se ejecute la línea 46, esta irá a asignar memoria suficiente para contener la clase C_Decode. Al mismo tiempo, llamará a la línea 24. Esta línea es el constructor de la clase C_Decode. Nota que, en este constructor, tenemos la inicialización de únicamente una variable. Esta mantendrá el nombre del símbolo — o mejor dicho, el nombre del símbolo donde se encuentra el Asesor Experto. Ahora, presta mucha atención a lo siguiente: en este modelo, NO TENDREMOS PERMISO DE ÓRDENES CRUZADAS. En este momento, creo que esto no está realmente claro para ti. Pero continúa leyendo el artículo para entender por qué no tendremos permisos para efectuar operaciones de órdenes cruzadas. Sin embargo, con algunas pequeñas modificaciones podremos hacer uso de órdenes cruzadas. Pero, por ahora, no te preocupes por esto. Recuerda que este código sirve únicamente para entender cómo funciona el protocolo de mensajes. No tiene el propósito de realmente hacer ninguna solicitud al servidor de trading.

Entonces, volvamos a la función OnInit. Después de ejecutar la línea 46, retornamos, en la línea 48, un valor que indica que la inicialización se ha completado con éxito. Es importante informar esto a MetaTrader 5. Esto porque, si el valor que estamos retornando es diferente de INIT_SUCCEEDED, MetaTrader 5 tomará, automáticamente, medidas para desactivar el Asesor Experto. Una de estas medidas es lanzar un evento Deinit, que llamará al procedimiento OnDeinit en el código del Asesor Experto.

Si tu código no contiene este procedimiento, MetaTrader 5 tomará las medidas predeterminadas. De cualquier forma, al final, incluso si tu aplicación permanece listada, no recibirá tiempo de procesador. Es decir, MetaTrader 5 no programará tu aplicación para su ejecución.

Y cualquier tipo de información que esté en el gráfico y que, por casualidad, pertenezca a la aplicación, deberá ignorarse. No es raro que una aplicación cree y coloque objetos en el gráfico. Sin embargo, cuando MetaTrader 5 dispara el evento Deinit, tu código no elimina dichos objetos y elementos del gráfico. Esto se debe a que muchos programadores simplemente ignoran el procedimiento OnDeinit. Entonces, en estos casos, MetaTrader 5 no podrá hacer nada más y los elementos y objetos quedarán allí en el gráfico, dando, en muchas ocasiones, informaciones inválidas o erróneas.

Por esta razón, es buena práctica que te preocupes siempre por implementar el procedimiento OnDeinit. Muchas veces, hará muy poco. Pero, en nuestro caso específico, solo contiene una línea: la 67. En ella, hacemos uso del operador delete para liberar la memoria asignada. En ese momento, se llamará al destructor de la clase C_Decode. Como nuestra clase no tiene un destructor declarado explícitamente, el compilador creará un destructor implícito al ver el uso del operador delete en la clase. Esto es así porque el operador delete realmente necesita un destructor. Pero no necesitas preocuparte por esto. Solo estoy explicando este hecho para que sepas cómo funcionan realmente las cosas.

Muy bien, ahora que ya hemos visto dónde comienza y dónde termina nuestro código del Asesor Experto, podemos pasar a los demás puntos. En la línea 51, tenemos el procedimiento que se llamará cada vez que el símbolo reciba una notificación. Este procedimiento es obligatorio en todos los Asesores Expertos. Pero debes evitar incluir código en este procedimiento o, mejor dicho, colocar código en él. Puedes consultar los motivos en la secuencia de artículos sobre cómo crear un Asesor Experto que opere de forma 100 % automática. Si deseas crear un Asesor Experto con algún nivel de automatización, te sugiero que consultes esa secuencia.

Hay 15 artículos en total, el primero de los cuales puede verse aquí Cómo construir un EA que opere automáticamente (Parte 10): Conceptos y estructuras. Realmente, leer esa secuencia te ayudará mucho. Pero, aquí, en esta secuencia del sistema de repetición/simulación, usaremos algunas cosas que fueron mostradas allá en la secuencia sobre Asesor Experto automático. Pero, de cualquier forma, no dejes de echar un vistazo a la secuencia que mencioné.

Siendo así, podemos ver el otro procedimiento, que se encuentra en la línea 53. Se trata del manejador de eventos OnChartEvent. Ahora es cuando la cosa se pone interesante. Pero, para separar los temas, vamos a ver esto en un nuevo tema.


Cómo decodificar un mensaje recibido en un evento

En artículos pasados, en esta misma secuencia sobre repetición/simulador, expliqué cómo EventChartCustom y OnChartEvent se interconectan. Esto fue intensamente utilizado para hacer que el servicio de repetición/simulador consiguiera transmitir datos al indicador de control. Esto para que el indicador de control pudiera saber en qué punto de la simulación o repetición nos encontrábamos. Si tú no viste o no leíste los artículos al respecto —esto por estar llegando a esta secuencia precisamente en este artículo de aquí— puedes consultarlos y entender cómo se hizo para que el servicio consiguiera enviar datos al indicador de control, revisando los artículos sobre cómo dar play al servicio.

Uno de esos artículos es Desarrollo de un sistema de repetición (Parte 60): Presionando play en el servicio (I). Son siete artículos sobre esto. Sin embargo, debes leer también los demás artículos, ya que te ayudarán a entender los detalles implicados — pero, principalmente, por qué hacer las cosas de esta manera.

Muy bien, en la comunicación entre el servicio y el indicador de control, la comunicación se realizaba mediante parámetros numéricos. Bien, esa era la parte fácil del sistema, ya que la información estaba disponible directamente en los parámetros (lparam o dparam). Pero aquí la cosa cambia. En este punto, usaremos el valor del parámetro sparam. Es decir, el mensaje ahora será una cadena. Y dentro de esta misma cadena es donde se encuentra lo que necesitamos. La información está codificada de alguna forma. La forma en que se hace esa codificación se llama protocolo de mensaje. En el artículo anterior, expliqué este concepto. Aquí aprenderemos a decodificar ese mismo mensaje que se encuentra dentro del protocolo.

Tú debes recordar que, en el artículo anterior, dije que el mensaje iba a contener el evento. Este tipo de cosa servirá para que podamos probar el mensaje aquí en el receptor. Es decir, el Asesor Experto conseguirá verificar si el mensaje realmente no fue corrompido de alguna forma.

Como el mensaje podrá ser decodificado usando el mismo protocolo —esto entre los tres tipos diferentes— podemos hacer lo que se ve entre las líneas 57 y 59. Observa que, allí, tenemos los tres eventos reconocidos y que el Asesor Experto deberá interceptar. Dado que todos los tres podrán pasar por el mismo filtro de decodificación, la única línea realmente usada es la línea 60. Esta línea irá a llamar el código que se encuentra en la línea 29. Ahora, mucha —pero mucha— atención a lo que voy a explicar. Si tú no logras entender la explicación, léela de nuevo, porque es algo muy importante, a pesar de ser muy poco común.

Observa que, en la línea 31, declaramos una variable local, que es un array dinámico. Al ser dinámico, el propio programa se encarga de asignar memoria para él. No necesitamos preocuparnos por él, entonces. Ahora, atención al siguiente hecho: en la línea 33, ejecutamos una llamada a la función StringSplit. Esta tiene como finalidad llenar el array dinámico con cadenas que están separadas por un determinado carácter. En este caso, es el carácter de interrogación. Pero ¿por qué usar este carácter?

El motivo se ve en el artículo pasado. Observa que, en el código mostrado allí, el carácter de interrogación es usado para separar los conjuntos. Pues bien, durante esta separación, se espera que exista un determinado número de cadenas. Si el mensaje está correcta —o mínimamente correcta— el número de cadenas será seis. Es decir, si StringSplit reporta un número menor o mayor, la prueba fallará y tendremos un retorno falso. Si se reportan las seis cadenas esperadas por la función, pasaremos a la línea siguiente.

Ahora, mucha atención a esta línea 34. Esta línea no es algo muy común, pero tampoco es un código alienígena. Para entender lo que está ocurriendo, tú debes ver esta línea 34 en conjunto con la estructura declarada en la línea 13. PRESTA MUCHA ATENCIÓN. Cada elemento presente en la línea 34 tiene un correspondiente y está haciendo referencia a algo en la estructura stInfoEvent. Lo que está siendo hecho no es algo común, pero lo hice intencionalmente para explicar algo. Observa el orden en que las variables están siendo declaradas en la estructura stInfoEvent. Esta observación es muy importante. Ahora, observa el orden en que los valores están siendo colocados en la línea 34. ¡Ay caramba! Vean que coinciden. Entonces, esta línea 34 sería el equivalente al siguiente código:

      stInfoEvent loc;
          
      loc.ev = (EnumEvents) StringToInteger(Res[0]);
      loc.szSymbol = Res[1];
      loc.IsDayTrade = (Res[2] == "D");
      loc.Leverange = (ushort) StringToInteger(Res[3]);
      loc.PointsTake = StringToDouble(Res[4]);
      loc.PointsStop = StringToDouble(Res[5]);

Fragmento de código - Modelo 01

Es exactamente lo mismo. Pero, sin embargo, no obstante y aun así, existe un riesgo al usar el código como se muestra en la línea 34. Y este mismo riesgo no ocurre cuando se usa el código visto en el fragmento. Este riesgo es el cambio en la estructura stInfoEvent. Pero ¿cómo es eso? No entendí por qué cambiar la estructura stInfoEvent es un problema cuando codificamos las cosas como se ve en la línea 34, pero no lo es cuando codificamos como se muestra en el fragmento.

El motivo es bien simple. Tal vez incluso parezca una tontería, y aun así va a dar muchos dolores de cabeza y horas tratando de entender por qué las cosas están saliendo mal. Vamos a imaginar un cambio bien simple: tú, en algún momento, decides intercambiar la variable que está declarada en la línea 19 con la variable declarada en la línea 20. Para un código hecho como se ve en el fragmento, este cambio no va a afectar en nada las cosas.

Sin embargo, para el código visto en la línea 34, la cosa cambia completamente. Esto porque el valor que esperamos colocar en la variable PointsTake será colocado en PointsStop. Y el valor esperado para ser colocado en PointsStop será colocado en PointsTake. Pero ¿qué locura es esta? Estás bromeando. No puede ser. No, estimado lector, esto no es ninguna broma, tampoco una locura.

El motivo por el que esto ocurre tiene que ver con la forma en que el compilador organiza las variables en la memoria. Este tipo de cosas, aunque ayuda en diversos momentos —especialmente cuando programamos en C legado—, a menudo queremos forzar al sistema a ejecutar ciertas cosas. Entonces, hacemos uso de una técnica muy parecida, pero de forma intencional, en la que forzamos al programa a escribir en ciertas regiones de la memoria y, justo después, hacemos un salto hacia esa región. No entraré en detalles sobre cómo hacer esto, pues escapa completamente al alcance e intención de este artículo.

Pero, si tú sabes lo que estás haciendo, puedes lograr cosas que, de otro modo, no sería posible hacer. Entonces, solo utiliza este modo de asignación de valores a una estructura cuando la estructura ya esté completa, totalmente elaborada y cerrada. Y, una vez que esté elaborada, NO DEBERÁS VOLVER A MODIFICARLA. En caso de que la modifiques, deberás revisar todos los puntos de asignación que se parezcan a la línea 34. Para entender exactamente este riesgo, utiliza este código para probar el sistema, solo cambiando esa línea 34 o cambiando el orden en que las variables están declaradas en la estructura stInfoEvent.

Pero continuemos con la explicación. Cuando el código llega a la línea 35, verificamos si las cosas corresponden a lo esperado: tanto el nombre del símbolo como el tipo de evento. Si esto es así, asignaremos el valor a un array estático. ATENCIÓN: esta asignación solo ocurrirá en esta fase de prueba y demostración. Esto es porque necesitamos que la estructura stInfoEvent esté en un array. El motivo es la línea 37. En esta línea, hacemos uso de otra función de MQL5, ArrayPrint. Esta función imprimirá el array para nosotros, de manera que el resultado de su contenido se mostrará en el terminal. El resultado de una de las ejecuciones puede verse en la imagen justo debajo.

Image


Conclusión

Por las razones que expliqué en este artículo, el Asesor Experto aún no puede enviar solicitudes al servidor de trading. Si no entiendes cómo funciona el código y, principalmente, cómo funciona realmente el protocolo de comunicación entre Chart Trade y el Asesor Experto, podrías correr el riesgo de hacer alguna tontería. Pero, aun así, fue interesante dejar las cosas de esta manera, porque aproveché para explicar algo con lo que podrías encontrarte en algún momento y no entender por qué funciona o no.

De cualquier forma, ya tenemos las premisas para lo que se hará en los próximos artículos. En el video de abajo, puedes ver cómo se está comportando el sistema. Entonces, hasta el próximo artículo, porque las cosas serán aún más interesantes.


Traducción del portugués realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/pt/articles/12492

Archivos adjuntos |
Anexo.zip (420.65 KB)
Creación de un Panel de administración de operaciones en MQL5 (Parte III): Ampliación de las clases incorporadas para la gestión de temas (II) Creación de un Panel de administración de operaciones en MQL5 (Parte III): Ampliación de las clases incorporadas para la gestión de temas (II)
En este artículo, ampliaremos cuidadosamente la biblioteca Dialog existente para incorporar la lógica de gestión de temas. Además, integraremos métodos para cambiar de tema en las clases CDialog, CEdit y CButton utilizadas en nuestro proyecto de Panel de administración. Continúe leyendo para obtener perspectivas más reveladoras.
Encabezado en Connexus (Parte 3): Dominando el uso de encabezado HTTP para solicitudes WebRequest Encabezado en Connexus (Parte 3): Dominando el uso de encabezado HTTP para solicitudes WebRequest
Continuamos desarrollando la biblioteca Connexus. En este capítulo, exploramos el concepto de cabeceras en el protocolo HTTP, explicando qué son, para qué sirven y cómo usarlos en las solicitudes. Cubrimos los principales encabezados utilizados en las comunicaciones con API y mostramos ejemplos prácticos de cómo configurarlos en la biblioteca.
Del básico al intermedio: Punto flotante Del básico al intermedio: Punto flotante
Este artículo es una breve introducción a lo que sería el punto flotante. Como este contenido es muy complicado, te aconsejo leer con calma y atención. No esperes dominar el sistema de punto flotante de manera rápida. El mismo solo se domina con el tiempo y la experiencia de uso. Pero este artículo te ayudará a entender por qué, a veces, tu aplicación reporta un resultado diferente del esperado originalmente. El contenido expuesto aquí tiene un propósito puramente didáctico. En ningún caso debe considerarse una aplicación cuya finalidad no sea el aprendizaje y el estudio de los conceptos mostrados.
Simulador rápido de estrategias comerciales en Python usando Numba Simulador rápido de estrategias comerciales en Python usando Numba
Este artículo implementaremos un simulador rápido de estrategias para modelos de aprendizaje automático utilizando Numba. En cuanto a su velocidad, superará en un factor de 50 a un simulador de estrategias puramente basado en Python. El autor recomienda usar esta biblioteca para acelerar los cálculos matemáticos, y especialmente cuando se utilizan ciclos.