Bonjour à tous,
J’utilise sur MT4 un indicateur que je trouve très pertinent et que j’aurais aimé convertir sur ProRealtime. Malheureusement, je n’ai pas un niveau suffisant en programmation pour cela.
Il s’agit de l’indicateur Fractal_Bands mis au point par Jean-Philippe Poton, que l’on trouve ici :
https://www.mql5.com/en/code/download/8895/fractal_bands.mq4
Une explication théorique avec la formule mathématique est disponible sur son blog, avec l’intérêt que présentent ces bandes en comparaison des bandes de Bollinger :
http://fractalfinance.blogspot.fr/2009/05/from-bollinger-to-fractal-bands.html
Merci d’avance à ceux qui pourront aider.
le code complet de l’indicateur MQ4 est le suivant :
//+——————————————————————+
//| Fractal_Bands.mq4 |
//| Copyright © 2008, jppoton@yahoo.com |
//| http://fractalfinance.blogspot.com/ |
//+——————————————————————+
#property copyright “Copyright © 2008, jppoton@yahoo.com”
#property link “http://fractalfinance.blogspot.com/”
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_width1 2
#property indicator_color2 Red
#property indicator_width2 1
#property indicator_color3 Red
#property indicator_width3 1
//************************************************************
// Input parameters
//************************************************************
extern int e_period =30;
extern int normal_speed =30;
extern double alpha =2.0;
extern int shift =0;
extern int e_type_data =PRICE_CLOSE;
//************************************************************
// Constant
//************************************************************
string INDICATOR_NAME=”Fractals Bands”;
string FILENAME =”Fractal_bands.mq4″;
double LOG_2;
//************************************************************
// Private vars
//************************************************************
double ExtOutputBuffer[];
double UpperBuffer[];
double LowerBuffer[];
int g_period_minus_1;
//+———————————————————————–+
//| FUNCTION : init |
//| Initialization function |
//| Check the user input parameters and convert them in appropriate types.|
//+———————————————————————–+
int init()
{
// Check e_period input parameter
if(e_period < 2 )
{
Alert( “[ 10-ERROR ” + FILENAME + ” ] input parameter \”e_period\” must be >= 1 (” + e_period + “)” );
return( -1 );
}
if(e_type_data < PRICE_CLOSE || e_type_data > PRICE_WEIGHTED )
{
Alert( “[ 20-ERROR ” + FILENAME + ” ] input parameter \”e_type_data\” unknown (” + e_type_data + “)” );
return( -1 );
}
IndicatorBuffers(3);
SetIndexBuffer(0,ExtOutputBuffer);
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
SetIndexBuffer(1,UpperBuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(2,LowerBuffer);
SetIndexStyle(2,DRAW_LINE);
SetIndexDrawBegin(0,2*e_period);
SetIndexDrawBegin(1,2*e_period);
SetIndexDrawBegin(2,2*e_period);
g_period_minus_1=e_period – 1;
LOG_2=MathLog( 2.0 );
//—-
return( 0 );
}
//+——————————————————————+
//| FUNCTION : deinit |
//| Custor indicator deinitialization function |
//+——————————————————————+
int deinit()
{
return(0);
}
//+——————————————————————+
//| FUNCTION : start |
//| This callback is fired by metatrader for each tick |
//+——————————————————————+
int start()
{
int counted_bars=IndicatorCounted();
if(counted_bars < 0) return(-1);
if(counted_bars>0) counted_bars–;
int limit=Bars-counted_bars;
if(counted_bars==0) limit-=1+MathMax(e_period,g_period_minus_1);
_computeLastNbBars(limit);
//—-
return( 0 );
}
//+================================================================================================================+
//+=== FUNCTION : _computeLastNbBars ===+
//+=== ===+
//+=== ===+
//+=== This callback is fired by metatrader for each tick ===+
//+=== ===+
//+=== In : ===+
//+=== – lastBars : these “n” last bars must be repainted ===+
//+=== ===+
//+================================================================================================================+
//+——————————————————————+
//| FUNCTION : _computeLastNbBars |
//| This callback is fired by metatrader for each tick |
//| In : – lastBars : these “n” last bars must be repainted |
//+——————————————————————+
double tmpArray[];
void _computeLastNbBars( int lastBars )
{
switch( e_type_data )
{
case PRICE_CLOSE : ArrayCopy(tmpArray,Close,0,0,WHOLE_ARRAY); FRACTAL_BANDS(lastBars, tmpArray); break;
case PRICE_OPEN : ArrayCopy(tmpArray,Open,0,0,WHOLE_ARRAY); FRACTAL_BANDS(lastBars, tmpArray); break;
case PRICE_HIGH : ArrayCopy(tmpArray,High,0,0,WHOLE_ARRAY); FRACTAL_BANDS(lastBars, tmpArray); break;
case PRICE_LOW : ArrayCopy(tmpArray,Low,0,0,WHOLE_ARRAY); FRACTAL_BANDS(lastBars, tmpArray); break;
default :
Alert( “[ 20-ERROR ” + FILENAME + ” ] the imput parameter e_type_data <” + e_type_data + “> is unknown” );
}
}
//+——————————————————————+
//| FUNCTION : FRACTAL_BANDS |
//| Compute the Fractal Bands for input data |
//| In : |
//| – lastBars : these “n” last bars are considered for |
//| calculating the fractal dimension |
//| – inputData : data array on which the computation is applied |
//| For further theoretical explanations, see my blog: |
//| http://fractalfinance.blogspot.com/ |
//+——————————————————————+
void FRACTAL_BANDS( int lastBars, double &inputData[] )
{
int pos, iteration;
double diff, priorDiff;
double length;
double priceMax, priceMin;
double fdi,trail_dim,beta,sum,newres,deviation,frasma,hurst;
int speed,k;
//—-
for( pos=lastBars; pos>=0; pos– )
{
priceMax=_highest( e_period, pos, inputData );
priceMin=_lowest( e_period, pos, inputData );
length =0.0;
priorDiff=0.0;
//—-
for( iteration=0; iteration <= g_period_minus_1; iteration++ )
{
if(( priceMax – priceMin)> 0.0 )
{
diff =(inputData[pos + iteration] – priceMin )/( priceMax – priceMin );
if(iteration > 0 )
{
length+=MathSqrt( MathPow( diff – priorDiff, 2.0)+(1.0/MathPow( e_period, 2.0)) );
}
priorDiff=diff;
}
}
if(length > 0.0 )
{
fdi=1.0 +(MathLog( length)+ LOG_2 )/MathLog( 2 * g_period_minus_1 );
}
else
{
/*
** The FDI algorithm suggests in this case a zero value.
** I prefer to use the previous FDI value.
*/
fdi=0.0;
}
hurst=2-fdi; // The Hurst exponent
trail_dim=1/hurst; // This is the trail dimension, the inverse of the Hurst-Holder exponent
beta=trail_dim/2;
speed=MathRound(normal_speed*beta);
ExtOutputBuffer[pos-shift]=iMA(NULL,0,speed,0,0,0,pos); // Buffer of the FRASMA
sum=0.0;
k=pos+g_period_minus_1;
frasma=ExtOutputBuffer[pos-shift];
while(k>=pos)
{
newres=Close[k]-frasma;
sum+=newres*newres;
k–;
}
deviation=2*MathSqrt(sum/e_period); // 2 standard deviations around the frasma
UpperBuffer[pos-shift]=frasma+deviation*MathPow(alpha,hurst);
LowerBuffer[pos-shift]=frasma-deviation*MathPow(alpha,hurst);
}
}
//+——————————————————————+
//| FUNCTION : _highest |
//| Search for the highest value in an array data |
//| In : |
//| – n : find the highest on these n data |
//| – pos : begin to search for from this index |
//| – inputData : data array on which the searching for is done |
//| |
//| Return : the highest value | |
//+——————————————————————+
double _highest( int n, int pos, double &inputData[] )
{
int length=pos + n;
double highest=0.0;
//—-
for( int i=pos; i < length; i++ )
{
if(inputData[i] > highest)highest=inputData[i];
}
return( highest );
}
//+——————————————————————+
//| FUNCTION : _lowest | ===+
//| Search for the lowest value in an array data |
//| In : |
//| – n : find the hihest on these n data |
//| – pos : begin to search for from this index |
//| – inputData : data array on which the searching for is done |
//| |
//| Return : the highest value |
//+——————————————————————+
double _lowest( int n, int pos, double &inputData[] )
{
int length=pos + n;
double lowest=9999999999.0;
//—-
for( int i=pos; i < length; i++ )
{
if(inputData[i] < lowest)lowest=inputData[i];
}
return( lowest );
}
//+——————————————————————+