¡Los proyectos ayudan a crear robots rentables! O eso parece

12 junio 2020, 17:37
MetaQuotes
0
1 033

La creación de un robot comercial comienza siempre por un pequeño archivo, que a su vez va creciendo y llenándose con multitud de funciones adicionales y objetos de usuario. La mayoría de los programadores de MQL5 afronta este problema con la ayuda de archivos de inclusión (MQH). Pero resulta mejor comenzar a escribir cualquier programa para trading directamente en un proyecto: es más rentable en todos los sentidos.


Ventajas de trabajar utilizando un proyecto

Un proyecto es un archivo aparte con la extensión "MQPROJ", en el que se guardan los ajustes del programa, los parámetros de compilación y la información sobre todos los archivos utilizados. Para trabajar cómodamente con un proyecto, se ha pensado una pestaña aparte en el Navegador. En esta, se representan por categorías todos los archivos utilizados: de inclusión, de recursos, de encabezado, etcétera.

Ejemplo de proyecto

De esta forma, un proyecto no supone simplemente un conjunto de archivos y carpetas ubicadas en un directorio aparte, sino también la posibilidad de descomponer un programa complejo en una estructura calculada en la que se perciban las interacciones y todos los datos necesarios se encuentren a mano, concretamente, nos referimos a:

  • archivos set con parámetros de entrada para la simulación y optimización,
  • códigos fuente de programas OpenCL,
  • archivos multimedia con imágenes y sonidos,
  • recursos, etcétera.

Por eso, trabajando en un proyecto, usted siempre podrá saber dónde se encuentra cualquier parte de su programa, y también desplazarse por todos los archivos utilizados. Y, naturalmente, los proyectos le permitirán realizar desarrollos de forma conjunta con la ayuda del repositorio incorporadoMQL5 Storage.


Crear un proyecto

Los nuevos proyectos se crean como cualquier programa MQL5 con ayuda del Wizard MQL5. Pulse "Nuevo proyecto", y ejecute después todos los pasos: indique el nombre del programa, añada los parámetros de entrada y establezca los manejadores de eventos utilizados. Una vez el funcionamiento del Wizard MQL5 haya finalizado, se abrirá un archivo MQPROJ para gestionar las propiedades del proyecto.

Propiedades del proyecto>


Aquí, usted podrá especificar la versión, indicar la descripción del programa, añadir un icono, y también gestionar las opciones adicionales:

  1. Maximum optimization — optimización del archivo EX5 ejecutable para su máxima velocidad de ejecución. La desactivación de esta opción acelerará la compilación del código fuente, pero el archivo EX5 obtenido podría funcionar a una velocidad significativamente menor.
  2. Check floating point dividers — comprobar si los números reales de tipo double y float no son iguales a cero en las operaciones de división. La desactivación de esta opción puede acelerar el funcionamiento, pero debemos hacer esto de forma consciente.
  3. Use tester optimization cache — por defecto, la opción está activada y el simulador guarda todos los resultados de las pasadas realizadas en la caché de optimización que se usan en los recálculos. En caso necesario, la caché puede ser desactivada con la ayuda de la propiedad tester_no_cache, pero en el proyecto, esto se realiza desmarcando la casilla.

Si el archivo del proyecto está cerrado, siempre podrá abrirlo de nuevo con la ayuda del comando del menú contextual "Propiedades". Para comprender mejor el contenido del archivo MQPROJ, ábralo en formato de texto con la ayuda del comando "Abrir". Esto le ayudará a entender la construcción interna del proyecto.

{
  "platform"    :"mt5",
  "program_type":"expert",
  "copyright"   :"Copyright 2019, MetaQuotes Software Corp.",
  "link"        :"https:\/\/www.mql5.com",
  "version"     :"1.00",
  "description" :"The mean reversion strategy: the price breaks the channel border outwards and reverts back towards the average. The channel is represented by Bollinger Bands. The Expert Advisor enters the market using limit orders, which can only be opened in the trend direction.",
  "icon"        :"Mean Reversion.ico",
  "optimize"    :"1",
  "fpzerocheck" :"1",
  "tester_no_cache":"0",
  "tester_everytick_calculate":"0",

  "files":
  [
    {
      "path":".\\Mean Reversion.mq5",
      "compile":"true",
      "relative_to_project":"true"
    },
    {
      "path":"MQL5\\Include\\Trade\\Trade.mqh",
      "compile":"false",
      "relative_to_project":"false"
    },
....


    Reglas comerciales

    Vamos a seguir unas reglas clásicas: entraremos en el mercado cuando el precio toque la banda de Bollinger. Se trata de una de las variedades de comercio basadas en el retorno a la media.

    Entrada en el mercado usando las bandas de Bollinger

    Entraremos solo con órdenes límite pendientes. Además, añadiremos una regla adicional: vamos a comerciar solo en la dirección de la tendencia. Esto significa que, si la tendencia es ascendente, colocaremos solo Buy Limit en el borde inferior del canal, y si la tendencia es descendente, colocaremos Sell Limit en el borde superior del mismo.

    La dirección de la tendencia se puede determinar de muchas maneras, así que elegiremos la más sencilla: según la ubicación de dos medias móviles una respecto a otra. Si la media móvil rápida (Fast EMA) es superior a la lenta, tendremos una tendencia ascendente. Y, en el caso contrario, descendente.

    Definiendo la tendencia con la ayuda de dos medias móviles

    No obstante, esta regla tan sencilla presenta una desventaja: siempre tendremos una tendencia o bien ascendente, o bien descendente. Y este sistema indicará muchas entradas falsas durante el mercado plano. Por eso, vamos a añadir una última mejora, a saber, solo será posible colocar órdenes pendientes en el caso de que la distancia entre las bandas de Bollinger sea lo suficientemente grande. Lo más adecuado será medir la anchura del canal en magnitudes relativas, y no en puntos. Para ello, tomaremos el indicador ATR, que mide la volatilidad en puntos.

    • Si la anchura del canal es inferior a k*ATR, tendremos un mercado plano, por lo que estará prohibido colocar órdenes.
    • Si la anchura del canal es superior a k*ATR, colocaremos una orden límite pendiente en el borde del canal en la dirección de la tendencia.

    Aquí, k es un cierto coeficiente que debe ser seleccionado.

    Calculando la anchura del canal de Bollinger con la ayuda del indicador ATR


    De esta forma, al crear un proyecto, deberemos indicar 8 parámetros de entrada para determinar las señales comerciales. El asesor comerciará siempre con un lote fijo, cuyo tamaño se determinará con el parámetro InpLot. Asimismo, existe otro parámetro no optimizable de servicio, InpMagicNumber, para que el asesor trabaje solo con sus propias órdenes y posiciones.

    //--- Parámetros del canal
    input int             InpBBPeriod   =20;           // periodo del indicador de Bollinger
    input double          InpBBDeviation=2.0;          // desviación de las bandas respecto a la media
    //-- periodos de EMA para calcular la tendencia 
    input int             InpFastEMA    =12;           // periodo de Fast EMA
    input int             InpSlowEMA    =26;           // periodo de Slow EMA
    //-- ATR parameters
    input int             InpATRPeriod  =14;           // periodo del indicador ATR
    input double          InpATRCoeff   =1.0;          // coeficiente de ATR para determinar el mercado plano
    //--- gestión de capital
    input double          InpLot        =0.1;          // volumen comercial en lotes
    //--- parámetros de los marcos temporales
    input ENUM_TIMEFRAMES InpBBTF       =PERIOD_M15;   // marco temporal en el que se toman los valores del indicador de Bollinger
    input ENUM_TIMEFRAMES InpMATF       =PERIOD_M15;   // marco temporal en el que se determina la tendencia
    //--- identificador del asesor para las transacciones comerciales
    input long            InpMagicNumber=245600;       // Magic Number
    

    Para no seleccionar manualmente el marco temporal para determinar la tendencia y la anchura del canal, se han añadido los parámetros de entrada InpBBTF y InpMATF. Esto permitirá buscar los marcos temporales adecuados directamente durante la optimización, evitando así operaciones innecesarias. Es decir, podemos iniciar el asesor en el marco temporal M1, mientras que usa el indicador Bollinger Bands en M15, y una media móvil con M30. En cuanto al indicador ATR, no hemos introducido un parámetro de entrada aparte para el marco temporal, para no aumentar el número de parámetros.


    Escribiendo las funciones

    Bien, ya hemos creado el proyecto: ahora es el momento de escribir el asesor propiamente dicho. Vamos a mostrar solo las 3 funciones principales encargadas de describir las reglas.

    El cálculo de la anchura del canal de Bollinger es sencillo: solo tenemos que copiar los valores de los búferes de indicador.

    //+------------------------------------------------------------------+
    //| Obtiene los valores de los bordes del canal                      |
    //+------------------------------------------------------------------+
    bool ChannelBoundsCalculate(double &up, double &low)
      {
    //--- obtenemos los valores del indicador Bollinger Bands 
       double bbup_buffer[];
       double bblow_buffer[];
       if(CopyBuffer(ExtBBHandle, 1, 1, 1, bbup_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtBBHandle,0,1,2,bbup_buffer), code=%d", __FILE__, GetLastError());
          return(false);
         }
    
       if((CopyBuffer(ExtBBHandle, 2, 1, 1, bblow_buffer)==-1))
         {
          PrintFormat("%s: Failed CopyBuffer(ExtBBHandle,0,1,2,bblow_buffer), code=%d", __FILE__, GetLastError());
          return(false);
         }
       low=bblow_buffer[0];
       up =bbup_buffer[0];
    //--- con éxito
       return(true);
      }
    

    Determinar el mercado plano tampoco supone un problema. Primero obtenemos los valores de los bordes del canal, después calculamos la anchura y comparamos con el valor del indicador ATR multiplicado por el coeficiente InpATRCoeff.

    //+------------------------------------------------------------------+
    //|  Retorna true si el canal es demasiado estrecho                  |
    //|  (indica mercado plano)                                          |
    //+------------------------------------------------------------------+
    int IsRange()
      {
    //--- obtenemos el valor de ATR en la última barra finalizada
       double atr_buffer[];
       if(CopyBuffer(ExtATRHandle, 0, 1, 1, atr_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtATRHandle,0,1,2,atr_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
       double atr=atr_buffer[0];
    //--- obtenemos los bordes del canal
       if(!ChannelBoundsCalculate(ExtUpChannel, ExtLowChannel))
          return(NO_VALUE);
       ExtChannelRange=ExtUpChannel-ExtLowChannel;
    //--- si la anchura del canal es inferior al coeficiente ATR*, tendremos mercado plano
       if(ExtChannelRange<InpATRCoeff*atr)
          return(true);
    //--- mercado plano no detectado
       return(false);
      }
    

    Como podemos ver por el código, en ciertos casos, se retorna el valor de la macro NO_VALUE, que nos indicará que no se ha logrado calcular cierto parámetro.

    #define NO_VALUE      INT_MAX                      // valor no válido al calcular la Señal o Tendencia

    La función encargada de determinar la tendencia es la más voluminosa.

    //+------------------------------------------------------------------+
    //| Retorna 1 para UpTrend o -1 para DownTrend (0 = no hay tendencia)|
    //+------------------------------------------------------------------+
    int TrendCalculate()
      {
    //--- primero, comprobamos si tenemos mercado plano 
       int is_range=IsRange();
    //--- comprobamos el resultado
       if(is_range==NO_VALUE)
         {
          //--- si la comprobación no ha tenido éxito, salimos antes con el valor "no value"
          return(NO_VALUE);
         }
    //--- durante el mercado plano, no calculamos la tendencia
       if(is_range==true) // intervalo estrecho, retornamos "flat"
          return(0);
    //--- obtenemos el valor de ATR en la última barra finalizada
       double atr_buffer[];
       if(CopyBuffer(ExtBBHandle, 0, 1, 1, atr_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtATRHandle,0,1,2,atr_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
    //--- obtenemos el valor de Fast EMA en la última barra finalizada
       double fastma_buffer[];
       if(CopyBuffer(ExtFastMAHandle, 0, 1, 1, fastma_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtFastMAHandle,0,1,2,fastma_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
    //--- obtenemos el valor de Slow EMA en la última barra finalizada
       double slowma_buffer[];
       if(CopyBuffer(ExtSlowMAHandle, 0, 1, 1, slowma_buffer)==-1)
         {
          PrintFormat("%s: Failed CopyBuffer(ExtSlowMAHandle,0,1,2,slowma_buffer), code=%d", __FILE__, GetLastError());
          return(NO_VALUE);
         }
    //--- por defecto, la tendencia no está definida
       int trend=0;
    //--- si la EMA rápida es superior a la lenta
       if(fastma_buffer[0]>slowma_buffer[0])
          trend=1;   // tendencia ascendente (uptrend)
    //--- si la EMA rápida es inferior a la lenta
       if(fastma_buffer[0]<slowma_buffer[0])
          trend=-1;  // tendencia descendente (downtrend)
    //--- retornamos la dirección de la tendencia
       return(trend);
      }
    

    La última función del algoritmo comercial se encarga de determinar una nueva barra. Se ha escrito de forma que calcule la dirección de la tendencia solo cuando aparezca una nueva barra.

    //+------------------------------------------------------------------+
    //| Checks the emergence of a new bar on the current timeframe,      |
    //| also calculates the trend and the signal                         |
    //+------------------------------------------------------------------+
    bool IsNewBar(int &trend)
      {
    //--- aquí se guarda de forma constante la hora de apertura de la barra actual entre las llamadas de la función
       static datetime timeopen=0;
    //--- obtenemos la hora de apertura de la barra actual 
       datetime time=iTime(NULL, InpMATF, 0);
    //--- si la hora no ha cambiado, significará que la barra no es nueva, así que salimos con el valor false
       if(time==timeopen)
          return(false);
    //--- la barra es nueva, así que tenemos que calcular la dirección de la tendencia
       trend=TrendCalculate();
    //--- si no hemos conseguido la dirección de la tendencia, salimos e intentamos obtenerla en la próxima llamada
       if(trend==NO_VALUE)
          return(false);
    //--- todas las comprobaciones han tenido éxito: la barra es nueva, y también hemos obtenido la dirección de la tendencia
       timeopen=time; //recordamos la hora de apertura de la barra actual para las siguientes llamadas.
    //---
       return(true);
      }
    

    Esto permite organizar el funcionamiento del asesor de forma que todas las operaciones comerciales se realicen solo una vez durante toda la barra. Por eso, los resultados de la simulación dependerán del modo de generación de ticks.

    El algoritmo comercial entero se muestra en el manejador OnTick():

    • Primero se determina la aparición de una nueva barra y la dirección de la tendencia.
    • Si no hay tendencia o se ha abierto una posición, se realizará un intento de eliminar las órdenes pendientes y salir del manejador.
    • Si existe una tendencia direccional y no se han colocado órdenes pendientes, se realizará un intento de colocar una orden límite en el borde del canal.
    • Si se ha colocado una orden, y esta no ha sido modificada todavía en la nueva barra, se realizará un intento de desplazarla al siguiente borde del canal.
    //+------------------------------------------------------------------+
    //| Expert tick function                                             |
    //+------------------------------------------------------------------+
    void OnTick()
      {
       static bool order_sent    =false;    // no se ha logrado colocar una orden límite en la barra actual
       static bool order_deleted =false;    // no se ha logrado eliminar la orden límite en la barra actual
       static bool order_modified=false;    // no se ha logrado modificar la orden límite en la barra actual
    //--- si los parámetros de entrada no son válidos, interrumpimos la simulación en el primer tick
       if(!ExtInputsValidated)
          TesterStop();
    //--- comprobamos la aparición de una nueva barra y la dirección de la tendencia
       if(IsNewBar(ExtTrend))
         {
          //--- redefinimos los valores de las variables estáticas a su estado original
          order_sent    =false;
          order_deleted =false;
          order_modified=false;
         }
    //--- creamos las variables auxiliares para que las comprobaciones sean llamadas solo una vez en la barra actual
       bool order_exist   =OrderExist();
       bool trend_detected=TrendDetected(ExtTrend);
    //--- si no hay tendencia o hay una posición abierta, eliminamos las órdenes pendientes
       if(!trend_detected || PositionExist())
          if(!order_deleted)
            {
             order_deleted=DeleteLimitOrders();
             //--- si las órdenes se han eliminado con éxito, no será necesario realizar ninguna operación más en la barra actual
             if(order_deleted)
               {
                //--- prohibimos la colocación y modificación de órdenes
                order_sent    =true;
                order_modified=true;
                return;
               }
            }
    
    //--- hay tendencia
       if(trend_detected)
         {
          //--- colocamos una orden en el borde del canal, si todavía no la hay
          if(!order_exist && !order_sent)
            {
             order_sent=SendLimitOrder(ExtTrend);
             if(order_sent)
                order_modified=true;
            }
          //--- intentamos desplazar la orden al borde del canal, si todavía no se ha hecho esto en la barra actual
          if(order_exist && !order_modified)
             order_modified=ModifyLimitOrder(ExtTrend);
         }
    //---
      }
    

    Las demás funciones comerciales del asesor son estándar, por lo que no serán descritas. Los códigos fuente del proyecto están incluidos en el paquete estándar del terminal MetaTrader 5 y se encuentran el directorio MQL5\Experts\Examples.

    Ubicación del proyecto MeanReversion en el Navegador


    Optimizando parámetros y añadiendo archivos Set

    Después de escribir el asesor, deberemos encontrar los valores óptimos para los parámetros de entrada en el simulador de estrategias. Pocos saben que el simulador permite copiar fácilmente los valores de las pestañas "Ajustes" y "Parámetros" en el portapapeles con la ayuda de la combinación estándar Ctr+C. Esto le permitirá transmitir rápidamente sus ajustes a otra persona, por ejemplo, a un cliente, a través del chat de freelance, sin necesidad de guardarlos en un archivo set. El cliente podrá copiar estos datos en el portapapeles y pegarlos en la pestaña "Ajustes" del simulador con la ayuda de la operación inversa Ctr+V.

    Naturalmente, el guardado de ajustes en un archivo set sigue funcionando, y muchos vendedores en el Mercado acompañan sus asesores con estos archivos para mayor comodidad de sus clientes, que pueden cargar de inmediato los conjuntos correctos de parámetros para la simulación y optimización en el instrumento necesario. Para cada instrumento, es necesario crear un archivo set aparte, y si hay muchos asesores y archivos de este tipo, resulta fácil confundirese. Los proyectos permiten a los compradores de sus robots trabajar solo con sus propios conjuntos de parámetros de entrada, evitando tener que buscar estos en el disco al cambiar de símbolo.

    Aquí tenemos un ejemplo de cómo los proyectos permiten añadir los conjuntos de parámetros necesarios directamente al archivo EX5 del asesor. Seleccione el instrumento en el que se va a realizar la optimización, por ejemplo, EURUSD. Establezca los valores Start, Step y Stop para los parámetros a optimizar e inicie la optimización. Una vez haya finalizado, en la pestaña "Optimización", clique dos veces en la que usted considere la mejor pasada: los valores de los parámetros de entrada de esta pasada se colocarán en la pestaña "Parámetros", iniciándose a continuación una simulación individual. Ahora, usted podrá guardar los parámetros encontrados en un archivo set, pero no tendrá que transferirlo por separado. Guarde el conjunto de parámetros, digamos, con el nombre EURUSD.set: esto significará que los parámetros deberán aplicarse precisamente a este símbolo, y no a GBPJPY.

    Guardando los ajustes de los parámetros de entrada en un archivo set

    Realice esta operación para cada símbolo en el que pueda trabajar este asesor. De esta forma, usted tendrá un conjunto de, digamos, 9 archivos set. Ahora, solo tendrá que añadir estos archivos a su proyecto: cree la carpeta "Settings and files\Set" correspondiente, para que queden guardados aparte de los códigos fuente. Los proyectos le permitirán mantener el orden con la ayuda de una estructura de archivos correcta.

    Añadiendo archivos set al proyecto


    Ahora, compile el proyecto y abra el simulador de estrategias con el asesor MeanReversion. En el menú contextual de la pestaña Parámetros, aparecerá el nuevo punto "Cargar desde un asesor", donde se encontrarán todas las variables de su conjunto de archivos set.

    Cargando los parámetros de entrada desde el asesor

    De esta forma, el archivo EX5 compilado del experto ha resultado un producto completamente finalizado: en él se encuentran los conjuntos de parámetros preparados, para poder comprobar la estrategia sin tener que pensar en los límites y el salto de cambio para cada símbolo. Los usuarios y compradores de sus asesores comerciales valorarán esta comodidad.


    Comprobamos estrategias usando datos reales

    El asesor MeanReversion fue lanzado en septiembre de 2019 en una cuenta demo para comprobar sus posibles errores programáticos y comerciales en tiempo real. En esta caso, además, el asesor comenzó en el modo de portafolio, comerciando en multitud de símbolos, como se pensó durante la optimización. Asimismo, se alquiló un VPS incorporado, creando para el monitoreo online la señal privadaMany MeanReversion Optimized

    Resultados comerciales en 9 meses

    Tras solo un mes de trabajo, el asesor mostró resultados positivos; después, tuvo pérdidas durante 5 meses. Gracias a que el hosting virtual incluía la prolongación automática de contrato, el asesor iniciado no molestaba a nadie, manteniendo un rumbo decidido hacia la pérdida total del depósito. Sin embargo, en marzo sucedieron ciertos cambios en el mercado de divisas, y el asesor mostró de repente un beneficio récord. Los 2 meses siguientes, los resultados fueron contradictorios, posiblemente no volvamos a ver un crecimiento semejante.

    El análisis de las transacciones y los resultados desde el punto de vista de los símbolos, muestra que las tres parejas del yen y AUDUSD no son rentables. El asesor no ha mostrado resultados impresionantes, pero incluso con una lógica comercial tan sencilla, ha podido aguantar 9 meses gracias al trabajo en el modo de portafolio, cuando las pérdidas en unos instrumentos se ven compensadas por el beneficio en otros.

    Distribución por símbolos

    Debemos destacar que, desde el momento en que el asesor comenzó a comerciar, sus parámetros de entrada no se modificaron nunca, ni se realizó una sola vez la migración. Es decir, un asesor compilado hace 9 meses comenzó a comerciar en 8 gráficos en un VPS incorporado y ha funcionado hasta ahora sin intervención alguna. Ahora, ya no podemos recordar por qué de los 9 conjuntos set solo se tomaron 8 para el trabajo, al igual que los parámetros que fueron utilizados. Sin embargo, el proyecto de asesor de prueba MeanReversion, creado con fines educativos, sigue activo, mostrando beneficios a día 10 junio de 2020.


    Comience a utilizar proyectos: ¡es rentable!

    Los proyectos permiten crear programas de cualquier nivel de complejidad y realizar desarrollos conjuntos. El trabajo en equipo con compañeros afines agiliza el desarrollo de aplicaciones, permite intercambiar ideas y habilidades útiles, y también aumenta la calidad del código.

    Las reglas comerciales de este asesor son muy sencillas, pero se pueden utilizar como plantilla para crear multitud de robots comerciales distintos. Bastará con cambiar las funciones que determinan la dirección de la tendencia, el estado del mercado plano, los niveles y los métodos de entrada: por ejemplo, no usar órdenes límite, sino de mercado. Posiblemente, resultaría más exitoso comerciar solo en los momentos de mercado plano, ya que no hay función de trailing stop, ni hay ajuste aparte para gestionar los niveles de StopLoss y TakeProfit. En resumen, hay mucho margen para investigar.

    Con la ayuda del asesor MeanReversion del paquete estándar MetaTrader 5, usted podrá estudiar y valorar todas las ventajas del trabajo con proyectos. Solo tiene que crearlo o copiarlo en una nueva carpeta, y comenzar experimentar. ¡Use proyectos, es cómodo y rentable en muchos aspectos!

    Traducción del ruso hecha por MetaQuotes Software Corp.
    Artículo original: https://www.mql5.com/ru/articles/7863

    Trabajando con las series temporales en la biblioteca DoEasy (Parte 36): El objeto de series temporales de todos los periodos utilizados del símbolo Trabajando con las series temporales en la biblioteca DoEasy (Parte 36): El objeto de series temporales de todos los periodos utilizados del símbolo

    En el artículo, vamos a analizar la combinación de las listas de objetos de barra de cada periodo utilizado del símbolo en un objeto de series temporales del símbolo. De esta forma, tendremos preparado para cada símbolo un objeto que guarde las listas de todos los periodos utilizados de la serie temporal de un símbolo.

    Pronosticación de series temporales (Parte 2): el método de los mínimos cuadrados de los vectores de soporte (LS-SVM) Pronosticación de series temporales (Parte 2): el método de los mínimos cuadrados de los vectores de soporte (LS-SVM)

    En el artículo se analiza la teoría y el uso práctico del algoritmo de pronosticación de series temporales usando como base el método de vectores de soporte. Asimismo, presentamos su implementación en MQL, además de varios indicadores de prueba y expertos. Esta tecnología todavía no ha sido implementada en MQL. Vamos a comenzar familiarizándonos con el aparato matemático.

    Optimización móvil continua (Parte 5): Panorámica del proyecto del optimizador automático, creación de la interfaz gráfica Optimización móvil continua (Parte 5): Panorámica del proyecto del optimizador automático, creación de la interfaz gráfica

    Continuamos con la descripción de la optimización móvil en el terminal MetaTrader 5. Tras analizar en los artículos anteriores los métodos de formación del informe de optimización y su método de filtrado, hemos procedido a describir la estructura interna de la aplicación encargada del propio proceso de optimización. El optimizador automático, ejecutado como una aplicación en C#, tiene su propia interfaz gráfica. Este artículo está dedicado precisamente a esta interfaz gráfica.

    El lenguaje MQL como medio de marcado de la interfaz gráfica de programas MQL. Parte 1 El lenguaje MQL como medio de marcado de la interfaz gráfica de programas MQL. Parte 1

    En el presente artículo, presentamos un nuevo concepto para la descripción de la interfaz de ventana de los programas MQL con la ayuda de las construcciones del lenguaje MQL. Las clases especiales transforman el marcado visual de MQL en elementos de GUI, permitiendo de controlarlos, ajustar sus propiedades y procesar eventos de forma unificada. Asimismo, mostraremos ejemplos de uso del marcado en las ventanas de diálogo y los elementos de la biblioteca estándar.