English Русский Deutsch 日本語
preview
Creación de un modelo de restricción de tendencia de velas (Parte 1): Para EAs e Indicadores Técnicos

Creación de un modelo de restricción de tendencia de velas (Parte 1): Para EAs e Indicadores Técnicos

MetaTrader 5Trading | 21 agosto 2024, 16:18
719 0
Clemence Benjamin
Clemence Benjamin

Contenido

  1. Introducción
  2. Anatomía de las velas de plazos superiores
  3. Desarrollo de la estrategia (Moving Average Crossover) más el código
  4. Justificación de la restricción y su aplicación más el código
  5. Ventajas de utilizar el código
  6. Conclusión


    Introducción

    Como alternativa al uso de las medias móviles para definir las tendencias del mercado, la naturaleza alcista o bajista de las velas de plazos superiores puede proporcionar información valiosa sobre la dirección del mercado. Por ejemplo, dentro de una vela D1 o H4, hay una actividad subyacente significativa que ocurre en los marcos temporales M1 e incluso en los ticks que dan forma a su formación. Al capitalizar las oportunidades de compra que presentan las velas D1 alcistas y vender durante las fases bajistas, los operadores pueden obtener una ventaja. La combinación de estos indicadores con indicadores técnicos nativos en plazos inferiores ayuda a identificar los puntos de entrada, lo que ofrece una ventaja estratégica a los operadores. Cuando se trata de una vela diaria alcista, los operadores deben esperar pacientemente a que las condiciones favorables del mercado se alineen antes de montar con confianza la tendencia.

    Este artículo tiene como objetivo clasificar eficazmente la vela actual como alcista o bajista utilizando el código MQL5, estableciendo una condición para vender sólo cuando es bajista y comprar cuando es alcista.

    Este modelo pretende limitar el generador de señales a la producción de señales alineadas con la tendencia actual de la vela. Piense en una valla que impide la entrada a determinadas criaturas en función del tamaño de su cuerpo, mientras que permite la entrada a otras. Aplicamos un concepto similar para filtrar las señales seleccionadas y conservar sólo las más óptimas. Para ello, el modelo analiza las velas y las tendencias del mercado en los marcos temporales superiores, creando así una barrera virtual que sólo permite el paso de las señales que se ajustan a la tendencia predominante. Este proceso de filtrado selectivo mejora la precisión y fiabilidad de las señales generadas, garantizando que sólo se presenten al usuario las oportunidades de negociación más favorables.

    Al final de este artículo, usted debe ser capaz de:

    1. Comprender la acción del precio con toda la vela D1 en los plazos microscópicos disponibles.
    2. Crear un buffer de indicador de cruce de medias móviles (MA) que incluya la condición de restricción de tendencia en un marco temporal superior.
    3. Comprender el concepto de filtrar las mejores señales de una estrategia determinada.

    Anatomía de las velas de plazos superiores

    Índice Boom 500, anatomía de velas D1 M5,13.04.24

    Fig. 1.1: La anatomía de D1 vista en el marco temporal M5 para los sintéticos del índice Boom 500.

    La imagen de arriba muestra una barra roja de velas D1 en el extremo izquierdo y una acción de precio M5 en el derecho delimitada entre separadores de periodos diarios. Se observa una clara tendencia bajista, apoyada por la naturaleza bajista de la vela diaria, que indica una mayor probabilidad de venta. La configuración enfatiza la ejecución de operaciones en alineación con la vela diaria, lo que refleja la aparición de la idea de restricción del desarrollo de una tendencia de marco de tiempo superior.

    Desarrollo de estrategias (Moving Average Crossover)

     El desarrollo de una estrategia de negociación requiere una combinación de análisis, pruebas y perfeccionamiento continuo. Una estrategia de negociación eficaz debe basarse en un conocimiento profundo del mercado, así como en un conjunto claro de reglas y directrices a seguir. Es importante supervisar y ajustar constantemente la estrategia a medida que cambian las condiciones del mercado, para adaptarse a las nuevas tendencias y oportunidades. Mediante el análisis continuo de los datos, la realización de pruebas retrospectivas de diferentes enfoques y los ajustes necesarios, los operadores pueden aumentar sus posibilidades de éxito en el mercado.

    Antes de proceder a nuestra estrategia de cruce de MA, a continuación se presenta un esquema que resume los consejos clave para el desarrollo de la estrategia:

    1. Defina sus objetivos y su tolerancia al riesgo
    2. Conozca el mercado
    3. Elija su estilo de negociación  
    4. Elaborar normas de entrada y salida  
    5. Aplicar estrategias de gestión de riesgos
    6. Pruebe su estrategia
    7. Optimice y perfeccione
    8. Comercio en papel antes de salir al mercado
    9.  Supervisar y evaluar
      Aquí desarrollaremos un indicador básico de cruce de medias móviles que muestra una flecha y activa una notificación en cuanto se produce el cruce. A continuación se exponen las etapas de nuestros criterios de elaboración de estrategias.
      1. Establecer las condiciones de la estrategia (En este caso cruce de EMA7 por encima o por debajo de EMA21)
      2. Establezca el estilo de visualización del indicador, que puede ser una flecha o cualquier forma geométrica disponible en MetaTrader 5
      3. (Opcional) si el indicador va a ser personalizable por el usuario, establezca las entradas

      He decidido incluir aquí el código final sin muchas explicaciones para centrarme en el algoritmo de restricciones, nuestro tema principal en este artículo. El siguiente programa está listo para compilar y generar señales de compra y venta. Después del código, analizaremos los resultados en el gráfico MT5 e identificaremos el problema que abordará el algoritmo de restricción.

      //Indicator Name: Trend Constraint
      #property copyright "Clemence Benjamin"
      #property link      "https://mql5.com"
      #property version   "1.00"
      #property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"
      
      //--- indicator settings
      #property indicator_chart_window
      #property indicator_buffers 2
      #property indicator_plots 2
      
      #property indicator_type1 DRAW_ARROW
      #property indicator_width1 5
      #property indicator_color1 0xFFAA00
      #property indicator_label1 "Buy"
      
      #property indicator_type2 DRAW_ARROW
      #property indicator_width2 5
      #property indicator_color2 0x0000FF
      #property indicator_label2 "Sell"
      
      #define PLOT_MAXIMUM_BARS_BACK 5000
      #define OMIT_OLDEST_BARS 50
      
      //--- indicator buffers
      double Buffer1[];
      double Buffer2[];
      
      double myPoint; //initialized in OnInit
      int MA_handle;
      double MA[];
      int MA_handle2;
      double MA2[];
      double Low[];
      double High[];
      
      void myAlert(string type, string message)
        {
         if(type == "print")
            Print(message);
         else if(type == "error")
           {
            Print(type+" | Trend constraint @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
           }
         else if(type == "order")
           {
           }
         else if(type == "modify")
           {
           }
        }
      
      // Custom indicator initialization function                         
      int OnInit()
        {   
         SetIndexBuffer(0, Buffer1);
         PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(0, PLOT_ARROW, 241);
         SetIndexBuffer(1, Buffer2);
         PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
         PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
         PlotIndexSetInteger(1, PLOT_ARROW, 242);
         //initialize myPoint
         myPoint = Point();
         if(Digits() == 5 || Digits() == 3)
           {
            myPoint *= 10;
           }
         MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle < 0)
           {
            Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         MA_handle2 = iMA(NULL, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE);
         if(MA_handle2 < 0)
           {
            Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
            Print("Runtime error = ", GetLastError());
            return(INIT_FAILED);
           }
         
         return(INIT_SUCCEEDED);
        }
      
      //Custom indicator iteration function                              
      int OnCalculate(const int rates_total,
                      const int prev_calculated,
                      const datetime& time[],
                      const double& open[],
                      const double& high[],
                      const double& low[],
                      const double& close[],
                      const long& tick_volume[],
                      const long& volume[],
                      const int& spread[])
        {
         int limit = rates_total - prev_calculated;
         //--- counting from 0 to rates_total
         ArraySetAsSeries(Buffer1, true);
         ArraySetAsSeries(Buffer2, true);
         //--- initial zero
         if(prev_calculated < 1)
           {
            ArrayInitialize(Buffer1, EMPTY_VALUE);
            ArrayInitialize(Buffer2, EMPTY_VALUE);
           }
         else
            limit++;
         
         if(BarsCalculated(MA_handle) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
         ArraySetAsSeries(MA, true);
         if(BarsCalculated(MA_handle2) <= 0) 
            return(0);
         if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
         ArraySetAsSeries(MA2, true);
         if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
         ArraySetAsSeries(Low, true);
         if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
         ArraySetAsSeries(High, true);
         //--- main loop
         for(int i = limit-1; i >= 0; i--)
           {
            if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
            
            //Indicator Buffer 1
            if(MA[i] > MA2[i]
            && MA[i+1] < MA2[i+1] //Moving Average crosses above Moving Average
            )
              {
               Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
              }
            else
              {
               Buffer1[i] = EMPTY_VALUE;
              }
            //Indicator Buffer 2
            if(MA[i] < MA2[i]
            && MA[i+1] > MA2[i+1] //Moving Average crosses below Moving Average
            )
              {
               Buffer2[i] = High[i]; //Set indicator value at Candlestick High
              }
            else
              {
               Buffer2[i] = EMPTY_VALUE;
              }
           }
         return(rates_total);
        }
      //copy the code to meta editor to compile it

        El 12.04.24, el gráfico de resultados de la prueba EURUSD indica el inicio de un período observado en los plazos M1. Los cruces se muestran con flechas que indican su posición: rojas para las señales de venta y azules para las de compra. A pesar de ello, una visión más amplia revela una clara tendencia bajista, lo que indica una vela D1 bajista. El indicador de cruce está emitiendo ambas señales, haciendo caso omiso de la tendencia predominante, lo que plantea un problema importante. Las señales contradictorias crean un escenario desafiante para los operadores que intentan navegar por el mercado. Si bien los plazos M1 sugieren posibles oportunidades a corto plazo, la tendencia bajista generalizada en la vela D1 hace temer por la sostenibilidad de cualquier movimiento alcista. En este artículo, abordaremos esta cuestión limitando nuestras señales a la tendencia D1.

        Señales de cruce de medias móviles

        Fig. 1.2 : Resultado de la prueba del indicador de cruce MA antes de la restricción.

        El resultado de la vela D1 es bajista con flechas de compra y venta generadas por la condición de cruce de MA. Muchas señales se consideran falsas o fuera de tendencia, lo que puede rectificarse incorporando la restricción de tendencia del marco temporal superior. La tabla resultante a continuación se creó utilizando la información de los gráficos desde el inicio del día hasta el cierre. 

        Tipo de señal Unidades
        Señales de venta 29
        Señales de compra 28
        Total 57
        Señales falsas y fuera de tendencia 41
        Señales exitosas 25


        Justificación de la restricción y su aplicación

        Imagina tener una mezcla de granos de maíz y trigo; uno es más grueso que el otro. Para separarlos, empleamos un tamiz. Esta acción confina el grano de maíz, permitiendo que sólo pase el trigo, lo que demuestra un nivel de control. Esta analogía concuerda con el concepto de limitación temporal superior que estamos examinando. Actúa como un filtro, filtrando ciertas señales y reteniendo sólo las que están en armonía con la tendencia predominante. La restricción temporal superior, similar al tamiz, afina nuestro enfoque, permitiéndonos discernir los elementos esenciales de la tendencia del mercado. Filtrando el ruido, podemos comprender mejor la dinámica subyacente, lo que facilita una toma de decisiones más informada. Este planteamiento estratégico mejora nuestra capacidad para navegar por las complejidades del panorama financiero, garantizando que nos mantenemos alineados con la dirección general, como el sorgo separado del grano de maíz, revelando la verdadera esencia del movimiento del mercado.

        Definir la naturaleza de la vela D1 como condición para la restricción de tendencia que codificamos anteriormente.
        • Definí mi sentimiento actual del mercado como alcista o bajista comparando el precio de cierre del día anterior, que es similar al precio de apertura del día actual, y los precios de cierre de las velas M1 del marco temporal inferior.
        • Para una vela alcista:

          cierre de la vela M1 anterior >= cierre de la vela D1 anterior

          Para una vela bajista:

          cierre de la vela M1 anterior <= cierre de la vela D1 anterior

          Las matemáticas sugieren que con una vela D1 alcista como impulsora de la tendencia, sólo recibiremos señales de compra y lo contrario es cierto para una vela D1 bajista.

          Optamos por el cierre del marco temporal inferior como punto de comparación con nuestra apertura D1 en lugar de utilizar otros aspectos como el precio de compra y venta o el cierre del día actual, ya que este último no muestra flechas en el gráfico como se desea según esta estrategia y estilo de indicador. Por lo tanto, al centrarnos en el cierre del marco temporal inferior en relación con nuestra apertura D1, podemos alinear eficazmente nuestra estrategia con las señales visuales y los indicadores deseados en el gráfico. Este planteamiento aumenta la claridad y precisión de nuestras decisiones comerciales, garantizando un proceso de análisis más ágil y eficaz.  

        • Examinemos el código. El código está bien estructurado y es fácil de seguir.
         if(Close[1+barshift_M1[i]] >= Open[1+barshift_D1[i]] //Candlestick Close >= Candlestick Open
              )
                {
                 Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
                }
              else
                {
                 Buffer1[i] = EMPTY_VALUE;
                }

        El código anterior representa una condición de vela D1 alcista. Recuerde que lo contrario es válido para los bajistas.

        • Por último, presento el código final en el que la restricción se integra perfectamente con el indicador de cruce de medias móviles.
        /Indicator Name: Trend Constraint
        #property copyright "Clemence Benjamin"
        #property link      "https://mql5.com"
        #property version   "1.00"
        #property description "A model that seek to produce sell signal when D1 candle is Bearish only and  buy signal when it is Bullish"
        
        //--- indicator settings
        #property indicator_chart_window
        #property indicator_buffers 2
        #property indicator_plots 2
        
        #property indicator_type1 DRAW_ARROW
        #property indicator_width1 5/
        #property indicator_color1 0xFFAA00
        #property indicator_label1 "Buy"
        
        #property indicator_type2 DRAW_ARROW
        #property indicator_width2 5
        #property indicator_color2 0x0000FF
        #property indicator_label2 "Sell"
        
        #define PLOT_MAXIMUM_BARS_BACK 5000
        #define OMIT_OLDEST_BARS 50
        
        //--- indicator buffers
        double Buffer1[];
        double Buffer2[];
        
        double myPoint; //initialized in OnInit
        int MA_handle;
        double MA[];
        int MA_handle2;
        double MA2[];
        double Close[];
        double Close2[];
        double Low[];
        double High[];
        
        void myAlert(string type, string message)
          {
           if(type == "print")
              Print(message);
           else if(type == "error")
             {
              Print(type+" | Trend constraint @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
             }
           else if(type == "order")
             {
             }
           else if(type == "modify")
             {
             }
          }
        
        // Custom indicator initialization function                         
        int OnInit()
          {   
           SetIndexBuffer(0, Buffer1);
           PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
           PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
           PlotIndexSetInteger(0, PLOT_ARROW, 241);
           SetIndexBuffer(1, Buffer2);
           PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
           PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
           PlotIndexSetInteger(1, PLOT_ARROW, 242);
           //initialize myPoint
           myPoint = Point();
           if(Digits() == 5 || Digits() == 3)
             {
              myPoint *= 10;
             }
           MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_EMA, PRICE_CLOSE);
           if(MA_handle < 0)
             {
              Print("The creation of iMA has failed: MA_handle=", INVALID_HANDLE);
              Print("Runtime error = ", GetLastError());
              return(INIT_FAILED);
             }
           
           MA_handle2 = iMA(NULL, PERIOD_CURRENT, 21, 0, MODE_EMA, PRICE_CLOSE);
           if(MA_handle2 < 0)
             {
              Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
              Print("Runtime error = ", GetLastError());
              return(INIT_FAILED);
             }
           
           return(INIT_SUCCEEDED);
          }
        
        // Custom indicator iteration function                              
        int OnCalculate(const int rates_total,
                        const int prev_calculated,
                        const datetime& time[],
                        const double& open[],
                        const double& high[],
                        const double& low[],
                        const double& close[],
                        const long& tick_volume[],
                        const long& volume[],
                        const int& spread[])
          {
           int limit = rates_total - prev_calculated;
           //--- counting from 0 to rates_total
           ArraySetAsSeries(Buffer1, true);
           ArraySetAsSeries(Buffer2, true);
           //--- initial zero
           if(prev_calculated < 1)
             {
              ArrayInitialize(Buffer1, EMPTY_VALUE);
              ArrayInitialize(Buffer2, EMPTY_VALUE);
             }
           else
              limit++;
           
           datetime TimeShift[];
           if(CopyTime(Symbol(), PERIOD_CURRENT, 0, rates_total, TimeShift) <= 0) return(rates_total);
           ArraySetAsSeries(TimeShift, true);
           int barshift_M1[];
           ArrayResize(barshift_M1, rates_total);
           int barshift_D1[];
           ArrayResize(barshift_D1, rates_total);
           for(int i = 0; i < rates_total; i++)
             {
              barshift_M1[i] = iBarShift(Symbol(), PERIOD_M1, TimeShift[i]);
              barshift_D1[i] = iBarShift(Symbol(), PERIOD_D1, TimeShift[i]);
           }
           if(BarsCalculated(MA_handle) <= 0) 
              return(0);
           if(CopyBuffer(MA_handle, 0, 0, rates_total, MA) <= 0) return(rates_total);
           ArraySetAsSeries(MA, true);
           if(BarsCalculated(MA_handle2) <= 0) 
              return(0);
           if(CopyBuffer(MA_handle2, 0, 0, rates_total, MA2) <= 0) return(rates_total);
           ArraySetAsSeries(MA2, true);
           if(CopyClose(Symbol(), PERIOD_M1, 0, rates_total, Close) <= 0) return(rates_total);
           ArraySetAsSeries(Close, true);
           if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close2) <= 0) return(rates_total);
           ArraySetAsSeries(Close2, true);
           if(CopyLow(Symbol(), PERIOD_CURRENT, 0, rates_total, Low) <= 0) return(rates_total);
           ArraySetAsSeries(Low, true);
           if(CopyHigh(Symbol(), PERIOD_CURRENT, 0, rates_total, High) <= 0) return(rates_total);
           ArraySetAsSeries(High, true);
           //--- main loop
           for(int i = limit-1; i >= 0; i--)
             {
              if (i >= MathMin(PLOT_MAXIMUM_BARS_BACK-1, rates_total-1-OMIT_OLDEST_BARS)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   
              
              if(barshift_M1[i] < 0 || barshift_M1[i] >= rates_total) continue;
              if(barshift_D1[i] < 0 || barshift_D1[i] >= rates_total) continue;
              
              //Indicator Buffer 1
              if(MA[i] > MA2[i]
              && MA[i+1] < MA2[i+1] //Moving Average crosses above Moving Average
              && Close[1+barshift_M1[i]] >= Close2[1+barshift_D1[i]] //Candlestick Close >= Candlestick Close
              )
                {
                 Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
                }
              else
                {
                 Buffer1[i] = EMPTY_VALUE;
                }
              //Indicator Buffer 2
              if(MA[i] < MA2[i]
              && MA[i+1] > MA2[i+1] //Moving Average crosses below Moving Average
              && Close[1+barshift_M1[i]] <= Close2[1+barshift_D1[i]] //Candlestick Close <= Candlestick Close
              )
                {
                 Buffer2[i] = High[i]; //Set indicator value at Candlestick High
                }
              else
                {
                 Buffer2[i] = EMPTY_VALUE;
                }
             }
           return(rates_total);
          }

        El resultado del código anterior es excelente. Consulte la imagen siguiente.

        Restricción de tendencia aplicada al indicador de cruce de medias móviles

        Fig. 1.3: Restricción de tendencia aplicada y el resultado es sorprendente.

        Tipo de señal Unidades
        Señal de venta 27
        Señal de compra 1
        Total 28
        Señales falsas y fuera de tendencia 3
        Señales exitosas 25

        En la tabla anterior, observamos un impacto positivo de la restricción de tendencia de marco temporal superior como filtro, lo que se traduce en más victorias que fracasos, por lo que es ideal para los EA. Comparando las tablas de resultados anterior y actual, observamos que las señales acertadas mantuvieron su valor, mientras que todas las señales falsas se redujeron. Esta mejora de la precisión de la señal indica una tendencia positiva en nuestra metodología de análisis de datos. Al perfeccionar nuestros algoritmos y criterios, hemos minimizado eficazmente la aparición de señales falsas, mejorando la fiabilidad general de nuestros resultados. De cara al futuro, estos avances contribuirán sin duda a una toma de decisiones más informada y a mejorar los resultados de nuestras estrategias.


        Ventajas de utilizar el código

        Las ventajas de imponer restricciones a las tendencias de plazos más largos mejoran la claridad de la dirección del mercado, reduciendo las tendencias a la sobrecompra y fomentando un enfoque más disciplinado de las decisiones de negociación.. Este método también puede proporcionar una perspectiva más amplia, ayudando a los operadores a evitar quedar atrapados en las fluctuaciones a corto plazo y permitiéndoles alinear sus estrategias con la tendencia predominante a largo plazo. Al centrarse en el panorama general, los operadores están mejor equipados para filtrar el ruido y tomar decisiones más informadas basadas en la tendencia subyacente. Este enfoque fomenta la paciencia y una comprensión más profunda de la dinámica del mercado, lo que en última instancia conduce a resultados comerciales más consistentes y rentables. Además, las restricciones en las tendencias de plazos más largos pueden servir como valiosas herramientas para la gestión del riesgo, permitiendo a los operadores establecer niveles claros para los puntos de entrada y salida basados en una evaluación estratégica de las condiciones del mercado.

        En resumen;

        • Mayor precisión de los indicadores generadores de señales
        • Mejor gestión del riesgo
        • Mayor rentabilidad
        • Menos trabajo
        • Menos señales


        Conclusión

        Las velas de los marcos temporales superiores ejercen una influencia significativa en las tendencias de los marcos temporales inferiores, ya sean alcistas o bajistas, dirigiendo esencialmente los mercados. Sobre la base de diversos estudios, es aconsejable considerar la compra durante las velas alcistas del día en marcos de tiempo más bajos y la venta durante las velas bajistas. Personalmente, la integración del concepto de restricciones de tendencias en plazos más largos, como éste, podría ser crucial en el desarrollo del EA e indicadores para obtener resultados positivos sostenidos. Surge la pregunta: ¿Debemos descartar ahora las medias móviles como instrumentos de definición de tendencias? Tal vez el próximo artículo arroje luz sobre esta cuestión a medida que profundicemos en el perfeccionamiento y la evolución de este concepto. Adjunto están los archivos de código fuente que puedes ver en MetaEditor y los archivos EX5 en la plataforma MetaTrader 5.


        Traducción del inglés realizada por MetaQuotes Ltd.
        Artículo original: https://www.mql5.com/en/articles/14347

        Desarrollamos un Asesor Experto multidivisas (Parte 4): Órdenes pendientes virtuales y guardado del estado Desarrollamos un Asesor Experto multidivisas (Parte 4): Órdenes pendientes virtuales y guardado del estado
        Tras empezar a desarrollar un EA multidivisa, ya hemos obtenido algunos resultados y hemos conseguido realizar varias iteraciones de mejora del código. Sin embargo, nuestro EA fue incapaz de trabajar con órdenes pendientes y reanudar la operación después del reinicio del terminal. Añadamos estas características.
        Trabajamos con modelos ONNX en formato float16 y float8 Trabajamos con modelos ONNX en formato float16 y float8
        Los formatos de datos usados para representar modelos de aprendizaje automático desempeñan un papel clave en su eficacia. En los últimos años, se han desarrollado varios tipos de datos nuevos específicamente para trabajar con modelos de aprendizaje profundo. En este artículo nos centraremos en dos nuevos formatos de datos que se han generalizado en los modelos modernos.
        Características del Wizard MQL5 que debe conocer (Parte 13): DBSCAN para la clase experta de señales Características del Wizard MQL5 que debe conocer (Parte 13): DBSCAN para la clase experta de señales
        El agrupamiento basado en densidad para aplicaciones con ruido (DBSCAN) es una forma no supervisada de agrupar datos que apenas requiere parámetros de entrada, salvo solo 2, lo cual, en comparación con otros enfoques como k-means, es una ventaja. Profundizamos en cómo esto podría ser constructivo para probar y eventualmente operar con Asesores Expertos montados por Wizard MQL5.
        Algoritmos de optimización de la población: Resiliencia ante el estancamiento en los extremos locales (Parte I) Algoritmos de optimización de la población: Resiliencia ante el estancamiento en los extremos locales (Parte I)
        El presente artículo presenta un experimento único cuyo objetivo es investigar el comportamiento de los algoritmos de optimización basados en poblaciones en el contexto de su capacidad para abandonar eficientemente los mínimos locales cuando la diversidad en la población es baja y alcanzar los máximos globales. Los trabajos en este campo nos permitirán comprender mejor qué algoritmos específicos pueden continuar con éxito la búsqueda a partir de las coordenadas fijadas por el usuario como punto de partida, y qué factores influyen en su éxito en este proceso.