Dibujando niveles de ruptura horizontales utilizando fractales

Victor Chebotariov | 12 noviembre, 2015

Fractales

Los fractales son uno de los cinco indicadores de la estrategia comercial de Bill Williams que permite encontrar un techo o un suelo en el mercado. Un fractal alcista es una serie de, por lo menos, cinco barras consecutivas, con dos barras con máximos inferiores situados directamente antes del máximo superior, y a continuación del mismo. La configuración opuesta (esto es, una serie de cinco barras con dos barras con mínimos superiores situados directamente antes del mínimo inferior, y después del mismo) se corresponde con un fractal bajista. Los fractales tienen los valores Alto y Bajo, y en este gráfico aparecen marcados con flechas.

Si analizamos el gráfico detenidamente, observaremos que cruzar el nivel del fractal normalmente significa continuar con el movimiento en la dirección del fractal. En un mercado alcista, este tipo de cruce sirve para mantener una posición larga; el nivel bajo del fractal es el nivel de soporte, de modo que sobrepasarlo será una señal de cierre de dicha posición larga. En las tendencias bajistas funciona igual, pero a la inversa. En un mercado plano esta estrategia no tiene ningún resultado.



Indicador de niveles fractales

Para determinar más fácilmente el nivel del último fractal alcista o bajista, podemos escribir un indicador sencillo que dibuje estos niveles con líneas horizontales. Crearemos el cuerpo principal del indicador con el "Asistente para MQL4/MQL5". Para ello tenemos que ejecutar la secuencia de comandos "Archivo -> Nuevo" o presionar el botón de la barra de herramientas. La pantalla mostrará el "Asistente para MQL4/MQL5".

Entonces la creación del cuerpo del programa habrá terminado, y tiene que ser como sigue:


//+------------------------------------------------------------------+
//|                                                 FractalsLine.mq4 |
//|                             Copyright © 2006, Victor Chebotariov |
//|                                      http://www.chebotariov.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Victor Chebotariov"
#property link      "http://www.chebotariov.com/"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- búferes
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizado            |
//+------------------------------------------------------------------+
int init()
  {
//---- indicadores
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,ExtMapBuffer2);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de desinicialización del indicador personalizado         |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de iteración del indicador personalizado                 |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----

   
//----
   return(0);
  }
//+------------------------------------------------------------------+

Solo falta añadir una pequeña pieza de código para que nuestro indicador esté listo.

Necesitamos:
1. El siguiente ciclo para calcular el valor del indicador en las barras del gráfico actual:

int i=Bars-counted_bars-1;
 
while(i>=0)
  {
   // Aquí calculamos el valor del indicador en cada barra (i)
   i--;
  }

2. Para obtener los valores de los fractales superiores e inferiores:

double upfrac_val=iFractals(NULL,0,MODE_UPPER,i+1);
double lofrac_val=iFractals(NULL,0,MODE_LOWER,i+1);

3. Lo más importante - debemos recurrir a las variables globales para memorizar el valor del último fractal:

if(upfrac_val>0)
  {
   GlobalVariableSet(Symbol()+Period()+"upfrac",upfrac_val);
  }
else if(lofrac_val>0)
  {
   GlobalVariableSet(Symbol()+Period()+"lofrac",lofrac_val);
  }


4. Leer los datos de las variables globales y pasarlos a nuestros índices:

ExtMapBuffer1[i] = GlobalVariableGet(Symbol()+Period()+"upfrac");
ExtMapBuffer2[i] = GlobalVariableGet(Symbol()+Period()+"lofrac");

El estado preparado de nuestro indicador tiene el aspecto siguiente:

//+------------------------------------------------------------------+
//|                                                 FractalsLine.mq4 |
//|                             Copyright © 2006, Victor Chebotariov |
//|                                      http://www.chebotariov.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Victor Chebotariov"
#property link      "http://www.chebotariov.com/"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- búferes
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizado            |
//+------------------------------------------------------------------+
int init()
  {
//---- indicadores
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,ExtMapBuffer2);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de desinicialización del indicador personalizado         |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de iteración del indicador personalizado                 |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----
   int i=Bars-counted_bars-1;
 
   while(i>=0)
     {
      double upfrac_val=iFractals(NULL,0,MODE_UPPER,i+1);
      double lofrac_val=iFractals(NULL,0,MODE_LOWER,i+1);
      if(upfrac_val>0)
        {
         GlobalVariableSet(Symbol()+Period()+"upfrac",upfrac_val);
        }
      else if(lofrac_val>0)
        {
         GlobalVariableSet(Symbol()+Period()+"lofrac",lofrac_val);
        }
      ExtMapBuffer1[i] = GlobalVariableGet(Symbol()+Period()+"upfrac");
      ExtMapBuffer2[i] = GlobalVariableGet(Symbol()+Period()+"lofrac");
      i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

Ahora hay que compilarlo, seleccionando "Archivo -> Compilar" o presionando el botón de la barra de herramientas.

El indicador recién creado puede adjuntarse al gráfico.



Aplicación práctica

En primera instancia, los niveles del fractal pueden ser útiles mientras el nivel StopLoss se mueve por debajo de la línea roja en un mercado alcista. El StopLoss debe mantenerse por encima de la línea azul en los mercados bajistas. Esta es una manera inteligente de garantizar la distancia de seguridad entre el StopLoss y el mercado.

Por ejemplo, supongamos que hemos entrado al mercado (véase la marca 1 del gráfico) con el stop de arriba de color azul (marca 2), si se atraviesa la línea roja (marca 3) movemos el StopLoss (marca 4); de igual modo, si ocurre una nueva ruptura (marca 5), movemos el StopLoss (marca 6). Si se cruza la línea azul (marca 7), cerramos la posición.

Para poder utilizar FractalsLine como mecanismo de trailing stop, primero tenemos que añadir dos pequeños fragmentos de código a nuestro Asesor Experto:

Obteniendo los datos del indicador FractalsLine:

double FLU = iCustom(NULL,0,"FractalsLine",0,0); // Línea fractal azul
double FLL = iCustom(NULL,0,"FractalsLine",1,0); // Línea fractal roja

Trailing-stop basado en el indicador FractalsLine:
if(Close[0]>FLU) // Trailing-stop para posiciones largas
  {
   if(OrderStopLoss()<FLL-3*Point || OrderStopLoss()==0)
     {
      OrderModify(OrderTicket(),OrderOpenPrice(),FLL-3*Point,OrderTakeProfit(),0,Green);
      return(0);
     }
  }


if(Close[0]<FLL) // Trailing-stop para posiciones cortas
  {
   if(OrderStopLoss()>FLL+(Ask-Bid+3)*Point || OrderStopLoss()==0)
     {
      OrderModify(OrderTicket(),OrderOpenPrice(),FLL+(Ask-Bid+3)*Point,OrderTakeProfit(),0,Red);
      return(0);
     }
  }


La implementación del trailing-stop basado en el indicador FractalsLine dio resultados positivos en el asesor experto MACD Sample. Esto se puede observar en los tests comparativos.


Pruebas de Standard MACD Sample

Símbolo EURUSD (Euro vs Dólar americano)
Período 1 hora (H1) 2008.01.02 12:00 - 2008.06.30 23:00 (2008.01.01 - 2008.07.01)
Modelo Cada tick (el método más preciso basado en todos los períodos menores disponibles para generar cada tick)
Parámetros TakeProfit=50; Lots=0.1; TrailingStop=30; MACDOpenLevel=3; MACDCloseLevel=2; MATrendPeriod=26;
Barras en la prueba 4059 Ticks modelados 1224016 Calidad del modelado 90.00%
Errores de gráficos mal agrupados 1
Depósito inicial 10000.00
Beneficio neto total 182.00 Beneficio bruto 1339.00 Pérdida bruta -1157.00
Factor de beneficio 1.16 Rentabilidad esperada 3.79
Disminución absoluta 697.00 Disminución máxima 827.00 (8.16%) Disminución relativa 8.16% (827.00)
Total de operaciones 48 Posiciones cortas (ganado %) 28 (82.14%) Posiciones largas (ganado %) 20 (85.00%)
Operaciones de beneficios (% del total) 40 (83.33%) Operaciones de pérdidas (% del total) 8 (16.67%)
Mayor Operaciones de beneficios 50.00 Operaciones de pérdidas -492.00
Media Operaciones de beneficios 33.48 Operaciones de pérdidas -144.63
Máximo ganancias consecutivas (beneficios en dinero) 14 (546.00) pérdidas consecutivas (pérdidas en dinero) 3 (-350.00)
Máximo beneficios consecutivos (número de ganancias) 546.00 (14) pérdidas consecutivas (número de pérdidas) -492.00 (1)
Media ganancias consecutivas 7 pérdidas consecutivas 1



Pruebas de MACD Sample con Trailing-stop basado en el indicador FractalsLine

Símbolo EURUSD (Euro vs Dólar americano)
Período 1 hora (H1) 2008.01.02 12:00 - 2008.06.30 23:00 (2008.01.01 - 2008.07.01)
Modelo Cada tick (el método más preciso basado en todos los períodos menores disponibles para generar cada tick)
Barras en la prueba 4059 Ticks modelados 1224016 Calidad del modelado 90.00%
Errores de gráficos mal agrupados 1
Depósito inicial 10000.00
Beneficio neto total 334.00 Beneficio bruto 1211.00 Pérdida bruta -877.00
Factor de beneficio 1.38 Rentabilidad esperada 5.14
Disminución absoluta 211.00 Disminución máxima 277.00 (2.75%) Disminución relativa 2.75% (277.00)
Total de operaciones 65 Posiciones cortas (ganado %) 41 (41.46%) Posiciones largas (ganado %) 24 (62.50%)
Operaciones de beneficios (% del total) 32 (49.23%) Operaciones de pérdidas (% del total) 33 (50.77%)
Mayor Operaciones de beneficios 50.00 Operaciones de pérdidas -102.00
Media Operaciones de beneficios 37.84 Operaciones de pérdidas -26.58
Máximo ganancias consecutivas (beneficios en dinero) 3 (150.00) pérdidas consecutivas (pérdidas en dinero) 4 (-168.00)
Máximo beneficios consecutivos (número de ganancias) 150.00 (3) pérdidas consecutivas (número de pérdidas) -168.00 (4)
Media ganancias consecutivas 2 pérdidas consecutivas 2



Conclusión

Las pruebas llevadas a cabo muestran que la rentabilidad aumenta y que las pérdidas disminuyen utilizando FractalsLine.