Conversion MQL4 – Jurik CFB

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #157870 quote
    Bruno Carnazzi
    Participant
    Senior

    Bonjour,

    J’ai trouvé le code MQL4 suivant, correspondant à l’indicateur Composite Fractal Behavior de Mark Jurik.

    Est-il possible de le convertir en langage Probuilder (le code a l’air complexe) ?

    Voici le code :

    //+------------------------------------------------------------------+
    //|                                                          cfb.mq4 |
    //|                                                           mladen |
    //+------------------------------------------------------------------+
    #property copyright "mladen"
    #property link      "mladenfx@gmail.com"
    
    #property indicator_separate_window
    #property indicator_buffers 1
    #property indicator_color1  Red
    #property indicator_minimum 0
    
    //
    //
    //
    //
    //
    
    extern string _                  = "Parameters";
    extern int    Depth              = 3;
    extern int    Price              = PRICE_WEIGHTED;
    extern int    BarsToCount        = 1000;
    extern int    Smooth             = 8;
    extern int    SmoothResultPeriod = 5;
    extern double SmoothSpeed        = 3.0;
    extern bool   SmoothAdaptive     = true;
    
    //
    //
    //
    //
    //
    
    double buffer1[];
    double storec[][5];
    double stored[][35];
    string IndicatorFileName;
    bool   CalculatingCFB=false;
    int    Depths[] = {2,3,4,6,8,12,16,24,32,48,64,96,128,192};
    
    
    
    
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    //
    //
    //
    //
    //
    
    int init()
    {
       SetIndexBuffer(0,buffer1);
    
       //
       //
       //
       //
       //
       
          CalculatingCFB = (_=="CalculateCFB");
          if (!CalculatingCFB)
          {
             Depth              = MathMax(MathMin(Depth,7),1)+7;
             SmoothResultPeriod = MathMax(SmoothResultPeriod,1);
             SmoothSpeed        = MathMax(SmoothSpeed,-1.5);
                                  SetIndexDrawBegin(0,Depths[Depth-1]);
          }
             
       //
       //
       //
       //
       //
                   
       IndicatorFileName = WindowExpertName();
       IndicatorShortName("cfb ("+(Depth-7)+")");
       return(0);
    }
    int deinit() { return(0); }
    
    
    
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    //
    //
    //
    //
    //
    
    int start()
    {
       double avg;
       int counted_bars=IndicatorCounted();
       int i,k,r,limit;
       
    
       if(counted_bars < 0) return(-1);
       if(counted_bars > 0) counted_bars--;
               limit = Bars-counted_bars;
               if (BarsToCount>100)
                      limit = MathMin(limit,BarsToCount+192);
    
       //
       //
       //
       //
       //
       
          if (CalculatingCFB)
          {
             if (ArrayRange(storec,0) != Bars) ArrayResize(storec,Bars);
                for(i=limit, r=Bars-i-1; i>=0; i--, r++) buffer1[i] = calculateCFB(i,r,Depth);
             return(0);
          }
          if (ArrayRange(stored,0) != Bars) ArrayResize(stored,Bars);
    
       //
       //
       //
       //
       //
    
       if (BarsToCount>100) SetIndexDrawBegin(0,Bars-BarsToCount);
       for(i=limit, r=Bars-i-1; i>=0; i--, r++)
       {
          double suma     = 0;
          double sumb     = 0;
          double cfb      = 0;
          double evenCoef = 1;
          double oddCoef  = 1;
             
          //
          //
          //
          //
          //
             
             for (k=Depth-1; k>=0; k--)
             {
                stored[r][k]    = iCustom(NULL,0,IndicatorFileName,"CalculateCFB",Depths[k],Price,BarsToCount,0,i);
                stored[r][k+14] = stored[r-1][k+14] + (stored[r][k]-stored[r-Smooth][k])/Smooth;
    
                   if ((k%2)==0)
                         { avg = oddCoef  * stored[r][k+14]; oddCoef  = oddCoef  * (1 - avg); }
                   else  { avg = evenCoef * stored[r][k+14]; evenCoef = evenCoef * (1 - avg); }
                   
                suma += avg*avg*Depths[k];
                sumb += avg;
             }
    
          //
          //
          //
          //
          //
    
          if (sumb != 0) cfb = suma/sumb;
          if (SmoothResultPeriod>1)
                buffer1[i] = iAverage(cfb,SmoothResultPeriod,SmoothSpeed,SmoothAdaptive,r,28);
          else  buffer1[i] = cfb;
       }
    
       //
       //
       //
       //
       //
          
       return(0);
    }
    
    
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    //
    //
    //
    //
    //
    
    #define _prices 0
    #define _roc    1
    #define _value1 2
    #define _value2 3
    #define _value3 4
    
    //
    //
    //
    //
    
    double calculateCFB(int i, int r, int depth)
    {
       storec[r][_prices] = iMA(NULL,0,1,0,MODE_SMA,Price,i);
    
       //
       //
       //
       //
       //
    
          storec[r][_roc]    = MathAbs(storec[r][_prices] - storec[r-1][_prices]);
          storec[r][_value1] = storec[r-1][_value1] - storec[r-depth][_roc] + storec[r][_roc];
          storec[r][_value2] = storec[r-1][_value2] - storec[r-1][_value1] + storec[r][_roc]*depth;
          storec[r][_value3] = storec[r-1][_value3] - storec[r-1-depth][_prices] + storec[r-1][_prices];
       
          double dividend = MathAbs(depth*storec[r][_prices]-storec[r][_value3]);
    
          //
          //
          //
          //
          //
             
       if (storec[r][_value2] != 0)
             return( dividend / storec[r][_value2]);
       else  return(0.00);            
    }
    
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    //
    //
    //
    //
    //
    
    #define E1  0
    #define E2  1
    #define E3  2
    #define E4  3
    #define E5  4
    #define E6  5
    #define res 6
    
    //
    //
    //
    //
    //
    
    double iAverage(double price, double averagePeriod, double const, bool adaptive, int r, int s)
    {
       double e1=stored[r-1][E1+s];  double e2=stored[r-1][E2+s];
       double e3=stored[r-1][E3+s];  double e4=stored[r-1][E4+s];
       double e5=stored[r-1][E5+s];  double e6=stored[r-1][E6+s];
    
       //
       //
       //
       //
       //
    
          if (adaptive && (averagePeriod > 1))
          {
             double minPeriod = averagePeriod/2.0;
             double maxPeriod = minPeriod*5.0;
             int    endPeriod = MathCeil(maxPeriod);
             double signal    = MathAbs((price-stored[r-endPeriod][res+s]));
             double noise     = 0.00000000001;
    
                for(int k=1; k<endPeriod; k++) noise=noise+MathAbs(price-stored[r-k][res+s]);
    
             averagePeriod = ((signal/noise)*(maxPeriod-minPeriod))+minPeriod;
          }
          
          //
          //
          //
          //
          //
          
          double alpha = (2.0+const)/(1.0+const+averagePeriod);
    
          e1 = e1 + alpha*(price-e1); e2 = e2 + alpha*(e1-e2); double v1 = 1.5 * e1 - 0.5 * e2;
          e3 = e3 + alpha*(v1   -e3); e4 = e4 + alpha*(e3-e4); double v2 = 1.5 * e3 - 0.5 * e4;
          e5 = e5 + alpha*(v2   -e5); e6 = e6 + alpha*(e5-e6); double v3 = 1.5 * e5 - 0.5 * e6;
    
       //
       //
       //
       //
       //
    
       stored[r][E1+s]  = e1;  stored[r][E2+s] = e2;
       stored[r][E3+s]  = e3;  stored[r][E4+s] = e4;
       stored[r][E5+s]  = e5;  stored[r][E6+s] = e6;
       stored[r][res+s] = price;
       return(v3);
    }

    Merci

    #157876 quote
    Nicolas
    Keymaster
    Master

    Description de l’indicateur et images svp.

    Merci de renseigner votre pays dans votre page de profile également.

    Pour une demande de conversion, merci d’utiliser ce formulaire la prochaine fois : https://www.prorealcode.com/free-code-conversion/ (disponible dans le menu Help du site).

    #157905 quote
    Bruno Carnazzi
    Participant
    Senior

    Bonjour Nicolas,

    C’est noté, c’est ma première utilisation de ce forum, merci pour votre indulgence.

     

    Alors une petite traduction de la présentation anglaise de l’indicateur :

    “Certaines tendances du marché sont le résultat de cycles sous-jacents, d’autres non. Utiliser des indicateurs dont les formules supposent toujours l’existence de ces cycles, c’est comme patiner sur de la glace fine : une catastrophe en attente de se produire.

    Par exemple, une approche populaire pour ajuster dynamiquement la vitesse (longueur) des indicateurs techniques classiques, comme une moyenne mobile, consiste à lier la vitesse à la longueur de cycle dominante du marché (DCL). De cette façon, si la longueur du cycle est longue, la vitesse de la moyenne mobile est automatiquement ralentie. Malheureusement, l’approche DCL pour ajuster la longueur de l’indicateur est problématique lorsque le marché n’a pas de véritable cycle dominant. Pendant ces périodes, la DCL estime la longueur des “cycles fantômes”, produisant des valeurs sans signification qui peuvent sérieusement dégrader la performance d’un système commercial.

    Pour éviter ce problème, nous avons conçu un indicateur qui ne présuppose pas la présence de cycles de marché. Jurik Reseach a découvert, dès 1996, comment les fractales pouvaient facilement évaluer la durée de la tendance du marché. Le nouvel indicateur, appelé CFB (Composite Fractal Behavior), fonctionne bien, que la série chronologique des prix comporte ou non des composantes cycliques.

    Le graphique ci-dessous montre l’indice CFB sous les barres de prix. Plus la durée de la tendance augmente, plus l’indice est important. Lorsque la tendance s’arrête, l’indice diminue. Le CFB peut mesurer la durée de la tendance jusqu’à 192 barres.”

     

    Un gif animé est joint en guise d’illustration.

    L’idée de cet indicateur, si j’ai bien compris, c’est de calculer automatiquement le paramètre “période” propre à de nombreux indicateurs.

    On peut s’en servir comme tel, ce qui n’est pas mon intention, ou bien simplement, en tant que confirmation de la tendance sur accroissement de la valeur et essouflement sur sa réduction.

    Merci,

    cfb_show.gif cfb_show.gif
    #157938 quote
    Nicolas
    Keymaster
    Master

    Merci je vais y regarder dés que possible.

    #159266 quote
    Bruno Carnazzi
    Participant
    Senior

    Bonjour Nicolas,

    Hum, j’ai l’impression qu’il n’y a pas de support des tableaux à dimensions multiples dans PRT v11. Du coup, à moins de complètement refactoriser le code, ça me semble compromis non ?

    #159316 quote
    Bruno Carnazzi
    Participant
    Senior

    Il faudrait bien rentrer dans le détail du code, mais je dirai qu’à longueur de ligne fixe (et uniquement dans ce cas), un accès par double indice d’un tableau à deux dimensions se linéarise facilement.

    Expression en pseudo-code :

    array[i][j] = arrray[i+j]

    Ne fonctionne que pour des longueurs de ligne fixe

    #159453 quote
    Nicolas
    Keymaster
    Master

    ça n’est souvent pas utile dans le cas de ce type de code (du même auteur), la multi dimension n’est pas indispensable puisque sous ProBuilder on va tracer l’indicateur en lisant l’historique, puis en temps réel, contrairement à ce qui se fait sous MT4 très souvent, c’est à dire faire une boucle sur tout l’historique en temps réel (à chaque tick) et c’est ce à quoi sert la première dimension ici, contenir le numéro de la bougie.

    #159458 quote
    Nicolas
    Keymaster
    Master

    en effet, après m’être plongé dans le code, sans une deuxième dimension, ça sera vraiment très complexe et hasardeux, elle est donc réellement utile ici ! Notamment à cause de la fonction “calculateCFB(int i, int r, int depth)”, désolé mais j’y passerai beaucoup trop de temps sans être certain d’obtenir un résultat satisfaisant 🙁

    #159499 quote
    Bruno Carnazzi
    Participant
    Senior

    Je comprends, pas de soucis Nicolas.

    Merci

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.

Conversion MQL4 – Jurik CFB


ProBuilder : Indicateurs & Outils Personnalisés

New Reply
Author
Summary

This topic contains 8 replies,
has 2 voices, and was last updated by Bruno Carnazzi
5 years, 1 month ago.

Topic Details
Forum: ProBuilder : Indicateurs & Outils Personnalisés
Language: French
Started: 01/14/2021
Status: Active
Attachments: 1 files
Logo Logo
Loading...