Indicateurs: Fourier extrapolation of price - page 4

 

Indicateur intéressant. J'aime bien l'aspect mathématique de l'utilisation d'un modèle de projection sur les graphiques. Je n'ai pas encore trop d'expérience avec le code, donc je me demande comment on pourrait paramétrer le modèle pour qu'il "revienne en arrière" et fasse la courbe de prédiction qu'il aurait faite un certain nombre de ticks plus tôt (disons 100). De cette façon, il pourrait être appliqué à différents graphiques et donner une idée de l'écart entre la réalité et le modèle, et peut-être l'utiliser pour identifier certaines caractéristiques d'un marché où le modèle fonctionne bien, etc.

 
Saidar:
Oui, j'utilise Windows 7, je vais jeter un coup d'œil.

il est possible que vous vouliez exécuter mt5 en mode portable :

terminal.exe /portable

vous obtiendrez un indicateur fonctionnant dans le répertoire actuel de mt5 - utile pour l'installation d'un pendrive

 

pour qu'il se décale vers l'arrière à temps pour tester sa capacité de prédiction :

à la ligne 32, insérer :
input int TimeShift = 10 ; // combien de barres se décalent en arrière, utile pour évaluer la prédictibilité de l'indicateur

à la ligne 54 replace :
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut) ;
avec :
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut - TimeShift) ;

à la ligne 55 insérer :
PlotIndexSetInteger(1, PLOT_SHIFT, -TimeShift) ;

à la ligne 87 replace :
if(CopyRates(NULL, 0, 0, Npast, rates) <= 0) return(0) ;
avec :
if(CopyRates(NULL, 0, TimeShift, Npast, rates) <= 0) return(0) ;

 

Cela vaut la peine d'y jeter un coup d'œil.

Qui l'utilise en bourse ?

Je l'ai passé à travers l'historique - il s'est avéré que l'indicateur ne prend pas du tout en compte la tendance, il a prédit contre la tendance pour plusieurs milliers de points à cinq chiffres, à mon avis il devrait être utilisé avec un indicateur comme MA/CCI/Bandes de Bollinger, où l'extrapolateur confirmera le signal, sinon il peut s'avérer être un drain.

Il est censé être mieux utilisé sur les échelles de temps supérieures, sur D1 il a prédit avec une précision étonnante pendant un mois, mais quand la tendance a commencé, j'ai été très déçu (voir le dernier paragraphe).

 

Merci de votre attention

 
lazarev-d-m:

Il vaut la peine de s'y intéresser.

Qui l'utilise dans le commerce ?


Je suis également très curieux de savoir si quelqu'un utilise des extrapolateurs dans ses TS, comment exactement ? Et dans quelle mesure cette direction de la recherche du Graal est-elle prometteuse ?

D'un point de vue purement intuitif, il semble que ce soit ce qu'il faut, mais les tests et les prédictions de cet extrapolateur ne correspondent pas du tout à la réalité, du moins en ce qui me concerne...

Pourriez-vous me dire quel est le choix des extrapolateurs et lequel d'entre eux est le plus précis ? Je veux dire qu'il n'y a probablement pas que les séries de Fourier qui peuvent être décomposées, les possibilités sont infinies. Par exemple, vous pouvez partir des méthodes les plus simples et commencer à partir du croisement de MA ou MACD et ainsi prédire la courbe, et si vous n'êtes pas paresseux, alors différentes décompositions empiriques, puis le calcul de la moyenne et encore une fois le copponing.... Je peux théoriquement imaginer comment le faire, mais si je commence à essayer de le coder, je ne serai pas capable de le faire en un an((((

Il serait intéressant que l'extrapolateur définisse la distribution de probabilité pour le futur proche, au lieu de tracer une ligne.

 
Alex_Bondar:


Il serait intéressant que l'extrapolateur définisse la distribution de probabilité pour le futur proche, au lieu de tracer une ligne.


Je pense que cela pourrait être le cas, si l'on s'entraîne avec photoshop)))))

 
Au début, il semblait bien prévoir, mais récemment il a commencé à donner une ligne droite, bien que sur les anciens terminaux, que je n'ai pas utilisés depuis longtemps, c'était encore mieux - la ligne rouge va presque à côté du prix. Probablement à cause des mises à jour ou parce qu'il est tellement codé qu'il vieillit avec le temps.
 

Indicateur intéressant ! Merci à son créateur.

Afin de voir la qualité de sa prédiction, j'ai ajouté un paramètre supplémentaire Start au code - à partir de quelle barre commencer au lieu de la barre zéro.

J'ai également ajouté un gestionnaire d'événement pour le mouvement de la souris.

Pour le lancer, il suffit d'appuyer sur Ctrl et de déplacer la souris (je vous conseille d'activer le réticule) - sa position sur le graphique sera Start.

C'est très amusant de le regarder en dynamique.

Pour l'éteindre, il suffit d'appuyer sur n'importe quelle touche sauf Ctrl.

//+--------------------------------------------------------------------------------------+
//| Fourier_Extrapolator_of_Price.mq5 |
//| Copyright 2010, gpwr |
//+--------------------------------------------------------------------------------------+
// ajout de la possibilité de décaler le Start ( appuyer sur CTRL)
#property copyright "gpwr"
#property version "1.00"
#property description "Extrapolation of open prices by trigonometric (multitone) model"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//--- résultats du modèle futur
#property indicator_label1 "Modelled future"
#property indicator_type1 DRAW_LINE
#property indicator_color1 Red
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- sorties du modèle passé
#property indicator_label2 "Modled past"
#property indicator_type2 DRAW_LINE
#property indicator_color2 Blue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- constantes globales
#define pi 3.141592653589793238462643383279502884197169399375105820974944592
//--- entrées de l'indicateur
input int Npast =300 ; // Barres passées, auxquelles la série trigonométrique est ajustée
input int Nfut =50 ; // Barres futures prédites
input int Nharm =20 ; // Narmonique dans le modèle
input double FreqTOL =0.00001 ; // Tolérance des calculs de fréquence
input int Start =0 ; // A partir de quelle barre nous commençons
//--- variables globales
int N ;
int key=0 ;
int start=0 ;
//--- tampons d'indicateurs
double ym[],xm[] ;
//+------------------------------------------------------------------+
//| Fonction d'initialisation personnalisée de l'indicateur |
//+------------------------------------------------------------------+
void OnInit()
{
//--- initialiser les variables globales
N=MathMax(Npast,Nfut+1) ;

//--- cartographie des tampons d'indicateurs
ArraySetAsSeries(xm,true) ;
ArraySetAsSeries(ym,true) ;
SetIndexBuffer(0,ym,INDICATOR_DATA) ;
SetIndexBuffer(1,xm,INDICATOR_DATA) ;
IndicatorSetInteger(INDICATOR_DIGITS,_Digits) ;
IndicatorSetString(INDICATOR_SHORTNAME, "Fourier("+string(Npast)+")") ;
PlotIndexSetInteger(0,PLOT_SHIFT,Nfut) ;
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true) ;
start=Start ;
}
//+------------------------------------------------------------------+
//| Fonction d'itération de l'indicateur personnalisé |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime& Time[],
const double& Open[],
const double& High[],
const double& Low[],
const double& Close[],
const long& tick_volume[],
const long& volume[],
const int& spread[])
{
{ // Vérifier si les données sont insuffisantes

if(rates_total<Npast)
{
Print("Error : pas assez de barres dans l'historique !") ;
return(0) ;
}

//--- initialiser les tampons de l'indicateur à EMPTY_VALUE
ArrayInitialize(xm,EMPTY_VALUE) ;
ArrayInitialize(ym,EMPTY_VALUE) ;

//--- rendre tous les prix disponibles
MqlRates rates[] ;
ArraySetAsSeries(rates,true) ;
if(CopyRates(NULL,0,start,Npast,rates)<=0) return(0) ;

//--- cycle principal
//--- préparer les données d'entrée
double x[] ;
ArrayResize(x,Npast) ;
double av=0 ;
for(int i=0;i<Npast;i++)
{
x[i]=rates[i].open ;
av+=x[i] ;
}
av/=Npast ;

//--- initialiser les sorties du modèle
for(int i=0;i<N<N;i++)
{
{ xm[i+start]=av ;
if(i<=Nfut) ym[i+start]=av ;
}

//--- ajuster le modèle trigonométrique et calculer les prédictions
for(int harm=1;harm<=Nharm;harm++)
{
double w,m,a,b ;
Freq(x,Npast,w,m,a,b) ;
for(int i=0;i<N;i++)
{
xm[i+start]+=m+a*MathCos(w*i)+b*MathSin(w*i) ;
if(i<=Nfut) ym[Nfut-i+start]+=m+a*MathCos(w*i)-b*MathSin(w*i) ;
}
}

return(rates_total) ;
}
//--- event handler for Ctrl press and mouse movement
void OnChartEvent(const int id, // event identifier
const long& lparam, // event parameter of type long
const double& dparam, // event parameter of type double
const string& sparam // event parameter of type string
)

{
double y ;
int window=0 ;
datetime ttt ;
if(id==CHARTEVENT_KEYDOWN) key=(int)lparam ;
if(id==CHARTEVENT_MOUSE_MOVE && key==17)
{
ChartXYToTimePrice(0,(int)lparam,(int)dparam,window,ttt,y) ;
if(ttt !=0) start=iBarShift(NULL,0,ttt,false) ;
Comment("x = ",lparam,", y = ",dparam,", Price = ",y,", start = ",start) ;


ArrayInitialize(xm,EMPTY_VALUE) ;
ArrayInitialize(ym,EMPTY_VALUE) ;

//--- rendre tous les prix disponibles
MqlRates rates[] ;
ArraySetAsSeries(rates,true) ;
if(CopyRates(NULL,0,start,Npast,rates)<=0) return ;

//--- cycle principal
//--- préparer les données d'entrée
double x[] ;
ArrayResize(x,Npast) ;
double av=0 ;
for(int i=0;i<Npast;i++)
{
x[i]=rates[i].open ;
av+=x[i] ;
}
av/=Npast ;

//--- initialiser les sorties du modèle
for(int i=0;i<N;i++)
{
xm[i+start]=av ;
if(i<=Nfut) ym[i+start]=av ;
}

//--- ajuster le modèle trigonométrique et calculer les prédictions
for(int harm=1;harm<=Nharm;harm++)
{
double w,m,a,b ;
Freq(x,Npast,w,m,a,b) ;
for(int i=0;i<N;i++)
{
xm[i+start]+=m+a*MathCos(w*i)+b*MathSin(w*i) ;
if(i<=Nfut) ym[Nfut-i+start]+=m+a*MathCos(w*i)-b*MathSin(w*i) ;
}
}
}
}


//+------------------------------------------------------------------+
//| Algorithme de Quinn et Fernandes pour trouver la fréquence |
//+------------------------------------------------------------------+
void Freq(double& x[],int n,double& w,double& m,double& a,double& b)
{
double z[] ;
ArrayResize(z,n) ;
double alpha=0.0 ;
double beta=2.0 ;
z[0]=x[0]-xm[0+début] ;
while(MathAbs(alpha-beta)>FreqTOL)
{
alpha=beta ;
z[1]=x[1]-xm[1+début]+alpha*z[0] ;
double num=z[0]*z[1] ;
double den=z[0]*z[0] ;
for(int i=2;i<n;i++)
{
z[i]=x[i]-xm[i+start]+alpha*z[i-1]-z[i-2] ;
num+=z[i-1]*(z[i]+z[i-2]) ;
den+=z[i-1]*z[i-1] ;
}
beta=num/den ;
}
w=MathArccos(beta/2.0) ;
TrigFit(x,n,w,m,a,b) ;
}
//+------------------------------------------------------------------+
//| Ajustement par les moindres carrés de séries trigonométriques |
//+------------------------------------------------------------------+
void TrigFit(double& x[],int n,double w,double& m,double& a,double& b)
{
double Sc =0.0 ;
double Ss=0.0 ;
double Scc=0.0 ;
double Sss=0.0 ;
double Scs=0.0 ;
double Sx=0.0 ;
double Sxc=0.0 ;
double Sxs=0.0 ;
for(int i=0;i<n;i++)
{
double c=MathCos(w*i) ;
double s=MathSin(w*i) ;
double dx=x[i]-xm[i+start] ;
Sc +=c ;
Ss +=s ;
Scc+=c*c ;
Sss+=s*s ;
Scs+=c*s ;
Sx +=dx ;
Sxc+=dx*c ;
Sxs+=dx*s ;
}.
Sc /=n ;
Ss /=n ;
Scc/=n ;
Sss/=n ;
Scs/=n ;
Sx /=n ;
Sxc/=n ;
Sxs/=n ;
if(w==0.0)
{
m=Sx ;
a=0.0 ;
b=0.0 ;
}
else
{
// calcul de a, b et m
double den=MathPow(Scs-Sc*Ss,2)-(Scc-Sc*Sc)*(Sss-Ss*Ss) ;
a=((Sxs-Sx*Ss)*(Scs-Sc*Ss)-(Sxc-Sx*Sc)*(Sss-Ss*Ss))/den ;
b=((Sxc-Sx*Sc)*(Scs-Sc*Sc*Ss)-(Sxs-Sx*Ss)*(Scc-Sc*Sc*Sc))/den ;
m=Sx-a*Sc-b*Ss ;
}
}

int iBarShift(string symbol,int timeframe,datetime time,bool exact=false)
{
if(time<0) return(-1) ;
ENUM_TIMEFRAMES tf=TFMigrate(timeframe) ;
datetime Arr[],time1 ;
CopyTime(symbol,tf,0,1,Arr) ;
time1=Arr[0] ;
if(CopyTime(symbol,tf,time,time1,Arr)>0)
{
if(ArraySize(Arr)>2) return(ArraySize(Arr)-1) ;
if(time<time1) return(1) ;
else return(0) ;
}
else return(-1) ;
}
ENUM_TIMEFRAMES TFMigrate(int tf)
{
switch(tf)
{
case 0 : return(PERIOD_CURRENT) ;
case 1 : return(PERIOD_M1) ;
case 5 : return(PERIOD_M5) ;
case 15 : return(PERIOD_M15) ;
case 30 : return(PERIOD_M30) ;
case 60 : return(PERIOD_H1) ;
case 240 : return(PERIOD_H4) ;
case 1440 : return(PERIOD_D1) ;
case 10080 : return(PERIOD_W1) ;
case 43200 : return(PERIOD_MN1) ;

case 2 : return(PERIOD_M2) ;
case 3 : return(PERIOD_M3) ;
case 4 : return(PERIOD_M4) ;
case 6 : return(PERIOD_M6) ;
case 10 : return(PERIOD_M10) ;
case 12 : return(PERIOD_M12) ;
case 16385 : return(PERIOD_H1) ;
case 16386 : return(PERIOD_H2) ;
case 16387 : return(PERIOD_H3) ;
case 16388 : return(PERIOD_H4) ;
case 16390 : return(PERIOD_H6) ;
case 16392 : return(PERIOD_H8) ;
case 16396 : return(PERIOD_H12) ;
case 16408 : return(PERIOD_D1) ;
case 32769 : return(PERIOD_W1) ;
case 49153 : return(PERIOD_MN1) ;
default : return(PERIOD_CURRENT) ;
}
}

 
Nikolay7ko:

...

Veuillez insérer le code correctement. Il est beaucoup plus agréable de percevoir un code correctement inséré : Insérer un code correctement dans le forum