English Русский 中文 Deutsch 日本語 Português
Construcción de líneas fractales

Construcción de líneas fractales

MetaTrader 4Ejemplos | 15 febrero 2016, 11:57
1 885 0
Shashev Sergei
Shashev Sergei

Introducción

Los fractales son utilizados prácticamente por todos los traders. No obstante, si se les pregunta a estos qué es un fractal, te responderán que es un indicador en el sistema Bill Williams. Los traders más avanzados dirán que es una serie de 5 barras en las que, si la barra de en medio High es superior a las demás barras de la serie, se trata de un fractal Up, y si la barra de en medio Low es inferior a las demás barras, se trata de un fractal Down. Como dice la frase, "Esto es todo lo que puedo decir de la guerra".

En el libro de Bill Williams llamado "Nuevas dimensiones del trading" hay una breve descripción de los fractales, especialmente de su naturaleza y su uso: Cómo sacar beneficios del caos en los valores, los bonos y las materias primas. También puede encontrarse algo en el artículo de Chekulaev llamado Fractales (en ruso). Las fórmulas matemáticas se describen bien en el libro de Shiryaev llamado "Fundamentos de matemáticas estocásticas" (en ruso).

Uso de los fractales

Hay dos tipos de penetración fractal: una sencilla es cuando el precio supera el nivel de fractal Up (cae bajo el nivel de fractal Down). En este caso, sería mejor esperar el precio de cierre y abrir una posición en la apertura de la siguiente barra.


Los fractales respectivos Buy y Sell están marcados con flechas en la figura anterior donde hemos considerado la penetración fractal simple. Una penetración compleja usa 2 fractales: el último y el penúltimo. Están unidos por una línea recta que se espera que sea penetrada por el precio de cierre.



Los puntos de entrada cuando la línea del fractal es penetrada están marcados por las flechas azul y roja. El entorno de desarrollo de MQL4 nos ayudará a conocer mejor el concepto de fractal.


Vamos a definir un problema para probar los fractales:

  • extraer fractales comprar/vender;
  • extraer niveles de penetración horizontal;
  • extraer líneas fractales;
  • marcar con flechas los puntos de entrada esperados.

Fractales comprar/vender

Esta es la parte más elemental. Debemos también tener en cuenta el indicador iFractal disponible en MQL4 (en Omega tuve que escribir este indicador yo mismo, y fue bastante difícil debido a las propiedades de Omega). Los ejemplos sobre cómo escribir este indicador pueden encontrarse en la Base de código.

Niveles horizontales de penetración

Vamos a usar las líneas horizontales estándar Especificaremos el precio de un fractal como coordenada del precio, la fecha de formación del fractal y el momento actual será dado como coordenadas temporales.

ObjectCreate("SimpleUp"+Up,OBJ_TREND,0,bufUpDate[Up],
             bufUpPrice[Up],Time[i-1],bufUpPrice[Up]);
ObjectSet("SimpleUp"+Up,OBJPROP_COLOR,Aqua);
ObjectSet("SimpleUp"+Up,OBJPROP_RAY,True);

Líneas fractales

La forma más sencilla parece ser trazar las líneas de tendencia a través de 2 puntos. Trazamos un rayo de la línea y esperamos la penetración. No obstante, de hecho, no parece ser posible comparar el precio de cierre y el valor del precio en la línea fractal ya que la función ObjectGet solo puede devolver valores de los puntos que han formado la línea fractal. Entonces, ¿qué debemos hacer?

Debemos recordar la geometría analítica. Tenemos 2 puntos, por lo que tenemos la ecuación de una línea recta. Y como sabemos la coordenada temporal, podemos obtener fácilmente el valor del precio a partir de la ecuación de la línea recta. La ecuación canónica de la línea recta es la siguiente:


Sustituiremos el precio y el tiempo por x e y. La realización correspondiente tiene lugar en la función LevelCalculate que calcula el nivel de penetración y, junto con este, define nuevas coordenadas de la línea fractal a establecer usando la función ObjectSet.

ObjectCreate("LineUp"+Up,OBJ_TREND,0,bufUpDate[Up],
             bufUpPrice[Up],bufUpDate[Up-1],bufUpPrice[Up-1]); 
ObjectSet("LineUp"+Up,OBJPROP_COLOR,Blue);
ObjectSet("LineUp"+Up,OBJPROP_RAY,False);

Colocación de flechas

Creamos todas las líneas necesarias en el bucle y luego las comparamos con los precios actuales. Si penetra una línea simple, ponemos una flecha amarilla. Si penetra una línea fractal, la flecha para Comprar será azul y para Vender será roja.

Todo esto tiene lugar como indicador FractalLines.mq4.

//+------------------------------------------------------------------+
//|                                                 FractalLines.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern int       lines=5;  //The amount of visible fractal lines
extern int       MaxFractals=10000; // :)
extern bool       ShowHorisontalLines=true;
extern bool       ShowFractalLines=true; 
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//--- my variables
double bufUpPrice[10000];  //price array of Up fractals
double bufUpDate[10000];   //date array of Up fractals
double bufDownPrice[10000];   //price array of Down fractals
double bufDownDate[10000]; //date array of Down fractals
int Up = 0; //counter of Up fractals
int Down = 0;  //counter of Down fractals
 
//The function calculates the price value of penetration of the fractal line by the simplest
//equations of analytic geometry
double LevelCalculate(double Price1, double Time1, double Price2, 
                     double Time2, double NewTime)
{
   double level;
   if (Time2!=Time1)// Just in case, to avoid zero divide.
   {
      level=(NewTime-Time1)*(Price2-Price1)/(Time2-Time1)+Price1;
   }
   else
   { 
      return(Price2);
   }
   return(level);
}
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,217);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexEmptyValue(0,0.0);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,218);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexEmptyValue(1,0.0);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//---- the last calculated bar will be recalculated   
   if(counted_bars > 0) 
       counted_bars--;
   int limit = Bars - counted_bars;
// We will rather place arrows at the moment of penetration of fractal lines, 
// estimate efficiency
 // The idea was borrowed from Rosh, hopefully he will not be offended by this :)    
  string arrowName; // here, we will give the arrow a unique name
  
  //The number of the penetrated fractal
  //Penetration of the fractal line
  int FractalUp = 0;
  int FractalDown = 0;
  //Simple penetration of a fractal
  int SimpleFractalUp = 0;
  int SimpleFractalDown = 0;
  
  double BuyFractalLevel = 0;  //penetration level of the Up fractal line
  double SellFractalLevel = 0; //penetration level of the Down fractal line
  double buf = 0; // buffer value of fractal being available; if it is 0, there is no fractal at all
 
//---- the main loop       
   for(int i = limit; i>0; i--)
   {   
   
       //Draw simple fractal levels
       
       //Define the current fractal levels 
 
         BuyFractalLevel=LevelCalculate(bufUpPrice[Up],bufUpDate[Up],
                   bufUpPrice[Up-1],bufUpDate[Up-1],Time[i]);
         //Move the second coordinate of the Up fractal line                              
         ObjectSet("LineUp"+Up,OBJPROP_TIME1,Time[i]);
         ObjectSet("LineUp"+Up,OBJPROP_PRICE1,BuyFractalLevel); 
         SellFractalLevel=LevelCalculate(bufDownPrice[Down],
                          bufDownDate[Down],bufDownPrice[Down-1],
                          bufDownDate[Down-1],Time[i]);
         //Move the second coordinate of the Down fractal line                               
         ObjectSet("LineDown"+Down,OBJPROP_TIME1,Time[i]);
         ObjectSet("LineDown"+Down,OBJPROP_PRICE1,SellFractalLevel);
         
      //Search for a simple penetration
         if (Close[i]>ObjectGet("SimpleUp"+Up,OBJPROP_PRICE1)&&
                          (Up>SimpleFractalUp))
         {
            arrowName="SimleUpArrow"+Up;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         Low[i-1]-Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,241);
            ObjectSet(arrowName,OBJPROP_COLOR,Yellow);
            SimpleFractalUp=Up;             
         }
         
         if (Close[i]<ObjectGet("SimpleDown"+Down,OBJPROP_PRICE1)&&
                          (Down>SimpleFractalDown))
         {
            arrowName="SimleUpArrow"+Down;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         High[i-1]+Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,242);
            ObjectSet(arrowName,OBJPROP_COLOR,Yellow);
            SimpleFractalDown=Down;             
         }                                                                                                                          
 
      //Search for a complex penetration
        if ((Close[i]>BuyFractalLevel)&&(Up>FractalUp)) 
         {
            //Put an up-arrow
            arrowName="UpArrow"+Up;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         Low[i-1]-Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,241);
            ObjectSet(arrowName,OBJPROP_COLOR,Blue);
            FractalUp=Up;        
         }
                                          
        if ((Close[i]<SellFractalLevel)&&(Down>FractalDown))
         {
            //Put a down-arrow
            arrowName="DownArrow"+Down;
            ObjectCreate(arrowName,OBJ_ARROW,0,Time[i-1],
                         High[i-1]+Point*10);
            ObjectSet(arrowName,OBJPROP_ARROWCODE,242);
            ObjectSet(arrowName,OBJPROP_COLOR,Red); 
            FractalDown=Down;       
         }
        //Draw the Up fractal itself
        ExtMapBuffer1[i] = iFractals(NULL, 0, MODE_UPPER, i);
        
        //If it is available, place it in the array of fractals
        buf = iFractals(NULL, 0, MODE_UPPER, i);
        if (buf!=0)
        {
            Up++;
            bufUpPrice[Up]=iFractals(NULL, 0, MODE_UPPER, i);
            bufUpDate[Up]=Time[i];
            //The current fractal penetration level - fractal itself
            BuyFractalLevel=bufUpPrice[Up];
            
            if (Up>1)
            
            {
               //Simple fractal
               ObjectCreate("SimpleUp"+Up,OBJ_TREND,0,bufUpDate[Up],
                   bufUpPrice[Up],Time[i-1],bufUpPrice[Up]);
      ObjectSet("SimpleUp"+Up,OBJPROP_COLOR,Aqua);
      ObjectSet("SimpleUp"+Up,OBJPROP_RAY,True);   
               //Draw fractal lines on 2 coordinates
               ObjectCreate("LineUp"+Up,OBJ_TREND,0,bufUpDate[Up],
                  bufUpPrice[Up],bufUpDate[Up-1],bufUpPrice[Up-1]); 
      ObjectSet("LineUp"+Up,OBJPROP_COLOR,Blue);
      ObjectSet("LineUp"+Up,OBJPROP_RAY,False);
               //Remove the outdated lines
               if (Up>lines+1)
               {
                  ObjectDelete("LineUp"+(Up-lines));
                  ObjectDelete("SimpleUp"+(Up-lines));                  
               }
            }     
        }
         //A similar block, but for Down fractals
        ExtMapBuffer2[i] = iFractals(NULL, 0, MODE_LOWER, i);
        buf = iFractals(NULL, 0, MODE_LOWER, i);    
        if (buf!=0)
        {
            Down++;
            bufDownPrice[Down]=iFractals(NULL, 0, MODE_LOWER, i);
            bufDownDate[Down]=Time[i];
            SellFractalLevel=bufDownPrice[Down];
                                         
            if (Down>1)
            
            {
               ObjectCreate("SimpleDown"+Down,OBJ_TREND,0,bufDownDate[Down],
                   bufDownPrice[Down],Time[i-1],bufDownPrice[Down]);        
               ObjectSet("SimpleDown"+Down,OBJPROP_COLOR,LightCoral);
               ObjectSet("SimpleDown"+Down,OBJPROP_RAY,True);
                                  
               ObjectCreate("LineDown"+Down,OBJ_TREND,0,
                            bufDownDate[Down],bufDownPrice[Down],
                            bufDownDate[Down-1],bufDownPrice[Down-1]);        
               ObjectSet("LineDown"+Down,OBJPROP_COLOR,Red);
               ObjectSet("LineDown"+Down,OBJPROP_RAY,False);
               if (Down>lines+1)
               {
                  ObjectDelete("LineDown"+(Down-lines));
                  ObjectDelete("SimpleDown"+(Down-lines));
               }            
            }
     
        }           
        if (!ShowHorisontalLines)
        {   
            ObjectDelete("SimpleDown"+Down);              
            ObjectDelete("SimpleUp"+Up);                
        }
        if (!ShowFractalLines)
        {
            ObjectDelete("LineDown"+Down);        
            ObjectDelete("LineUp"+Up);
        }          
     }   
//----
   return(0);
  }
//+----------------------------------------------------------------- 

Las líneas antiguas deben eliminarse, de lo contrario el gráfico parecerá una paleta. Hay un par de ajustes adicionales en el indicador, como la visibilidad de las líneas o sus cantidades. El resultado de las actividades del indicador se da en a continuación.




Esto viene como anillo al dedo para quienes les encantan los fractales.


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

Archivos adjuntos |
FractalLines.mq4 (9.4 KB)
Secretos del terminal de cliente de MetaTrader 4: Biblioteca de archivos en MetaEditor Secretos del terminal de cliente de MetaTrader 4: Biblioteca de archivos en MetaEditor
Cuando se crean programas personalizados, el editor de código es de gran importancia. Cuantas más funciones hay disponibles en el editor, más rápida y cómoda es la creación del programa. Muchos programas se crean sobre la base de un código ya existente. ¿Utiliza un indicador o un script que no se ajusta completamente a su propósito? Descargue el código de este programa de nuestro sitio web y personalícelo.
Estrategias de trading en Forex Estrategias de trading en Forex
Este artículo ayudará los traders principiantes a desarrollar tácticas de trading en Forex.
Archivo de registro alternativo con el uso de HTML y CSS Archivo de registro alternativo con el uso de HTML y CSS
En este artículo describiré el proceso de escritura de una sencilla pero muy potente biblioteca para la creación de archivos html, aprenderemos a ajustar su visualización y veremos cómo pueden implementarse y utilizarse fácilmente en nuestros expertos o en el script.
Representación gráfica de las pruebas: El trading manual Representación gráfica de las pruebas: El trading manual
Pruebas de estrategias manuales con el historial ¡Pruebe su algoritmo de trading sin ahondar en las complejidades de la programación!