English Русский 中文 Deutsch 日本語 Português
preview
Desarrollando un canal de Donchian personalizado con la ayuda de MQL5

Desarrollando un canal de Donchian personalizado con la ayuda de MQL5

MetaTrader 5Trading | 11 octubre 2023, 15:14
492 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introducción

En este artículo hablaremos sobre una parte muy importante del trading: la identificación de tendencias. Asimismo, estudiaremos una herramienta técnica que puede resultar útil en este asunto, hoy hablaremos del canal de Donchian. Se trata de un indicador de seguimiento de tendencia.

Todas estas cuestiones se tratarán en los siguientes apartados:


¡Atención! Toda la información del presente artículo se ofrece «tal cual», únicamente con fines ilustrativos, y no supone ningún tipo de recomendación. El artículo no garantiza ningún resultado en absoluto. Todo lo que ponga en práctica usando este artículo como base, lo hará bajo su propia cuenta y riesgo; el autor no garantiza resultado alguno.


Definición de canal de Donchian

En esta sección definiremos el canal de Donchian y consideraremos sus principios de aplicación. El canal de Donchian fue desarrollado por el tráder Richard Donchian. Su objetivo principal es detectar una tendencia. Se trata de un indicador rezagado de monitoreo de tendencias, ya que sigue las direcciones de las tendencias y los movimientos del precio. Consta de tres líneas que forman un canal en el que se encuentra el precio. La línea del canal superior representa el precio más alto registrado durante un tiempo determinado, la línea del canal inferior representa el precio más bajo durante un periodo de tiempo determinado y la línea media representa la mitad de la distancia entre las líneas superior e inferior.

A continuación le mostramos un ejemplo de canal:

ejemplo de indicador

En el gráfico vemos una línea por encima de los precios, otra debajo de los mismos y una tercera entre ellos. El indicador contiene o rodea los precios con una línea superior e inferior además de otra línea media que también puede resultar útil. El indicador puede ser la base para diversas estrategias de búsqueda de tendencias, concretamente para buscar rupturas y líneas de apoyo/resistencia.

El principio básico del uso del indicador consiste en observar los máximos y mínimos de los precios durante un periodo de tiempo para determinar las tendencias o la dirección predominante. Si el precio está por encima del máximo de un momento determinado, esto podría ser una señal de compra, mientras que si el precio está por debajo del mínimo más bajo de un momento determinado, esto podría ser una señal de venta. Entonces, tras especificar un cierto periodo de tiempo y determinar los máximos y mínimos del precio, observaremos el precio hasta que los precios comienzan a moverse en una determinada dirección hacia arriba o hacia abajo: la señal aquí será la ruptura del máximo o mínimo predeterminado.

El indicador se puede usar para determinar los niveles de stop loss y take profit. Esto resulta muy importante en el trading porque reduce la probabilidad de cometer errores al establecer los niveles si se utilizan los parámetros correctos. Por ejemplo, el mínimo del canal se puede usar como nivel de stop loss para una posición de compra o como nivel de take profit para una posición de venta. El máximo del canal se puede utilizar como stop loss para una posición de venta o como take profit para una posición de compra.

Veamos el método de cálculo del indicador:

  • Línea superior (CH)= Máximo más alto de los últimos N periodos
  • Línea Inferior (CL)= Mínimo más bajo de los últimos N periodos
  • Línea media (ML)= (CH+CL)/2

Por consiguiente, tendremos que determinar el periodo de tiempo deseado durante el cual deberemos determinar la dirección, detectar el precio máximo y mínimo, trazar las líneas de observación y obtener la línea media calculando la mitad de la distancia entre los extremos del precio. Mientras que el canal Donchian muestra el máximo más alto y el mínimo más bajo durante un periodo de tiempo, las Bandas de Bollinger muestran el promedio durante un periodo de tiempo después de sumar y restar dos desviaciones estándar. Para obtener más información sobre las Bandas de Bollinger y cómo crear un sistema comercial basado en ellas, le propongo leer uno de mis artículos anteriores.

Le recomiendo utilizar el canal junto con otros indicadores técnicos para obtener una imagen completa del mercado, además de mejores resultados.


Canal de Donchian personalizado

En esta sección, veremos un método que podemos utilizar para crear nuestro propio canal Donchian usando MQL5. Así, crearemos un indicador que tendrá una línea superior, una inferior y una media. 

Luego crearemos parámetros adicionales con los siguientes valores de identificador:

  • indicator_chart_window - muestra el indicador en la ventana del gráfico.
  • indicator_buffers - número de búferes de cálculo de indicadores. El valor utilizado será (3).
  • indicator_plots - número de series gráficas en el indicador. El valor utilizado será (3).
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3

Después crearemos dos parámetros de entrada: uno para el periodo y otro para el color de las líneas del indicador, como se muestra a continuación:

  • Crearemos una variable entera (indPeriod) y estableceremos 20 como valor predeterminado. Usted puede usar un valor diferente.
  • Luego crearemos una variable de color (indColor) y estableceremos el color azul como valor predeterminado. También podrá usar un valor diferente.
input int indPeriod=20; //Period
input color indColor=clrBlue; //Color

Ahora crearemos variables las globales como se muestra a continuación:

  • arrays de tipo doble - upperBuff, lowerBuff, middleBuff
  • arrays de tipo double - upperLine, lowerLine, middleLine
  • tipo de variable entera - start y bar
double upperBuff[];
double lowerBuff[];
double middleBuff[];
double upperLine,lowerLine,middleLine;
int start, bar;

Después crearemos una función de indicador personalizada usando void para no retornar nada y crearemos una variable indInit con tres parámetros (índice, búfer en forma de array dinámico y etiqueta en forma de línea para cada línea del indicador). En el cuerpo de la función haremos lo siguiente:

  • Usaremos la función SetIndexBuffer, que conecta el indicador especificado con un array dinámico unidimensional. Sus parámetros serán:
    • index - indica el número del búfer de indicador. Usaremos una variable de índice.
    • buffer[] - define el array dinámico buffer[] creado.
    • data_type - define los valores predeterminados que necesitamos guardar (INDICATOR_DATA).
  • Usaremos la función PlotIndexSetInteger cinco veces con diferentes parámetros prop-id y prop_value, como veremos en el código. La función establecerá el valor de la línea de indicador correspondiente. La propiedad del indicador deberá ser un número entero. Parámetros:
    • plot_index - determina el índice de dibujado. Usaremos una variable de índice.
    • prop_id - define el valor del identificador de propiedad, que puede ser uno de ENUM_PLOT_PROPERT_INTEGER.
    • prop_value - define el valor de una propiedad específica en prop_id.
  • Usaremos la función PlotIndexSetString, que establece el valor del indicador de propiedad de fila correspondiente. Sus parámetros serán los mismos que los de la función PlotIndexSetInteger, pero la propiedad del indicador aquí deberá ser una línea.
  • Usaremos la función PlotIndexSetDouble para establecer el valor del indicador de propiedad double correspondiente. Los parámetros serán los mismos, pero la propiedad del indicador deberá ser de tipo double.
void indInit(int index, double &buffer[],string label)
  {
   SetIndexBuffer(index,buffer,INDICATOR_DATA);
   PlotIndexSetInteger(index,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(index,PLOT_LINE_WIDTH,2);
   PlotIndexSetInteger(index,PLOT_DRAW_BEGIN,indPeriod-1);
   PlotIndexSetInteger(index,PLOT_SHIFT,1);
   PlotIndexSetInteger(index,PLOT_LINE_COLOR,indColor);
   PlotIndexSetString(index,PLOT_LABEL,label);
   PlotIndexSetDouble(index,PLOT_EMPTY_VALUE,EMPTY_VALUE);
  }

Después de esto, en el cuerpo de OnInit() usaremos nuestra función de indicador personalizada tres veces para las tres líneas del indicador, y se verá así:

   indInit(0,upperBuff,"Donchian Channel");
   indInit(1,lowerBuff,"Donchian Channel");
   indInit(2,middleBuff,"Middle Donchian");

Luego usaremos la función IndicatorSetString para configurar la etiqueta de texto del indicador.

IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")");

En la parte de OnCalculate, realizaremos los siguientes pasos para calcular el indicador:

Después verificaremos si times_total es menor que el periodo +1 introducido por el usuario; de ser así, queremos que el programa retorne cero.

   if(rates_total<indPeriod+1)
     {
      return 0;
     }

A continuación, asignaremos un valor a la variable start usando el operador ternario ?: - si start=prev_calculated==0 es true, el operador se establecerá en indPeriod. Si es false, el operador establecerá prev_calculated-1.

start=prev_calculated==0? indPeriod: prev_calculated-1;

Usaremos la función for para crear un ciclo para calcular el indicador, la expresión 1 será (bar=start), la expresión 2 será (bar < rate_total), mientras que la expresión 3 será (bar ++) para incrementar la barra en uno. La declaración del bucle for será igual a la siguiente:

  • Calcularemos UpperLine determinando el valor máximo high usando la función ArrayMaximum, que busca el mayor valor en el array.
  • Calcularemos lowerLine determinando el valor mínimo low con la función ArrayMinimum, que busca el menor valor en el array.
  • Calcularemos middleLine dividiendo la suma de UpperLine y LowerLine por 2
  • Asignaremos los valores a UpperBuff[bar], lowerBuff[bar] y middleBuff[bar}
   for(bar=start;bar<rates_total;bar++)
   {
      upperLine=high[ArrayMaximum(high,bar-indPeriod+1,indPeriod)];
      lowerLine=low[ArrayMinimum(low,bar-indPeriod+1,indPeriod)];
      middleLine=(upperLine+lowerLine)/2;
      
      upperBuff[bar]=upperLine-(upperLine-lowerLine);
      lowerBuff[bar]=lowerLine+(upperLine-lowerLine);
      middleBuff[bar]=middleLine;

   }

El código completo se verá así:

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
input int indPeriod=20; //Period
input color indColor=clrBlue; //Color
double upperBuff[];
double lowerBuff[];
double middleBuff[];
double upperLine,lowerLine,middleLine;
int start, bar;
void indInit(int index, double &buffer[],string label)
  {
   SetIndexBuffer(index,buffer,INDICATOR_DATA);
   PlotIndexSetInteger(index,PLOT_DRAW_TYPE,DRAW_LINE);
   PlotIndexSetInteger(index,PLOT_LINE_WIDTH,2);
   PlotIndexSetInteger(index,PLOT_DRAW_BEGIN,indPeriod-1);
   PlotIndexSetInteger(index,PLOT_SHIFT,1);
   PlotIndexSetInteger(index,PLOT_LINE_COLOR,indColor);
   PlotIndexSetString(index,PLOT_LABEL,label);
   PlotIndexSetDouble(index,PLOT_EMPTY_VALUE,EMPTY_VALUE);
  }
int OnInit()
  {
   indInit(0,upperBuff,"Donchian Channel");
   indInit(1,lowerBuff,"Donchian Channel");
   indInit(2,middleBuff,"Middle Donchian");
   IndicatorSetString(INDICATOR_SHORTNAME,"Donchian ("+IntegerToString(indPeriod)+")");

   return(INIT_SUCCEEDED);
  }
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[])
  {
   if(rates_total<indPeriod+1)
     {
      return 0;
     }
   start=prev_calculated==0? indPeriod: prev_calculated-1;
   for(bar=start;bar<rates_total;bar++)
   {
      upperLine=high[ArrayMaximum(high,bar-indPeriod+1,indPeriod)];
      lowerLine=low[ArrayMinimum(low,bar-indPeriod+1,indPeriod)];
      middleLine=(upperLine+lowerLine)/2;
      
      upperBuff[bar]=upperLine-(upperLine-lowerLine);
      lowerBuff[bar]=lowerLine+(upperLine-lowerLine);
      middleBuff[bar]=middleLine;
   }
   return(rates_total);
  }

El código deberá compilarse sin errores ni advertencias; luego buscaremos el indicador en la ventana "Navegador" del terminal comercial en la carpeta "Indicadores" y, una vez ejecutado, abriremos la ventana de parámetros e introduciremos lo siguiente:

parámetros de entrada del indicador

Como podemos ver, tenemos dos parámetros de entrada:

  • Period - define el periodo de tiempo para calcular el indicador. El valor predeterminado será 20.
  • Color - define el color de las líneas del indicador. El valor predeterminado será azul.

Tras configurar los parámetros y clicar en OK, el indicador se adjuntará al gráfico:

indicador adjunto

Como podemos ver, todo parece como debería.


Asesor del canal de Donchian

Hoy vamos a usar un canal Donchian personalizado en el sistema comercial, creando un asesor para generar señales basadas en el movimiento o comportamiento del indicador. Podemos hacer esto usando dos métodos diferentes: el primero es escribir el código del indicador en el asesor; el segundo consiste en usar la función iCustom para adjuntar el indicador creado al asesor. Aquí desarrollaremos sistemas muy simples para entender la idea general, así como la forma en que podemos mejorar estos sistemas basándonos en el segundo método considerado al crear el asesor.

Asesor simple del canal de Donchian

Ahora crearemos el primer sistema que mostrará los valores del indicador (canales superior, medio e inferior) en el gráfico. El programa monitoreará continuamente estos valores y los mostrará en el gráfico en forma de comentario.

A continuación detallaremos los pasos para crear el asesor:

Para ello, crearemos una variable de entrada para el periodo del indicador con el valor predeterminado (20). El usuario podrá actualizar el valor de los parámetros de entrada del asesor. 

input int indPeriod=20; //Period

Luego crearemos la variable global entera donChianChannel.

int donchianChannel;

En la parte OnInit(), actualizaremos donchianChannel asignándole la función iCustom, que retornará el descriptor del indicador personalizado creado. Los parámetros serán los siguientes:

  • symbol — nombre del símbolo; para nosotros será _Symbol, es decir, calcularemos el indicador según el símbolo del gráfico actual.
  • period - marco temporal para el cálculo; el valor PERIOD_CURRENT implicará que el indicador se calculará en el marco temporal actual
  • name - especifica el nombre de cadena del indicador y la ruta al mismo.
  • Después de esto, indicaremos los datos de entrada del indicador, es decir, su periodo.
donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);

En la parte OnDeinit(), usaremos la función Print para retornar el mensaje Donchian Channel EA Removed cuando el asesor se elimine.

Print("Donchian Channel EA Removed");

En la parte OnTick(), crearemos tres arrays ChannelBuff, ChannelBuff1 y MiddleBuff.

double channelBuff[],channelBuff1[], middleBuff[];

Usaremos la función CopyBuffer para obtener los datos de cada búfer del canal de Donchian personalizado. Sus parámetros serán:

  • indicator_handle - para especificar el identificador del indicador, usaremos el identificador donchianChannel creado para los tres búferes.
  • buffer_num - número de búfer: 0 - canalBuff, 1 - canalBuff1 y 2 - middleBuff.
  • start_pos - posición del primer elemento a copiar. Usaremos 0 para los tres búferes.
  • count - cantidad de datos a copiar. Usaremos 3 para los tres búferes.
  • buffer[] - para especificar el array de destino a copiar; especificaremos tres búferes (channelBuff, channelBuff1 y middleBuff).
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);

Determinemos los valores actuales de cada fila tras crear una variable double para todas.

   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];

Utilizaremos la función Comment para retornar al gráfico un comentario con tres valores, cada uno en una línea separada.

Comment("Channel High: ",channelHigh,"\nChannel Middle: ",channelMiddle,"\nChannel Low: ",channelLow);

El código completo se verá así:

input int indPeriod=20; //Period
int donchianChannel;
int OnInit()
  {
   donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Donchian Channel EA Removed");
  }
void OnTick()
  {
   double channelBuff[],channelBuff1[], middleBuff[];
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);
   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];
   Comment("Channel High: ",channelHigh,"\nChannel Middle: ",channelMiddle,"\nChannel Low: ",channelLow);
  }

Después de compilar con éxito, el código aparecerá en la ventana del Navegador en la carpeta "Asesores". Al iniciar el asesor experto en un gráfico, la ventana de parámetros se verá así:

Ventana de parámetros de entrada de dcSimpleEA

Después de iniciar el asesor en el gráfico, veremos los valores del canal de Donchian en forma de comentario:

asesor dcSimpleEA iniciado y una señal

El gráfico contendrá la señal deseada en forma de comentario con tres valores de indicador (Channel High, Channel Middle y Channel Low). Cada valor estará en una línea aparte.

Si comparamos los valores de las señales del asesor y los valores del indicador, veremos que los valores en la ventana de datos son los mismos que los valores de las señales del asesor:

La señal dcSimpleEA coincide con los valores del indicador


Si queremos que el asesor encuentre señales según los movimientos y niveles del indicador, podemos mejorarla estableciendo las condiciones necesarias para recibir señales de compra y venta.

Asesor Donchian Channel Breakout:

En esta versión del asesor, necesitaremos que el programa verifique constantemente los valores de los tres indicadores, y si el precio (ask) supera el máximo del canal, necesitaremos recibir una señal de compra como comentario en el gráfico. En consecuencia, si el precio (bid) supera el mínimo del canal, necesitaremos recibir una señal de venta. En todos los demás casos, no será necesario recibir nada.

A continuación le mostramos el código completo para crear este tipo de sistema comercial en forma de asesor:

input int indPeriod=20; //Period
int donchianChannel;
int OnInit()
  {
   donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Donchian Channel EA Removed");
  }
void OnTick()
  {
   double channelBuff[],channelBuff1[], middleBuff[];
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);
   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];
   double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   if(ask>channelHigh)
     {
      Comment("Buy Signal");
     }
     else if(bid<channelLow)
     {
      Comment("Sell Signal");
     }
     else Comment(" ");
  }

Cuáles son las diferencias en este código:

La definición de ask y bid utilizando la función SymbolInfoDouble para retornar los valores de la propiedad (ask, bid) tras crear variables double para ellos.

   double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);

Condiciones de la estrategia:

En caso de compra

Necesitaremos que el programa verifique el ask y el máximo del canal para determinar sus posiciones. Si ask supera el máximo del canal, esta será una condición de compra y necesitaremos que el asesor retorne una señal de compra como comentario en el gráfico una vez que se cumpla esta condición.

   if(ask>channelHigh)
     {
      Comment("Buy Signal");
     }

En caso de venta

Necesitaremos que el programa verifique el bid y el mínimo del canal para determinar sus posiciones. Si ask está por debajo del mínimo del canal, esta será una condición de venta y necesitaremos que el asesor retorne una señal de venta como comentario en el gráfico una vez que se cumpla esta condición.

     else if(bid<channelLow)
     {
      Comment("Sell Signal");
     }

En los demás casos

Necesitaremos que el asesor no retorne nada si hay algo aparte de las condiciones de compra o venta.

else Comment(" ");

Tras realizar la compilación con éxito, arrastraremos el asesor al gráfico deseado para obtener las señales:

En caso de una señal de compra

señal de compra dcBreakout

En la esquina superior izquierda del gráfico veremos una señal de compra después de romperse el máximo del canal hacia arriba.

En caso de una señal de venta:

señal de venta dcBreakout

En la esquina superior izquierda del gráfico veremos una señal de venta después de romperse el mínimo del canal hacia abajo.

En los demás casos

sin señal dcBreakout

Como podemos ver, no hay señal, ya que el precio se mueve dentro del canal, por debajo del máximo del canal y por encima del mínimo.

Canal de Donchian y ruptura de la media móvil:

Ahora necesitaremos mejorar un poco el asesor. Para ello, filtraremos las señales añadiendo una media móvil a las condiciones de la estrategia. Por consiguiente, necesitaremos obtener una señal de compra cuando el precio ask supere el máximo del canal en caso de que la EMA (media móvil exponencial) de 200 periodos esté por debajo del precio ask. En el caso de una señal de venta, deberemos asegurarnos de que el precio bid haya caído por debajo del mínimo del canal y, al mismo tiempo, que la EMA de 200 periodos esté por encima del precio bid. En todos los demás casos no deberíamos recibir nada.

A continuación le mostramos el código completo para crear este tipo de sistema comercial:

input int indPeriod=20; //Period
input int maPeriod=200; //Moving Average Period
int donchianChannel;
int EMA;
double emaArray[];
int OnInit()
  {
   donchianChannel=iCustom(_Symbol,PERIOD_CURRENT,"My Files\\Donchian_Channel\\Donchian_Channel",indPeriod);
   EMA = iMA(_Symbol,_Period,maPeriod,0,MODE_EMA,PRICE_CLOSE);
   return(INIT_SUCCEEDED);
  }
void OnDeinit(const int reason)
  {
   Print("Donchian Channel EA Removed");
  }
void OnTick()
  {
   double channelBuff[],channelBuff1[], middleBuff[];
   CopyBuffer(donchianChannel,0,0,3,channelBuff);
   CopyBuffer(donchianChannel,1,0,3,channelBuff1);
   CopyBuffer(donchianChannel,2,0,3,middleBuff);
   ArraySetAsSeries(emaArray,true);
   CopyBuffer(EMA,0,0,3,emaArray);
   double channelHigh=channelBuff1[0];
   double channelMiddle=middleBuff[0];
   double channelLow=channelBuff[0];
   double EMAValue=NormalizeDouble(emaArray[0],_Digits);
   double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);
   if(ask>channelHigh&&ask>EMAValue)
     {
      Comment("Buy Signal","\nAsk above Channel High","\nAsk above (",maPeriod,") EMA");
     }
     else if(bid<channelLow&&bid<EMAValue)
     {
      Comment("Sell Signal","\nBid below Channel Low","\nBid Below (",maPeriod,") EMA");
     }
     else Comment(" ");
  }

Cuáles son las diferencias en este código:

Crearemos otro parámetro de entrada para la variable entera maPeriod con el valor predeterminado (200).

input int maPeriod=200; //Moving Average Period

Crearemos una variable entera global EMA.

int EMA;

Crearemos un array emaArray[]

double emaArray[];

Actualizaremos la variable EMA usando la función iMA para retornar el descriptor del indicador de media móvil y sus parámetros:

  • symbol - símbolo; en nuestro caso, (_Symbol), es decir, calcularemos el indicador según el símbolo del gráfico actual.
  • period - marco temporal para el cálculo; el valor (_period) significará que el indicador se calculará en el marco temporal actual.
  • ma_period - periodo de promediación; usaremos un parámetro de entrada personalizado (maPeriod).
  • ma_shift - especificaremos (0), ya que no se requiere ningún desplazamiento.
  • ma_method - tipo de media móvil; usaremos (MODE_EMA), ya que necesitamos una media móvil exponencial.
  • applied_price - tipo de precio; utilizaremos (PRICE_CLOSE).
EMA = iMA(_Symbol,_Period,maPeriod,0,MODE_EMA,PRICE_CLOSE);

Usaremos la función ArraySetAsSeries para configurar AS_SERIES. Aquí tenemos sus parámetros:

  • array[] - para especificar un array, utilizaremos emaArray.
  • flag - dirección de indexación en el array; será true.
ArraySetAsSeries(emaArray,true);

Usaremos la función para obtener los datos del búfer de media móvil.

CopyBuffer(EMA,0,0,3,emaArray);

Determinaremos el valor de la EMA y lo normalizaremos.

double EMAValue=NormalizeDouble(emaArray[0],_Digits);

Condiciones de la estrategia:

En caso de compra

Si el precio > máximo del canal, se mostrará el siguiente comentario en el gráfico

  • Señal de compra
  • Ask por encima del máximo del canal
  • Ask por encima del periodo EMA
   if(ask>channelHigh&&ask>EMAValue)
     {
      Comment("Buy Signal","\nAsk above Channel High","\nAsk above (",maPeriod,") EMA");
     }

En caso de venta

Si el precio < mínimo del canal, se mostrará el siguiente comentario en el gráfico

  • Señal de venta
  • Bid por debajo del mínimo del canal
  • Bid por debajo del periodo EMA
     else if(bid<channelLow&&bid<EMAValue)
     {
      Comment("Sell Signal","\nBid below Channel Low","\nBid Below (",maPeriod,") EMA");
     }

Si no hay señal

else Comment(" ");

Tras realizar la compilación y el inicio en el gráfico con éxito, veremos las siguientes señales comerciales

En caso de una señal de compra

señal de compra dc & EMABreakout

Como podemos ver, tenemos una señal de compra (el precio se encuentra por encima del máximo del canal y la EMA de 200).

En caso de una señal de venta:

señal de venta dc y EMABreakout

Tenemos una señal de venta (el precio se encuentra por debajo del mínimo del canal y la EMA de 200).

Si no hay señal

sin señal CC y EMABreakout

No hay señal. El precio está por debajo de la EMA de 200, pero por encima del mínimo y por debajo del máximo del canal.


Conclusión

En el presente artículo hemos podido convencernos de que el canal de Donchian puede resultar una herramienta útil y valiosa, especialmente en el contexto de la ejecución personalizada y como parte de los sistemas comerciales. El lector podrá crear sus propios canales de Donchian según sus preferencias. También podrá crear un sistema comercial utilizando la función iCustom para negociar o recibir señales basadas en el indicador. Asimismo, podrá mejorar su sistema comercial (asesor) añadiendo ciertas condiciones y utilizando otras herramientas técnicas.

Espero que el artículo le haya sido útil y le ayude a mejorar sus resultados comerciales. No aplique el contenido de este artículo sin realizar antes las pruebas correspondientes. Tampoco olvide que no existe una herramienta adecuada para todos los tráders. 

Clicando en los enlaces que verá a continuación, podrá leer mis otros artículos. En concreto, encontrará una serie de artículos sobre la creación de sistemas comerciales basados ​​en los indicadores técnicos más populares. Espero que los encuentre útiles.

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

Archivos adjuntos |
dcSimpleEA.mq5 (0.74 KB)
dcBreakout.mq5 (0.91 KB)
Redes neuronales: así de sencillo (Parte 45): Entrenando habilidades de exploración de estados Redes neuronales: así de sencillo (Parte 45): Entrenando habilidades de exploración de estados
El entrenamiento de habilidades útiles sin una función de recompensa explícita es uno de los principales desafíos del aprendizaje por refuerzo jerárquico. Ya nos hemos familiarizado antes con dos algoritmos para resolver este problema, pero el tema de la exploración del entorno sigue abierto. En este artículo, veremos un enfoque distinto en el entrenamiento de habilidades, cuyo uso dependerá directamente del estado actual del sistema.
Redes neuronales: así de sencillo (Parte 44): Estudiamos las habilidades de forma dinámica Redes neuronales: así de sencillo (Parte 44): Estudiamos las habilidades de forma dinámica
En el artículo anterior, nos familiarizamos con el método DIAYN, que ofrece un algoritmo para el aprendizaje de diversas habilidades. El uso de las habilidades aprendidas puede aprovecharse en diversas tareas, pero estas habilidades pueden resultar bastante impredecibles, lo cual puede dificultar su uso. En este artículo, analizaremos un algoritmo para el aprendizaje de habilidades predecibles.
Estrategia comercial de reversión a la media simple Estrategia comercial de reversión a la media simple
La reversión a la media es una técnica de negociación de contratendencia en la que el tráder espera que el precio regrese a algún tipo de equilibrio, que generalmente se mide usando una media u otro indicador estadístico de la tendencia promediada.
Comprensión y uso eficaz del simulador de estrategias MQL5 Comprensión y uso eficaz del simulador de estrategias MQL5
Para los desarrolladores de MQL5 resulta imperativo dominar herramientas importantes y valiosas. Una de esas herramientas es el simulador de estrategias. El presente artículo es una guía práctica para utilizar el simulador de estrategias MQL5.