English Русский 中文 Deutsch 日本語 Português
Comercio por los niveles de DiNapoli

Comercio por los niveles de DiNapoli

MetaTrader 5Ejemplos | 8 enero 2018, 08:32
1 503 0
Dmitriy Zabudskiy
Dmitriy Zabudskiy

Introducción

En el mercado, igual como en la vida, todo sufre cambios constantemente. Lo que funcionaba perfectamente ayer, hoy demuestra unos resultados que no intersan en absoluto. Sin embargo, quedan algunas estrategias fundamentales que con el tiempo pasan por unas correcciones cosméticas, pero siguen manteniendo su base ideológica. Una de ellas es la estrategia «Niveles de DiNapoli» que lleva el nombre de su creador. Ella representa la implementación recortada de los «retrocesos de Fibonacci». 

Los puntos de entrada de la estrategia son los niveles de Fibonacci 38,2% y 61,8%. El COP (Contracted Objective Point, punto de objetivo ajustado) — 61,8%, OP (Objective Point, punto de objetivo) — 100%, XOP (Expanded Objective Point, punto de objetivo expandido) — 161,8% se admiten como puntos de fijación del beneficio. Todas las distancias se indican en por cientos de la longitud de la tendencia (fig. 1).

Fig. 1. «Niveles de DiNapoli» en el par EURUSD, H4

Fig. 1. «Niveles de DiNapoli» en el par EURUSD, H4

En la imagen 1, los niveles se colocan a través de las herramientas de Fibonacci que forman parte de la entrega estándar de MetaTrader 5: retrocesos (color rojo) y expansiones (color azul) de Fibonacci. Además, la imagen demuestra cómo se colocan los niveles. La línea vertical marcada con dos flechas muestra el nivel de 61,8% que se coge de la tendencia (línea roja descendiente) y se coloca hacia abajo del precio máximo del retroceso (rollback), formando el nivel COP.

Hay cuatro variantes para entrar en el mercado: «Arbustos», «Bonsái», «Zapador A» y «Zapador B». Las dos primeras son las más agresivas. La entrada en el mercado a través de ellas se realiza en la primera corrección. Otros dos escenarios suponen la apertura de la posición en la segunda corrección. Otra diferencia entre estas variantes consiste en la colocación del nivel Stop Loss. La descripción detallada de estos métodos se encuentra en el artículo «Sistema comercial DiNapoli», por eso no vamos a entrar en detalles aquí.

En la figura de arriba, yo sólo quería demostrar la imagen clásica de los niveles DiNapoli, es decir, el propio fundamento de la estrategia. Vemos que lo más conveniente para entrar en el mercado es hacerlo en el nivel 61,8% (y aquí podemos ver una marca roja de precio), pero este nivel no siempre se alcanza. Por eso, algunos traders empezaban a negociar activamente en 38,2%: es evidente debido a la vela descendiente a las 20:00. Estas entradas son más propias al trading agresivo según el método «Arbustos». Siguiéndolo, el trader coloca Stop en un nivel más alto en el que ha sido abierta la posición. El cierre de la transacción ha sido en el nivel COP (61,8%). En la imagen, está marcado con la etiqueta de precio azul.

Todo eso se ve bastante sencillo, pero en la práctica, los niveles descritos no siempre tienen efecto debido al cambio frecuente de las tendencias. Para determinar una tendencia con más precisión, el autor de la estrategia propone los siguientes indicadores en adición de los niveles: la media móvil (MA) y el oscilador Stochastic. Basándose en este fundamento, yo propongo desarrollar una estrategia rentable e impementarla en el Asesor Experto (EA).


Formación de la estrategia usando las herramientas estándar de MetaTrader 5

Una estrategia eficaz del trading según los niveles de DiNapoli supone un trabajo conjunto de muchos factores. Por esa razón, su implementación de programación es bastante compleja e interesante. También hay dificultades en la organización del trading: de acuerdo con esta estrategia, a veces es necesario esperar bastante tiempo el momento para entrar en el mercado. El monitoreo constante manual no es una tarea fácil para el trader, por tanto, el factor automático va a prevalecer en este tipo del trading.

Voy a intentar explicar la estrategia que será la base para nuestro EA de forma máximamente sencilla.

Fig. 2. Niveles de DiNapoli con indicadores auxiliares, EURUSD, H4 (tendencia alcista)

Fig. 2. Niveles de DiNapoli con indicadores auxiliares, EURUSD, H4 (tendencia alcista)

En la imagen 2 se muestra el gráfico del par EURUSD H4. Este gráfico incluye los niveles DiNapoli, indicador Stochastic (8,3,3) y dos medias móviles con el desplazamiento 25 (roja) y 7 (azul).

Empezamos por orden. En el gráfico se observa una tendencia alcista a la cual se sobrepone la Cuadrícula de Fibonacci con los niveles 23,6%, 38,2%, 50%, 61,8%. Aquí hay más niveles en comparación con la implementación clásica: la práctica ha demostrado que el precio puede repelerse de cada uno de ellos. 

La expansión de Fibonacci se solapa al retroceso/rollback (corrección): así aparecen los niveles COP y OP. Sin embargo, en este caso, y en toda la estrategia en general, estos niveles son de poca importancia. Aquí, se calculan exclusivamente para colocar Take Profit (lo veremos en el código más tarde).

Al fin y al cabo, resulta que la entrada es posible en cuatro puntos. La figura demuestra que si captamos la reversión de la tendencia al mismo principio y abrimos la posición en el punto 23,6%, nos traerá el beneficio; pero la reducción (drawdown) también será bastante significante. Naturalmente, eso no nos conviene, por eso seguimos buscando un punto de entrada más seguro. 

  • La primera regla: la entrada por los niveles de DiNapoli es posible de 23,6% a 61,8%. Es un rango bastante amplio, por eso tenemos que proceder a la segunda etapa del análisis.

El siguiente filtro de la señal es el indicador Stochastic (con los parámetros 8,3,3) con dos niveles: 30 y 70.

  • La segunda regla: compramos cuando la línea de señal y la línea principal del indicador Stochastic se encuentran por debajo del nivel 30, y vendemos cuando están por encima del nivel 70.

Ahora, hay que determinar la tendencia. Para eso, usamos la media móvil (desplazamiento 5, período 25). Resulta que la compra es posible cuando el precio se encuentra por encima de la línea de tendencia, y la venta cuando está por debajo. Pero es un rango bastante grande y para reducirlo, introducimos otra media móvil (desplazamiento 5, período 7). Pero incluso usando esta MA, el rango puede ser demasiado amplio. En este caso, introducimos su reducción adicional: se permite abrir las transacciones solamente en la «mitad superior» de las diverencias, más cerca de la línea con el período 25. 

  • La tercera regla: compramos en la segunda mitad del intervalo, más cerca de la línea con el período 25, además, la línea con el período menor se encuentra por encima.
  • La cuarta regla: vendemos en la segunda mitad del intervalo, más cerca de la línea con el período 25, además, la línea con el período menor se encuentra por debajo.

Supongamos que las condiciones arriba expuestas se han cumplido, y hemos abierto la posición. Ahora, hay que aclarar las reglas del cierre. Los niveles formados por la expansión de Fibonacci, y el indicador Stochastic nos ayudarán en eso.

  • La quinta regla: cerramos la transacción si el precio alcanza uno de los niveles objetivos de DiNapoli (COP, OP, XOP), o el indicador Stochastic da la señal de cierre.

En la imagen 2 y 3, las zonas que se ajustan a estas reglas se muestran con rectángulos amarillos.

Fig. 3. Niveles de DiNapoli con indicadores auxiliares, EURUSD, H4 (tendencia bajista)

Fig. 3. Niveles de DiNapoli con indicadores auxiliares, EURUSD, H4 (tendencia bajista)

Como podemos ver, las reglas obtenidas son lógicas y comprensibles. En ellas, todavía no se estipulaba la colocación de Take Profit o Stop Loss y un pequeño trailing para pasar al punto muerto (break even). Todo eso lo consederaremos más abajo.


Codificando la estrategia

Parámetros de entrada

Primero, incluimos la clase CTrade (Trade.mqh). Luego, definimos los parámetros de los niveles de DiNapoli, el nivel mínimo y máximo de entrada. Por defecto, se establecen como se especifica más arriba: de 23,6% a 61,8%. Pero para diferentes pares de divisas pueden variar y encontrarse en diferentes límites.

Los siguientes parámetros son Take Profit y Stop Loss. Stop Loss se coloca por los niveles desde el precio máximo. En las figuras 2 y 3, se muestran en color rojo. Take Profit se establece desde el precio de la colocación de la orden.

Es decir, supongamos que el nivel de compra es 50%, Stop Loss está establecido en 70%, Take Profit en 70%. Entonces, si asumimos que 100% son 100 puntos, Stop Loss va a encontrarse por debajo del precios de compra a 20 puntos, mientras que Take Profit a 70 puntos. Eso tiene que tomarse en cuenta durante la optimización del EA.

Luego, hay que definir el trailing o el paso al punto muerto (breakeven). De acuerdo con los parámetros actuales en el código, cuando el precio pasa por 400 puntos, Stop Loss se desplazará por 10 puntos en la dirección rentable.

Los demás parámetros no requieren comentarios.

//+------------------------------------------------------------------+
//|                                               Dinapoli_v1.01.mq5 |
//|                                                          Aktiniy |
//|                                            https://www.mql5.com/ |
//+------------------------------------------------------------------+
#property copyright "Aktiniy"
#property link      "https://www.mql5.com/"
#property version   "1.01"
#include<Trade\Trade.mqh>
//--- input parameters
//--- Fibo number
input double   percent_min_enter=23.6;      // Porcentaje mínimo de la entrada
input double   percent_max_enter=61.8;      // Porcentaje máximo de la entrada
input double   percent_for_tp=60;           // Porcentaje del posible Take Profit
input double   percent_for_sl=70;           // Porcentaje del posible Stop Loss
input int      trailing_sl=400;             // Cambio al breakeven al pasar a través de los puntos
input int      trailing_profit=10;          // Nivel del breakeven en puntos
//--- order
input long     magic_number=65758473787389; // Número mágico
input double   order_volume=0.01;           // Tamaño del lote
input int      order_deviation=100;         // Desviación en la apertura de la posición
//--- Stochastic
input int      stochastic_k=8;              // Indicador Stochastic "Período %К"
input int      stochastic_d=3;              // Indicador Stochastic "Ralentización"
input int      stochastic_slowing=3;        // Indicador Stochastic "Período %D"
input double   stochastic_up_level=70;      // Indicador Stochastic "Nivel de la señal arriba"
input double   stochastic_down_level=30;    // Indicador Stochastic "Nivel de la señal abajo"
//--- MA RED 25 5
input int      ma_red_period=25;            // Indicador MA RED "Período"
input int      ma_red_shift=5;              // Indicador MA RED "Desplazamiento"
//--- MA BLUE 7 5
input int      ma_blue_period=7;            // Indicador MA BLUE " Período"
input int      ma_blue_shift=5;             // Indicador MA BLUE "Desplazamiento"
//--- Variable
CTrade trade;
int stochastic_handle=0;
char answer_stochastic=0;
int ma_red_handle=0;
int ma_blue_handle=0;
char answer_ma=0;
int fractals_handle=0;

Al final, se determinan las variables que guardan los manejadores (handle) de los indicadores y las respuestas de las funciones de las señales.

Inicialización

Luego, va una pequeña función de la inicialización. Aquí, configuramos la clase CTrade y obtenemos los manejadores de los indicadores.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   trade.SetExpertMagicNumber(magic_number);
   trade.SetDeviationInPoints(order_deviation);
   trade.SetTypeFilling(ORDER_FILLING_FOK);
   trade.SetAsyncMode(false);

   stochastic_handle=iStochastic(_Symbol,_Period,stochastic_k,stochastic_d,stochastic_slowing,MODE_SMA,STO_LOWHIGH);
   ma_red_handle=iMA(_Symbol,_Period,ma_red_period,ma_red_shift,MODE_SMA,PRICE_CLOSE);
   ma_blue_handle=iMA(_Symbol,_Period,ma_blue_period,ma_blue_shift,MODE_SMA,PRICE_CLOSE);
   fractals_handle=iFractals(_Symbol,_Period);
//---
   return(INIT_SUCCEEDED);
  }

Antes de pasar a la función principal, estudiaremos el principio de las funciones de las señales.

Obtener la señal del indicador Stochastic

//+------------------------------------------------------------------+
//| Obteniendo la señal del indicador  Stochastic                        |
//+------------------------------------------------------------------+
void Stochastic(char &answer)                                                                          // 0-sin señal; 1-señal arriba; 2-señal abajo
  {
   answer=0;                                                                                           // respuesta
   double stochastic_line_main[3];
   double stochastic_line_signal[3];
   int line_main=CopyBuffer(stochastic_handle,0,0,3,stochastic_line_main);
   int line_signal=CopyBuffer(stochastic_handle,1,0,3,stochastic_line_signal);
   if(line_main!=3 || line_signal!=3)
     {Alert("Error of copy iStochastic: main line=",line_main,", signal line=",line_signal);}          // comprobamos los datos copiados de Stochastic

   if(stochastic_line_main[1]>stochastic_up_level && stochastic_line_signal[1]>stochastic_up_level)
     {answer=2;}                                                                                       // venta favorable
   if(stochastic_line_main[1]<stochastic_down_level && stochastic_line_signal[1]<stochastic_down_level)
     {answer=1;}                                                                                       // compra favorable
  }

Todo es bastante fácil: se copian tres últimos valores del indicador, el último de ellos se compara con los niveles establecidos en los ajustes. La función traspasa la respuesta en la variable.

Obtener la señal del indicador MA

//+------------------------------------------------------------------+
//| Obteniendo la señal de los indicadores MA                        |
//+------------------------------------------------------------------+
void MA(char &answer)                                              // 0-sin señal; 1-señal arriba; 2-señal abajo
        double &line_blue,
        double &line_red,
        double ask,
        double bid)
  {
   answer=0;                                                        // respuesta
   double ma_red[3];
   double ma_blue[3];
   int red=CopyBuffer(ma_red_handle,0,0,3,ma_red);
   int blue=CopyBuffer(ma_blue_handle,0,0,3,ma_blue);
   if(red!=3 || blue!=3)
     {Alert("Error of copy iMA: MA red=",red,", MA blue=",blue);}   // copiamos los datos copiados de MA red y blue

   line_blue=ma_blue[2];
   line_red=ma_red[2];

   if(ma_blue[2]>ma_red[2])                                         // supuestamente la tendencia es alcista
      if(ask<ma_blue[2])                                            // supuestamente el precio se encuentra en una posición de retroceso
         if(ask>ma_red[2])
           {answer=1;}                                              // es posible un próximo movimiento en dirección de la tendencia (hacia arriba)

   if(ma_blue[2]<ma_red[2])                                         // supuestamente la tendencia es bajista
      if(bid>ma_blue[2])                                            // supuestamente el precio se encuentra en una posición de retroceso
         if(bid<ma_red[2])
           {answer=2;}                                              // es posible un próximo movimiento en dirección de la tendencia (hacia abajo)
  }

Aquí, los tres últimos valores también se copian a los búferes, después de lo cual se determina si el precio se encuentra entre dos líneas del indicador a través de la comparación. Antes ya hemos dicho que a menudo es necesario reducir el intervalo en el que se admite el trading. Precisamente por eso esta función traspasa no sólo la respuesta, sino también los últimos valores de dos MAs. Más tarde consideraremos el mecanismo de la reducción del intervalo.

Obteniendo los datos del indicador Fractals

La función para determinar el tamaño de la tendencia es más complicada. Está implementada a base de los datos del indicador Fractals. Al principio de la función se copian 100 últimos datos, luego se realiza la comprobación de las señales inferiores y superiores a través de dos ciclos. Aquí, se realiza la prueba de la presencia del fractal: todos los valores más de 10 000 se filtran, luego se comparan los valores adyacentes en busca del primer fractal más grande y más pequeño desde el final.

//+------------------------------------------------------------------+
//| Obteniendo los datos del indicador Fractals                      |
//+------------------------------------------------------------------+
void Fractals(double &price_up,
              double &price_down)
  {
   price_up=0;
   price_down=0;
   double fractals_up[100];
   double fractals_down[100];
   int up=CopyBuffer(fractals_handle,0,0,100,fractals_up);
   int down=CopyBuffer(fractals_handle,1,0,100,fractals_down);
   if(up!=100 || down!=100)
     {Alert("Error of copy iFractals: Fractals up=",up,", Fractals down=",down);} // comprobamos los datos copiados de Fractals up y down

   double price_high=0;
   double price_low=0;

   for(int x=99; x>0; x--)                                                        // ciclo para el fractal superior
     {
      if(fractals_up[x]<10000)                                                    // comprobando la presencia del fractal
        {
         if(price_high==0){price_high=fractals_up[x];}                            // primera comprobación
         if(price_high>fractals_up[x]){break;}                                    // si los fractales han ido hacia abajo, detenemos el ciclo
         else{price_high=fractals_up[x];}                                         // si los fractales han ido hacia arriba, detenemos el ciclo
        }
     }

   for(int x=99; x>0; x--)                                                        // repetimos el ciclo para el fractal inferior
     {
      if(fractals_down[x]<10000)                                                  // comprobación de la presencia del fractal
        {
         if(price_low==0){price_low=fractals_down[x];}                            // primera comprobación
         if(price_low<fractals_down[x]){break;}                                   // si los fractales han ido hacia arriba, detenemos el ciclo
         else{price_low=fractals_down[x];}                                        // si los fractales van hacia abajo, copiamos
        }
     }

   double price_ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);                         // solicitud del precio de compra
   double price_bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);                         // solicitud del precio de venta

   if(price_high>price_ask && price_high>price_bid)                               // comprobamos si los precios ask y bid se encuentran entre el precio superior e inferior
      if(price_low<price_ask && price_low<price_bid)
        {
         price_up=price_high;                                                     // asignamos los valores para la respuesta
         price_down=price_low;
        }
  }
//+------------------------------------------------------------------+

Para asegurarse de la fiabilidad de la señal, antes de la respuesta se comprueba si el precio se encuentra dentro del rango encontrado. Se hace porque el último fractal, y probablemente el más importante, se forma tras la formación de dos últimas velas (según las reglas de formación del fractal).

Cálculo del precio de la apertura de posición

La función más importante se usa para calcular los niveles de DiNapoli. Dentro de ella, se traspasan los precios máximos y mínimos obtenidos antes, así como los datos sobre la dirección de la supuesta tendencia y el último valor de las MAs. Primero, todas las distancias obtenidas se convierten en puntos. Luego, desde ellos se calculan las secciones a base de los por cientos establecidos en los parámetros. Las secciones son fraccionadas por eso vamos a normalizarlas.

//+------------------------------------------------------------------+
//| Cálculo del precio de la apertura de posición                    |
//+------------------------------------------------------------------+
void Price_for_order(double high_price,
                     double low_price,
                     double &p_enter_min,
                     double &p_enter_max,
                     double &p_tp,
                     double &p_sl,
                     char trend,                                      // 1- arriba; 2 - abajo
                     double blue_line,
                     double red_line
                     )
  {
   double point_price=(high_price-low_price);
   double point_enter_min=point_price*percent_min_enter/100;
   double point_enter_max=point_price*percent_max_enter/100;
   double point_tp=point_price*percent_for_tp/100;
   double point_sl=point_price*percent_for_sl/100;
   double point_ma_line=MathAbs(blue_line-red_line)/2;

   point_enter_min=NormalizeDouble(point_enter_min,_Digits);
   point_enter_max=NormalizeDouble(point_enter_max,_Digits);
   point_ma_line=NormalizeDouble(point_ma_line,_Digits);

   point_tp=NormalizeDouble(point_tp,_Digits);
   point_sl=NormalizeDouble(point_sl,_Digits);

   if(trend==1)                                                       // arriba
     {
      p_enter_min=high_price-point_enter_min;
      double p_ma_min=red_line+point_ma_line;
      if(p_enter_min>p_ma_min)
        {p_enter_min=p_ma_min;}
      p_enter_max=high_price-point_enter_max;
      if(p_enter_max>p_enter_min)
        {p_enter_max=red_line;}

      p_tp=p_enter_min+point_tp;
      p_sl=high_price-point_sl;
     }

   if(trend==2)                                                       // abajo
     {
      p_enter_min=low_price+point_enter_min;
      double p_ma_min=red_line-point_ma_line;
      if(p_enter_min<p_ma_min)
        {p_enter_min=p_ma_min;}
      p_enter_max=low_price+point_enter_max;
      if(p_enter_max<p_enter_min)
        {p_enter_max=red_line;}

      p_tp=p_enter_min-point_tp;
      p_sl=low_price+point_sl;
     }
  }

Luego, dependiendo de la dirección de la tendencia, se calculan los precios, y la función devuelve la respuesta.

Modificación y cierre de la posición

Primero, obtenemos todos los datos de la última posición. Luego, dependiendo del tipo de la tendencia, se moderniza (pasa al breakeven) o se cierra si Stochastic da una señal opuesta.

//+------------------------------------------------------------------+
//| Modificación y cierre de la posición                             |
//+------------------------------------------------------------------+
void Position_mod(double ask,
                  double bid,
                  int point,
                  int profit,
                  char stochastic)
  {
   double price=trade.RequestPrice();
   double tp=trade.RequestTP();
   double sl=trade.RequestSL();
   double sl_point=point*_Point;
   double sl_profit=profit*_Point;
   double tp_point=(MathAbs(tp-price))/2;

   if(trade.RequestType()==ORDER_TYPE_BUY)              // orden de compra
     {
      if(sl<price && bid>(price+sl_point))
        {
         sl_profit=sl_profit+price;
         trade.PositionModify(_Symbol,sl_profit,tp);
        }
      if(stochastic==2)                                 // se espera el movimiento hacia abajo
        {
         trade.PositionClose(_Symbol,order_deviation);
        }
     }
   if(trade.RequestType()==ORDER_TYPE_SELL)             // orden de compra
     {
      if(sl>price && ask<(price-sl_point))
        {
         sl_profit=sl_profit-price;
         trade.PositionModify(_Symbol,sl_profit,tp);
        }
      if(stochastic==1)                                 // se espera el movimiento hacia arriba
        {
         trade.PositionClose(_Symbol,order_deviation);
        }

     }
  }

Función de consolidar

La última función combina todas las funciones consideradas más arriba. Primero, se declaran todas las variables concordantes. Luego, a través de las funciones de los indicadores, se obtienen los principales valores actuales de las «reglas superiores de la estrategia». Luego ocurre la división dependiendo de las respuestas obtenidas por las «reglas superiores». Se calcula el tamaño de la tendencia y los precios que son favorables para entrar en el mercado. Si las posiciones abiertas antes no se encuentran y el precio está en el rango calculado, la posición se abre.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double price_high=0;                                           // precio superior para el cálculo por los fractales
   double price_low=0;                                            // precio inferior para el cálculo por los fractales

   double price_enter_min=0;                                      // precio mínimo de la entrada
   double price_enter_max=0;                                      // precio máximo de la entrada
   double price_tp=0;                                             // nivel Take Profit
   double price_sl=0;                                             // nivel Stop Loss

   double price_ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);         // solicitud del precio de compra
   double price_bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);         // solicitud del precio de venta

   double ma_blue_line=0;                                         // valor de МА BLUE de período bajo
   double ma_red_line=0;                                          // valor de МА RED de período alto

   Stochastic(answer_stochastic);
   MA(answer_ma,ma_blue_line,ma_red_line,price_ask,price_bid);

   if(answer_stochastic==1)                                       // se espera el movimiento hacia arriba
     {
      if(answer_ma==1)                                            // nos encontramos en el rango del trading de compra 
        {
         Fractals(price_high,price_low);
         Price_for_order(price_high,price_low,price_enter_min,price_enter_max,price_tp,price_sl,1,ma_blue_line,ma_red_line);

         if(price_ask<price_enter_min && price_ask>price_enter_max)
           {
            if(PositionsTotal()==0)
              {
               trade.Buy(order_volume,_Symbol,price_ask,price_sl,price_tp,"Buy");
              }
           }
        }
     }

   if(answer_stochastic==2)                                        // nos encontramos en el rango de venta 
     {
      if(answer_ma==2)                                             // se espera el movimiento hacia abajo
        {
         Fractals(price_high,price_low);
         Price_for_order(price_high,price_low,price_enter_min,price_enter_max,price_tp,price_sl,2,ma_blue_line,ma_red_line);

         if(price_bid>price_enter_min && price_bid<price_enter_max)
            if(PositionsTotal()==0)
              {
               trade.Sell(order_volume,_Symbol,price_bid,price_sl,price_tp,"Sell");
              }
        }
     }

   if(PositionsTotal()!=0)
     {
      Position_mod(price_ask,price_bid,trailing_sl,trailing_profit,answer_stochastic);
     }

  }

Si las posiciónes abiertas ya existen, se llama a la función de modernizar/eliminar la posición. Aquí, el código se termina. Ya ha llegado el momento para probar el Asesor Experto.


Testeamos lo que ha salido.

La simulación del EA Dinapoli_v1.01 se realizaba en diferentes pares de divisas, en timeframe H4. Usamos el historial de 2017.01.01 a 2017.11.12.

Símbolo: EURUSD

Parámetros:

percent_min_enter=33.6 magic_number=65758473787389 stochastic_up_level=70
percent_max_enter=56 order_volume=0.01 stochastic_down_level=30
percent_for_tp=145 order_deviation=100 ma_red_period=25
percent_for_sl=100 stochastic_k=8 ma_red_shift=5
trailing_sl=675 stochastic_d=3 ma_blue_period=7
trailing_profit=40 stochastic_slowing=3 ma_blue_shift=5


Fig. 4. Resultados de la simulación en EURUSD H4 (2017.01.01 - 2017.11.12)

Fig. 4. Resultados de la simulación en EURUSD H4 (2017.01.01 - 2017.11.12)

Símbolo: GBPUSD

Parámetros:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=90
percent_max_enter=50 order_volume=0.01 stochastic_down_level=30
percent_for_tp=335 order_deviation=100 ma_red_period=15
percent_for_sl=63 stochastic_k=3 ma_red_shift=5
trailing_sl=425 stochastic_d=1 ma_blue_period=4
trailing_profit=20 stochastic_slowing=4 ma_blue_shift=5


Fig. 5. Resultados de la simulación en GBPUSD H4 (2017.01.01 - 2017.11.12)

Fig. 5. Resultados de la simulación en GBPUSD H4 (2017.01.01 - 2017.11.12)

Símbolo: NZDUSD

Parámetros:

percent_min_enter=31.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=88 order_volume=0.01 stochastic_down_level=30
percent_for_tp=45 order_deviation=100 ma_red_period=24
percent_for_sl=95 stochastic_k=10 ma_red_shift=5
trailing_sl=550 stochastic_d=2 ma_blue_period=4
trailing_profit=100 stochastic_slowing=1 ma_blue_shift=5


Fig. 6. Resultados de la simulación en NZDUSD H4 (2017.01.01 - 2017.11.12)

Fig. 6. Resultados de la simulación en NZDUSD H4 (2017.01.01 - 2017.11.12)

Símbolo: USDCAD

Parámetros:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=73 order_volume=0.01 stochastic_down_level=20
percent_for_tp=315 order_deviation=100 ma_red_period=25
percent_for_sl=69 stochastic_k=10 ma_red_shift=5
trailing_sl=325 stochastic_d=1 ma_blue_period=3
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5


Fig. 7. Resultados de la simulación en USDCAD H4 (2017.01.01 - 2017.11.12)

Fig. 7. Resultados de la simulación en USDCAD H4 (2017.01.01 - 2017.11.12)

Símbolo: USDCHF

Parámetros:

percent_min_enter=49.6 magic_number=65758473787389 stochastic_up_level=70
percent_max_enter=69 order_volume=0.01 stochastic_down_level=40
percent_for_tp=55 order_deviation=100 ma_red_period=20
percent_for_sl=98 stochastic_k=13 ma_red_shift=5
trailing_sl=900 stochastic_d=6 ma_blue_period=12
trailing_profit=40 stochastic_slowing=3 ma_blue_shift=5


Fig. 8. Resultados de la simulación en USDCHF H4 (2017.01.01 - 2017.11.12)

Fig. 8. Resultados de la simulación en GBPUSD H4 (2017.01.01 - 2017.11.12)

Símbolo: USDJPY

Parámetros:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=60
percent_max_enter=50 order_volume=0.01 stochastic_down_level=20
percent_for_tp=295 order_deviation=100 ma_red_period=22
percent_for_sl=53 stochastic_k=3 ma_red_shift=5
trailing_sl=750 stochastic_d=1 ma_blue_period=5
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5


Fig. 9. Resultados de la simulación en USDJPY H4 (2017.01.01 - 2017.11.12)

Fig. 9. Resultados de la simulación en GBPUSD H4 (2017.01.01 - 2017.11.12)

Símbolo: AUDUSD

Parámetros:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=80
percent_max_enter=81 order_volume=0.01 stochastic_down_level=40
percent_for_tp=305 order_deviation=100 ma_red_period=13
percent_for_sl=69 stochastic_k=3 ma_red_shift=5
trailing_sl=250 stochastic_d=4 ma_blue_period=1
trailing_profit=20 stochastic_slowing=4 ma_blue_shift=5


Fig. 10. Resultados de la simulación en AUDUSD H4 (2017.01.01 - 2017.11.12)

Fig. 10 Resultados de la simulación en AUDUSD H4 (2017.01.01 - 2017.11.12)

El análisis de los resultados obtenidos muestra cierta estabilidad en las entradas. En todos los pares, salvo USHCHF, se observa una recta casi horizontal..

La razón consiste en los siguiente: para reducir el drawdown del balance, la estrategia supone la colocación del Stop Loss cuanto más cerca posible. Pero así se amenta la exigencia a la calidad de las señales. Por tanto, cuanto más alta sea la calidad de las señales, menor será el número de las entradas en el mercado, pero la subida del precio del gráfico también se hace más estable (por ejemplo, en el par USDCHF). No obstante, en la práctica no planteamos conseguir el máximo beneficio. Tenemos que estar seguros de que el EA va a minimizar las pérdidas de manera estable en las situacioenes difíciles del mercado.

De esta manera, durante la optimización y simulación, hay que confiar en los resultados con un gran número de entradas, mostrados en un intervalo de tiempo prolongado.

Símbolo: XAUUSD

Después de probar el EA en todos los símbolos populares, sería bueno averiguar cómo se comportará en los mercados de bienes. Por eso, voy a testear el símbolo XAUUSD (futuros del oro para USD), y éste es el resultado:

Parámetros:

percent_min_enter=23.6 magic_number=65758473787389 stochastic_up_level=90
percent_max_enter=50 order_volume=0.2 stochastic_down_level=10
percent_for_tp=255 order_deviation=100 ma_red_period=23
percent_for_sl=80 stochastic_k=3 ma_red_shift=5
trailing_sl=750 stochastic_d=1 ma_blue_period=6
trailing_profit=10 stochastic_slowing=1 ma_blue_shift=5



Fig. 11. Resultados de la simulación en XAUUSD H4 (2017.01.01 - 2017.11.12)

Fig. 11 Resultados de la simulación en XAUUSD H4 (2017.01.01 - 2017.11.12)

El resultado para el oro es bastante interesante: el EA ha calculado las entradas con la precisión de 83,3% (transaccioenes rentables), y el beneficio ha llegado a 461%, con el drawdown de 40%. Eso quiere decir que el beneficio superaba el drawdown en casi 10 veces. Es un resultado bastante interesante, pero debido a un número de transacciones no muy grande (son sólo 18) no podemos hacer conclusiones serias a base de la prueba realizada.


Desventajas de la estrategia comercial

Este EA también tiene sus desventajas, igual como cualquier otro que hemos desarrollado.

Fig. 12. Trabajo del EA en la tendencia (NZDUSD H4)

Fig. 12 Trabajo del EA en la tendencia (NZDUSD H4)

En la imagen 12 podemos ver que el EA trabaja en un determinado canal. Todo parece bastante estable, pero hay una desventaja principal que salta a la vista: la salida prematura de las transacciones.

Fig. 13. Trabajo del EA en el flat (EURUSD H4)

Fig. 13 Trabajo del EA en el flat (EURUSD H4)

Otro «cuello de botella» es que al EA no le gusta trabajar en el flat. En la imagen 13, vemos que el beneficio no es muy grande con este tipo del movimiento, las entradas tampoco se calculan de manera muy correcta.

Tabla de resultado

SímboloTradesTrades rentables (%)Beneficio neto, $ Drawdown máximo en % del balanceBeneficio esperado, $PFRFSharpe
AUDUSD4116 (39.0%)49.9411.81.222.262.800.19
EURUSD5228 (53.8%)124.7917.72.402.234.010.28
GBPUSD4017 (42.5%)126.3919.03.164.845.020.24
NZDUSD13151 (38.9%)111.6311.90.852.255.290.26
USDCAD23145 (19.4%)85.7128.70.371.921.930.12
USDCHF1714 (82.3%)77.114.34.547.167.240.94
USDJPY21045 (21.4%)50.8852.30.241.350.960.07
XAUUSD1815 (83.3%)461.995.1
25.679.009.880.47

Aquí, se puede observar que los resultados no son uniformes, aunque se notan tendencias generales entre diferentes pares. Usando las mismas configuraciones, algunos pares traen beneficios (aunque son bastante moderados). Conclusión: para aumentar el beneficio, es necesario optimizar minuciosamente las configuraciones del EA para cada par de divisas. 

Conclusión

Nos convencimos otra vez más de que la «escuela vieja» de los traders había creado un podentísimo fundamento para mucho tiempo. La estrategia del comercio con los niveles de DiNapoli ha demostrado grandes perspectivas, y yo planeo mejorarla en el futuro. Hoy en día tiene sus inconvenientes: por ejemplo, el EA ha mostrado malos resultados en el flat. Además, el precio no siempre alcanza COP, y con más frecuencia las posiciones se cierran más efectivamente por el indicador Stochastic.

Las entradas bastante agresivas pueden ser atribuidas a las ventajas del EA, sobre todo eso se ve en la imagen 13. El EA actúa siguiendo estrictamente el algoritmo en las situaciones cuando el trader segurmente no abriría la posición manualmente. Pero al final, se alcanza el beneficio, además el drawdown no es muy grande.

Archivos adjuntos

# Nombre Tipo Descripción
1 Dinapoli_v1.01.mq5 Asesor Experto El EA que implementa la estrategia del uso de los niveles DiNapoli e indicadores auxiliares
2 AUDUSDH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en AUDUSD Н4
3 EURUSDH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en EURUSD H4
4 GBPUSDH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en GBPUSD H4
5 NZDUSDH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en NZDUSD H4
6 USDCADH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en USDCAD H4
7 USDCHFH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en USDCHF H4
8 USDJPYH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en USDJPY H4
9 XAUUSDH4.set Archivo de configuraciones del EA Ajustes utilizados durante la simulación y optimización en XAUUSD H4

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

Archivos adjuntos |
Dinapoli_v1.01.mq5 (29.64 KB)
AUDUSDH4.set (1.3 KB)
EURUSDH4.set (1.36 KB)
GBPUSDH4.set (1.3 KB)
NZDUSDH4.set (1.3 KB)
USDCADH4.set (1.3 KB)
USDCHFH4.set (1.3 KB)
USDJPYH4.set (1.3 KB)
XAUUSDH4.set (1.3 KB)
La estrategia comercial 'Momentum Pinball' La estrategia comercial 'Momentum Pinball'
En este artículo se continúa con el tema de la escritura de código para los sistemas comerciales descritos en el libro de Linda Raschke y Laurence Connors "Secretos bursátiles. Estrategias comerciales de alto rendiemiento a corto plazo". En esta ocasión, analizaremos el sistema 'Momentum Pinball', describiendo la creación de dos indicadores, un robot comercial y un bloque comercial para el sistema.
Selección automática de señales prometedoras Selección automática de señales prometedoras
Este artículo está dedicado al estudio de las señales comerciales para MetaTrader 5 con la ejecución automática en las cuentas de los suscriptores. Además, se considera el desarrollo de las herramientas para buscar las señales comerciales prometedoras directamente en el terminal.
Creamos una nueva estrategia comercial usando una tecnología de colocación de entradas a los indicadores Creamos una nueva estrategia comercial usando una tecnología de colocación de entradas a los indicadores
En el artículo se expone una tecnología con cuya ayuda cualquiera podrá crear su propia estrategia comercial combinando un conjunto individual de indicadores, y también desarrollar sus propias señales para entrar en el mercado.
El comercio nocturno en la sesión asiática: cómo mantener los beneficios El comercio nocturno en la sesión asiática: cómo mantener los beneficios
En el artículo se analizan el concepto de comercio nocturno, sus estrategias comerciales y su implementación en MQL5. Se han realizado varias simulaciones y se han sacado las conclusiones pertinentes.