
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hey, interesting indicator. I'm liking the mathematical aspect of actually using a projection model on the charts. I'm not too experienced with code yet, so I'm wondering how you'd go about setting the model to "go back" and do the prediction curve it -would- have made a certain number of ticks ago (say, 100). That way it could be applied to various charts and give an idea of how much the reality varies from the model, maybe use that to identify some characteristics of a market where the model works well, etc.
Yes I use Windows 7, will have a look
you may want to run mt5 in portable mode:
terminal.exe /portable
you will get indicator working in the current mt5 directory - useful for pendrive installation
modification for making it back-shift in time for testing its prediction capability:
at line 32 insert:
input int TimeShift = 10; // how many bars shift back, useful for evaluating predictability of indicator
at line 54 replace:
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut);
with:
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut - TimeShift);
at line 55 insert:
PlotIndexSetInteger(1, PLOT_SHIFT, -TimeShift);
at line 87 replace:
if(CopyRates(NULL, 0, 0, Npast, rates) <= 0) return(0);
with:
if(CopyRates(NULL, 0, TimeShift, Npast, rates) <= 0) return(0);
Worth a look.
Who uses it in trading?
I ran it through the history - it turned out that the indicator does not take into account the trend at all, it predicted against the trend for several thousand five-digit points, in my opinion it should be used with an indicator like MA/CCI/Bollinger Bands, where the extrapolator will confirm the signal, otherwise it can turn out to be a drain
It is supposed to be best used on higher timeframes, on D1 it predicted with amazing accuracy for a month, but when the trend started, I was very disappointed (see last paragraph).
Thank You
Worth a look.
Who uses it in the trade?
I am also very curious, if anyone uses extrapolators in their TS, how exactly? And how promising is this direction of searching for the Grail?
Purely intuitively it seems that this is what is needed, but somehow on the tests and predictions of this extrapolator correlate very poorly with reality, at least for me it turned out so...
Could you please tell me, what is the choice of extrapolators and which of them is the most accurate? I mean probably not only Fourier series can be decomposed, the ways are endless. For example, you can go from the simplest ways and start from the crossing of MA or MACD and thus predict the curve, and if you are not lazy, then different empirical decompositions, then averaging and then again copponing.... I can theoretically imagine how to do it, but if I start trying to code it, I won't be able to do it in a year((((
It would be cool if the extrapolator would set the probability distribution for the near future instead of drawing a line.
It would be cool if the extrapolator set the probability distribution for the near future, instead of drawing a line.
I think it could be like that, if you practise in photoshop))))
Interesting indicator! Thanks to its creator.
In order to see the quality of its prediction, I added one more parameter Start to the code - from which bar to start instead of the zero bar.
I also added an event handler for mouse movement.
To start it you just need to press Ctrl and move the mouse (I advise you to enable crosshair) - its position on the chart will be Start.
It is very funny to watch it in dynamics.
To switch it off - just press any key except Ctrl
//+--------------------------------------------------------------------------------------+
//| Fourier_Extrapolator_of_Price.mq5 |
//| Copyright 2010, gpwr |
//+--------------------------------------------------------------------------------------+
// added possibility to shift the Start ( press 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
//--- future model outputs
#property indicator_label1 "Modeled future"
#property indicator_type1 DRAW_LINE
#property indicator_color1 Red
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- past model outputs
#property indicator_label2 "Modeled past"
#property indicator_type2 DRAW_LINE
#property indicator_color2 Blue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- global constants
#define pi 3.141592653589793238462643383279502884197169399375105820974944592
//--- indicator inputs
input int Npast =300; // Past bars, to which trigonometric series is fitted
input int Nfut =50; // Predicted future bars
input int Nharm =20; // Narmonics in model
input double FreqTOL =0.00001; // Tolerance of frequency calculations
input int Start =0; // From which bar we start
//--- global variables
int N;
int key=0;
int start=0;
//--- indicator buffers
double ym[],xm[];
//+------------------------------------------------------------------+
//| Custom indicator initialisation function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- initialize global variables
N=MathMax(Npast,Nfut+1);
//--- indicator buffers mapping
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;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
{ // Check for insufficient data
if(rates_total<Npast)
{
Print("Error: not enough bars in history!");
return(0);
}
//--- initialise indicator buffers to EMPTY_VALUE
ArrayInitialize(xm,EMPTY_VALUE);
ArrayInitialize(ym,EMPTY_VALUE);
//--- make all prices available
MqlRates rates[];
ArraySetAsSeries(rates,true);
if(CopyRates(NULL,0,start,Npast,rates)<=0) return(0);
//--- main cycle
//--- prepare input data
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;
//--- initialise model outputs
for(int i=0;i<N<N;i++)
{
{ xm[i+start]=av;
if(i<=Nfut) ym[i+start]=av;
}
//--- fit trigonometric model and calculate predictions
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);
//--- make all prices available
MqlRates rates[];
ArraySetAsSeries(rates,true);
if(CopyRates(NULL,0,start,Npast,rates)<=0) return;
//--- main cycle
//--- prepare input data
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;
//--- initialise model outputs
for(int i=0;i<N;i++)
{
xm[i+start]=av;
if(i<=Nfut) ym[i+start]=av;
}
//--- fit trigonometric model and calculate predictions
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);
}
}
}
}
//+------------------------------------------------------------------+
//| Quinn and Fernandes algorithm for finding frequency |
//+------------------------------------------------------------------+
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+start];
while(MathAbs(alpha-beta)>FreqTOL)
{
alpha=beta;
z[1]=x[1]-xm[1+start]+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);
}
//+------------------------------------------------------------------+
//| Least-squares fitting of trigonometric series |
//+------------------------------------------------------------------+
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
{
// calculating a, b, and 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);
}
}
...