English Русский Deutsch 日本語
preview
Creación de un modelo de restricción de tendencia de velas (Parte 3): Detección de cambios en las tendencias al utilizar este sistema

Creación de un modelo de restricción de tendencia de velas (Parte 3): Detección de cambios en las tendencias al utilizar este sistema

MetaTrader 5Trading | 3 octubre 2024, 10:21
13 0
Clemence Benjamin
Clemence Benjamin

Contenido


Introducción

Por lo general, los mercados no permanecen estáticos. Tanto si la tendencia es alcista como bajista, pueden producirse cambios inesperados cuando el mercado altera su trayectoria. Es vital que un sistema identifique y se ajuste a estos cambios. Incluso una vela D1 bajista prolongada puede señalar un cambio en la dinámica cuando se produce un retroceso en un marco temporal inferior. Este artículo profundiza en varios métodos empleados para reconocer cambios en las tendencias de la acción del precio. A medida que los operadores navegan por las complejidades de los mercados financieros, la capacidad de adaptarse rápidamente a la evolución de las condiciones se convierte en algo primordial. Reconocer los matices de los movimientos de los precios, comprender el significado de los indicadores clave e interpretar el sentimiento del mercado son componentes cruciales para mantenerse a la vanguardia. Al perfeccionar la habilidad de identificar los cambios en las tendencias, los operadores pueden posicionarse estratégicamente para capitalizar las oportunidades que surgen en medio del paisaje siempre cambiante del mundo financiero.

Diversos factores influyen o impulsan los cambios en las tendencias del mercado. He aquí algunos ejemplos:

  • El comportamiento de los inversores, es decir, comprar y vender.
  • Noticias económicas como el PIB y las nóminas no agrícolas.
  • Políticas monetarias.
  • Acontecimientos mundiales como catástrofes naturales.
  • Acontecimientos políticos como una guerra, etc.

A través de diferentes recursos de aprendizaje, hemos adquirido amplios conocimientos sobre cómo detectar manualmente los cambios de tendencia. Esto incluye el concepto de análisis de líneas de tendencia, que consiste en trazar líneas en un gráfico de precios para conectar los máximos o mínimos del movimiento de precios de un activo, de forma que los operadores puedan hacerse una idea de los posibles cambios de tendencia cuando el precio rompe por encima o por debajo de estas líneas. Más adelante en este artículo, seleccionaremos un método para detectar los cambios de tendencia del mercado y lo integraremos en nuestro indicador Trend Constraint utilizando MQL5. En primer lugar, exploraremos varias herramientas de análisis técnico, como las medias móviles, los patrones de velas, el índice de fuerza relativa (véase la parte 2) y las líneas de tendencia (véase la Fig. 1) para identificar posibles cambios de tendencia. Procederemos a modificar nuestro indicador Trend Constraint en MQL5 para incorporar esta nueva funcionalidad. 

Descargo de responsabilidad: Las estrategias y técnicas descritas en este artículo sólo tienen fines educativos. Sus operaciones son el resultado de sus propias acciones. No seré responsable de ninguna pérdida resultante del uso de la información o las herramientas proporcionadas aquí
.

Ilustración de tendencias

Fig. 1: Ilustración de las tendencias.

Nota: La imagen de arriba ha sido dibujada a mano con fines didácticos; no se presenta ningún activo real.

La ilustración anterior muestra una tendencia alcista típica con los mínimos A y B conectados por una línea de tendencia azul, que indica una tendencia alcista. En los siguientes ejemplos, exploraremos instancias de gráficos reales para comprender mejor las tendencias. Nuestro objetivo principal es reconocer los cambios de tendencia del mercado e incorporar un método adecuado a nuestro sistema utilizando el código MQL5. 


Formas de detectar cambios en las tendencias del mercado.

Empecemos por definir las tendencias del mercado como:

La tendencia del mercado significa la dirección general en la que se mueve un mercado a lo largo del tiempo, reflejando el comportamiento de compradores y vendedores. Las tendencias pueden ser alcistas, bajistas o laterales (consolidación). Véase (Fig. 1) en Introducción.

Definamos ahora un cambio de tendencia como:

Un cambio de tendencia se produce cuando el movimiento de los precios pasa de una tendencia alcista a una bajista, o viceversa. Este cambio se puede identificar analizando indicadores técnicos clave, como promedios móviles, líneas de tendencia, patrones de velas y niveles de soporte/resistencia. Los comerciantes e inversores siguen de cerca estos cambios en la tendencia del mercado para tomar decisiones informadas y ajustar sus estrategias en consecuencia.


Uso de promedios móviles para detectar cambios de tendencia.

En la parte 1 de esta serie, creamos un indicador de cruce de medias de movimiento rápido para proporcionar señales de continuación de la tendencia cuando se produce un cruce. Sin embargo, las medias móviles de mayor periodo pueden indicar un cambio de tendencia significativo durante un cruce. En este artículo, examinaremos cómo reaccionan las medias móviles cuando el mercado cambia de dirección. A continuación se muestra una imagen.

USDJPYmicroM5 mostrando como las Medias Móviles pueden señalar una reversión

Fig. 2: Cruce de medias móviles como señal de cambio de tendencia.

Utilizar las formas de las velas para detectar los cambios de tendencia.

Los patrones de velas pueden utilizarse eficazmente para detectar posibles retrocesos. Han sido analizados a lo largo de la historia por su capacidad para cambiar significativamente el sentimiento del mercado. Visionarios como Munehisa Honma, creador de La Biblia De Comercio De Velas Japonesas (The Candlestick Bible), han enriquecido nuestra comprensión de las velas japonesas. He aquí algunos de los patrones de velas más frecuentes para los retrocesos del mercado:

Nombre de la vela Descripción
Martillo 
Cuerpo pequeño y una larga sombra inferior.
Martillo invertido
Cuerpo pequeño y una larga sombra superior.
Patrón envolvente alcista
Una vela alcista engulle completamente a la vela bajista anterior.
Patrón envolvente bajista
Una vela bajista engulle completamente a la vela alcista anterior.
Doji Un cuerpo pequeño y largas sombras superiores e inferiores.
Estrella fugaz Un cuerpo pequeño y una larga sombra superior.
Hombre colgado Un cuerpo pequeño y una larga sombra inferior.
Estrella de la mañana Una vela bajista larga, seguida de una vela de cuerpo pequeño con un mínimo más bajo y un máximo más alto.
Estrella del atardecer Una vela alcista larga, seguida de una vela de cuerpo pequeño con un máximo más alto y un mínimo más bajo.
Todas estas características de las velas son programables usando MQL5 porque tienen todos los niveles de precio apertura cierre máximo y mínimo que son cruciales a la hora de programar.


Utilizar las líneas de tendencia para detectar un cambio de tendencia.

En el gráfico de la plataforma MetaTrader 5 podemos utilizar la herramienta objeto línea de tendencia para trazar tendencias conectando mínimos consecutivos en una serie de precios de un activo digital. Una línea de tendencia rota indica un cambio de tendencia. Para dibujar una línea de tendencia, basta con hacer clic en la herramienta de línea de tendencia de la barra de herramientas y, a continuación, hacer clic en la primera depresión y arrastrar la línea hasta la siguiente depresión. La línea de tendencia se extenderá automáticamente a la derecha del gráfico.

Ruptura de la línea de tendencia del índice B300

Fig. 3: La línea de tendencia como herramienta para detectar un cambio de tendencia.

Utilizar los niveles de soporte/resistencia para detectar un cambio de tendencia.

La herramienta de línea horizontal del gráfico MT5 puede utilizarse para trazar niveles de soporte y resistencia en las tendencias colocándola en los picos de los precios. Observar el precio cuando rompe esos niveles podría indicar un cambio de tendencia. Vea el vídeo explicativo a continuación.

Problemas con nuestro sistema actual.

Hemos configurado con éxito nuestro sistema para alinear su señal con la forma de la tendencia D1 e incorporar indicadores como la SMA 400 en la parte 2. Sin embargo, se observan importantes retos en los datos históricos. Debemos tener en cuenta las fluctuaciones en plazos inferiores, que potencialmente pueden invertir el sentimiento inicial al comienzo del día; por ejemplo, un día puede comenzar con una perspectiva bajista pero concluir con una barra alcista o un sentimiento alcista. Las señales de reversión suelen surgir en plazos inferiores, lo que nos lleva a adaptar el mecanismo de señalización del sistema para tener en cuenta los cambios de tendencia, aunque inicialmente se limitaran al sentimiento diario del mercado.


Incorporación de la función de detección de cambios de tendencia con MQL5

He optado por utilizar la SMA 200 como media móvil lenta y la EMA 100 como media móvil rápida. Normalmente, estas medias móviles están más separadas durante las tendencias fuertes, pero más juntas cuando el impulso del mercado es débil o el precio se mueve lateralmente. Cuando ambos promedios se cruzan, suele indicar un cambio de dirección. Sería muy beneficioso que nuestro sistema detectara esto y nos alertara. Nuestro objetivo es que el sistema solo nos proporcione la señal, para que nuestras señales de restricción puedan ajustarse en consecuencia. Con este enfoque, pretendemos capturar posibles reversiones de tendencias y capitalizar oportunidades comerciales rentables. Explicaré algunas características clave y luego incluiré el código principal después.

Nuestro manejador MA se declara como sigue.

MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE); // For EMA 100

MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE); // For SMA 200

El código siguiente muestra las condiciones de cruce en MQL5 bajo la función de iteración.

//Indicator Buffer 3
      if(MA3[i] > MA4[i]
      && MA3[i+1] < MA4[i+1] //Moving Average crosses above Moving Average
      )
        {
         Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer3[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 4
      if(MA3[i] < MA4[i]
      && MA3[i+1] > MA4[i+1] //Moving Average crosses below Moving Average
      )
        {
         Buffer4[i] = High[i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer4[i] = EMPTY_VALUE;
        }

El 'Trend Constraint' del artículo anterior presentaba 2 buffers, uno para las señales de compra y otro para las de venta para la continuación de la tendencia. Para lograr nuestro objetivo, queremos añadir dos búferes más, uno para la venta y otro para la compra, que representen señales de inversión cuando se produzca un cruce. En el programa se denominan consecutivamente Buffer3 y Buffer4. Hemos optimizado un nuevo estilo de visualización para la función. La visualización del indicador se puede personalizar seleccionando símbolos de objetos en MQL5 utilizando la fuente Wingdings. Aquí, utilicé el objeto número 236 para mi señal de inversión de compra y el objeto número 238 para la señal de inversión de venta.

// under OnInit() function. The wingding objects can be customized by altering those highlighted values choosing from wingding listing.
  SetIndexBuffer(2, Buffer3);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(2, PLOT_ARROW, 236);
   SetIndexBuffer(3, Buffer4);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(3, PLOT_ARROW, 238);

El otro aspecto es el código de colores utilizando MQL5. Estos colores pueden optimizarse a través de los ajustes de entrada en MetaTrader 5. Cada color está representado por un código único dentro de un programa. Por ejemplo: "C'0,0,0'"  representa el negro. Véase el fragmento de código siguiente:

#property indicator_type3 DRAW_ARROW
#property indicator_width3 1  // with can be adjusted up to 5 times.
#property indicator_color3 0x04CC04 //color for buy reversal
#property indicator_label3 "buy reversal"

#property indicator_type4 DRAW_ARROW
#property indicator_width4 1              //with can be adjusted up to 5 times.
#property indicator_color4 0xE81AC6  // Color code for sell reversal
#property indicator_label4 "sell reversal"

Más detalles y comentarios en el código principal a continuación después de haber combinado todas las piezas y la idea juntas.

///Indicator Name: Trend Constraint
#property copyright "Clemence Benjamin"
#property link      "https://mql5.com"
#property version   "1.03"
#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 4
#property indicator_plots 4

#property indicator_type1 DRAW_ARROW
#property indicator_width1 5
#property indicator_color1 0xFF3C00
#property indicator_label1 "Buy"

#property indicator_type2 DRAW_ARROW
#property indicator_width2 5
#property indicator_color2 0x0000FF
#property indicator_label2 "Sell"

#property indicator_type3 DRAW_ARROW
#property indicator_width3 1
#property indicator_color3 0x04CC04
#property indicator_label3 "Buy Reversal"

#property indicator_type4 DRAW_ARROW
#property indicator_width4 1
#property indicator_color4 0xE81AC6
#property indicator_label4 "Sell Reversal"

#define PLOT_MAXIMUM_BARS_BACK 5000
#define OMIT_OLDEST_BARS 50

//--- indicator buffers
double Buffer1[];
double Buffer2[];
double Buffer3[];
double Buffer4[];

input double Oversold = 30;
input double Overbought = 70;
datetime time_alert; //used when sending alert
input bool Audible_Alerts = true;
input bool Push_Notifications = true;
double myPoint; //initialized in OnInit
int RSI_handle;
double RSI[];
double Open[];
double Close[];
int MA_handle;
double MA[];
int MA_handle2;
double MA2[];
int MA_handle3;
double MA3[];
int MA_handle4;
double MA4[];
double Low[];
double High[];

void myAlert(string type, string message)
  {
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
     }
   else if(type == "modify")
     {
     }
   else if(type == "indicator")
     {
      if(Audible_Alerts) Alert(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Push_Notifications) SendNotification(type+" | Trend Constraint V1.03 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
  }

//+------------------------------------------------------------------+
//| 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);
   SetIndexBuffer(2, Buffer3);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(2, PLOT_ARROW, 236);
   SetIndexBuffer(3, Buffer4);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, EMPTY_VALUE);
   PlotIndexSetInteger(3, PLOT_DRAW_BEGIN, MathMax(Bars(Symbol(), PERIOD_CURRENT)-PLOT_MAXIMUM_BARS_BACK+1, OMIT_OLDEST_BARS+1));
   PlotIndexSetInteger(3, PLOT_ARROW, 238);
   //initialize myPoint
   myPoint = Point();
   if(Digits() == 5 || Digits() == 3)
     {
      myPoint *= 10;
     }
   RSI_handle = iRSI(NULL, PERIOD_CURRENT, 14, PRICE_CLOSE);
   if(RSI_handle < 0)
     {
      Print("The creation of iRSI has failed: RSI_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle = iMA(NULL, PERIOD_CURRENT, 7, 0, MODE_SMMA, 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, 400, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle2 < 0)
     {
      Print("The creation of iMA has failed: MA_handle2=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle3 = iMA(NULL, PERIOD_CURRENT, 100, 0, MODE_EMA, PRICE_CLOSE);
   if(MA_handle3 < 0)
     {
      Print("The creation of iMA has failed: MA_handle3=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   MA_handle4 = iMA(NULL, PERIOD_CURRENT, 200, 0, MODE_SMA, PRICE_CLOSE);
   if(MA_handle4 < 0)
     {
      Print("The creation of iMA has failed: MA_handle4=", 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);
   ArraySetAsSeries(Buffer3, true);
   ArraySetAsSeries(Buffer4, true);
   //--- initial zero
   if(prev_calculated < 1)
     {
      ArrayInitialize(Buffer1, EMPTY_VALUE);
      ArrayInitialize(Buffer2, EMPTY_VALUE);
      ArrayInitialize(Buffer3, EMPTY_VALUE);
      ArrayInitialize(Buffer4, EMPTY_VALUE);
     }
   else
      limit++;
   datetime Time[];
   
   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(RSI_handle) <= 0) 
      return(0);
   if(CopyBuffer(RSI_handle, 0, 0, rates_total, RSI) <= 0) return(rates_total);
   ArraySetAsSeries(RSI, true);
   if(CopyOpen(Symbol(), PERIOD_M1, 0, rates_total, Open) <= 0) return(rates_total);
   ArraySetAsSeries(Open, true);
   if(CopyClose(Symbol(), PERIOD_D1, 0, rates_total, Close) <= 0) return(rates_total);
   ArraySetAsSeries(Close, true);
   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(BarsCalculated(MA_handle3) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle3, 0, 0, rates_total, MA3) <= 0) return(rates_total);
   ArraySetAsSeries(MA3, true);
   if(BarsCalculated(MA_handle4) <= 0) 
      return(0);
   if(CopyBuffer(MA_handle4, 0, 0, rates_total, MA4) <= 0) return(rates_total);
   ArraySetAsSeries(MA4, 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);
   if(CopyTime(Symbol(), Period(), 0, rates_total, Time) <= 0) return(rates_total);
   ArraySetAsSeries(Time, 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(RSI[i] < Oversold
      && RSI[i+1] > Oversold //Relative Strength Index crosses below fixed value
      && Open[barshift_M1[i]] >= Close[1+barshift_D1[i]] //Candlestick Open >= Candlestick Close
      && MA[i] > MA2[i] //Moving Average > Moving Average
      && MA3[i] > MA4[i] //Moving Average > Moving Average
      )
        {
         Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer1[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 2
      if(RSI[i] > Overbought
      && RSI[i+1] < Overbought //Relative Strength Index crosses above fixed value
      && Open[barshift_M1[i]] <= Close[1+barshift_D1[i]] //Candlestick Open <= Candlestick Close
      && MA[i] < MA2[i] //Moving Average < Moving Average
      && MA3[i] < MA4[i] //Moving Average < Moving Average
      )
        {
         Buffer2[i] = High[i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer2[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 3
      if(MA3[i] > MA4[i]
      && MA3[i+1] < MA4[i+1] //Moving Average crosses above Moving Average
      )
        {
         Buffer3[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Buy Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer3[i] = EMPTY_VALUE;
        }
      //Indicator Buffer 4
      if(MA3[i] < MA4[i]
      && MA3[i+1] > MA4[i+1] //Moving Average crosses below Moving Average
      )
        {
         Buffer4[i] = High[i]; //Set indicator value at Candlestick High
         if(i == 1 && Time[1] != time_alert) myAlert("indicator", "Sell Reversal"); //Alert on next bar open
         time_alert = Time[1];
        }
      else
        {
         Buffer4[i] = EMPTY_VALUE;
        }
     }
   return(rates_total);
  }
//Thank you for getting this far, you are amazing.
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+


Exploración de los resultados del sistema final

Los resultados del sistema son impresionantes. Ahora podemos limitar nuestro sistema de señales al sentimiento del mercado D1 y también recibir señales cuando ocurre un impulso de reversión a través del cruce de EMA (100) y SMA (200). Aquí hay imágenes que muestran la salida del indicador en el historial del gráfico real. El sistema parece funcionar excepcionalmente bien a la hora de capturar los cambios en el sentimiento del mercado e identificar posibles puntos de reversión. Al centrarnos en el sentimiento del mercado D1 y utilizar las señales de cruce EMA (100) y SMA (200), podemos mejorar nuestras estrategias comerciales y tomar decisiones más informadas. La salida del indicador en los datos del gráfico histórico demuestra claramente la eficacia de estas señales para predecir los movimientos del mercado.

USDJPYM1 con Trend Constraint v1.03

Fig. 4: Resultados de Trend Constraint V1.03 en USDJPYmicroM1

Nota: Si tiene problemas con flechas de señal faltantes en su gráfico después de agregar el indicador, intente actualizar haciendo clic derecho con el botón del mouse (RMB) mientras está en el gráfico MT5 y seleccionando "Actualizar" en el menú que aparece.

Los datos recogidos de los desarrollos que estamos realizando pueden incorporarse posteriormente a sistemas de aprendizaje automático e inteligencia artificial para perfeccionarlos. Estos sistemas pueden entrenarse para realizar análisis avanzados, lo que sería beneficioso para superar los retos a los que nos hemos enfrentado con el modelo actual. Las señales de la imagen de resultados de arriba concuerdan con la idea, pero también hubo algunas señales engañosas. Esto es típico de cualquier sistema y sirve de motivación para explorar métodos adicionales para mejorar nuestro sistema actual. Los sintéticos pueden proporcionar diversos resultados al utilizar este sistema, tal y como ofrece Deriv Limited.


Vídeo explicativo de los resultados

Vea el video a continuación para explorar el rendimiento del desarrollo de nuestra nueva versión.




Conclusión

La incorporación de funciones de detección de cambios de tendencias a nuestro sistema lo ha mejorado significativamente. Si bien limitamos nuestras señales a la tendencia actual del mercado, hemos mitigado con éxito las pérdidas potenciales que podrían surgir de señales que respaldan una tendencia invalidada, a pesar de que el sentimiento D1 la respalda. Hemos encontrado problemas con las señales de reversión proporcionadas por este sistema durante una tendencia persistente. Para abordar esto, he decidido ampliar el período de los promedios móviles utilizados. En próximos artículos volveré a tratar este tema para profundizar en cómo se desarrolló este ajuste. Espero que esta conversación le resulte útil y agradezco sus opiniones en la sección de comentarios a continuación. Nuestros futuros artículos incorporarán visualizaciones avanzadas de nuestro sistema de indicadores utilizando el versátil lenguaje MQL5.




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

Redes neuronales: así de sencillo (Parte 85): Predicción multidimensional de series temporales Redes neuronales: así de sencillo (Parte 85): Predicción multidimensional de series temporales
En este artículo presentaremos un nuevo método complejo de previsión de series temporales que combina armoniosamente las ventajas de los modelos lineales y los transformadores.
Algoritmo de optimización Brain Storm - Brain Storm Optimization (Parte I): Clusterización Algoritmo de optimización Brain Storm - Brain Storm Optimization (Parte I): Clusterización
En este artículo analizaremos un innovador método de optimización denominado BSO (Brain Storm Optimization), inspirado en el fenómeno natural de la tormenta de ideas. También discutiremos un nuevo enfoque de resolución de tareas de optimización multimodales que utiliza el método BSO y nos permite encontrar múltiples soluciones óptimas sin tener que determinar de antemano el número de subpoblaciones. En este artículo, también analizaremos los métodos de clusterización K-Means y K-Means++.
Particularidades del trabajo con números del tipo double en MQL4 Particularidades del trabajo con números del tipo double en MQL4
En estos apuntes hemos reunido consejos para resolver los errores más frecuentes al trabajar con números del tipo double en los programas en MQL4.
Características del Wizard MQL5 que debe conocer (Parte 20): Regresión simbólica Características del Wizard MQL5 que debe conocer (Parte 20): Regresión simbólica
La regresión simbólica es una forma de regresión que parte de supuestos mínimos o nulos sobre cómo sería el modelo subyacente que traza los conjuntos de datos objeto de estudio. Aunque puede implementarse mediante Métodos Bayesianos o Redes Neuronales, veremos cómo una implementación con Algoritmos Genéticos puede ayudar a personalizar una clase de señal experta utilizable en el asistente MQL5.