Индикаторы: Экстраполяция цен методом Фурье - страница 4

 

Интересный индикатор. Мне нравится математический аспект использования проекционной модели на графиках. Я еще не слишком опытен в работе с кодом, поэтому мне интересно, как вы собираетесь настроить модель на "возврат назад" и сделать кривую прогноза, которую она - должна была бы - сделать определенное количество тиков назад (скажем, 100). Таким образом можно было бы применять модель к различным графикам и получать представление о том, насколько реальность отличается от модели, возможно, использовать это для определения некоторых характеристик рынка, на котором модель работает хорошо, и т.д.

 
Saidar:
Да, я использую Windows 7, я посмотрю.

возможно, вы захотите запустить mt5 в портативном режиме:

terminal.exe /portable

Вы получите индикатор, работающий в текущем каталоге mt5 - полезно для установки на pendrive

 

модификация, заставляющая индикатор сдвигаться назад по времени для проверки его предсказательной способности:

в строке 32 вставить:
input int TimeShift = 10; // на сколько баров сдвигается назад, полезно для оценки предсказуемости индикатора

в строке 54 заменить:
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut);
на:
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut - TimeShift);

в строке 55 вставить:
PlotIndexSetInteger(1, PLOT_SHIFT, -TimeShift);

в строке 87 заменить:
if(CopyRates(NULL, 0, 0, Npast, rates) <= 0) return(0);
with:
if(CopyRates(NULL, 0, TimeShift, Npast, rates) <= 0) return(0);

 

Стоящая внимания вещь.

Кто его ипользует в торговле?

Я прогнал по истории - оказалось, что индикатор не учитывает тренд вообще, он на протяжении нескольких тысяч  пятизначных  пунктов прогнозировал против тренда, по моему его надо использовать с индикатором вроде MA/CCI/Полос Боллинджера, где экстраполятор будет подтверждать сигнал, иначе это может обернуться сливом

По идее его правильнее всего использовать на старших таймфреймах, на D1 он на протяжении месяца прогнозировал с потрясающей точностью, но когда пошел тренд, я был очень сильно разочарован(см. прошлый абзац)

 

Спасибо

 
lazarev-d-m:

Стоящая внимания вещь.

Кто его ипользует в торговле?


 

Мне тоже очень интересно, если кто использует экстрапооляторы в своих ТС, то как именно? И насколько перспективно такое направление поиска Грааля?

Чисто интуитивно кажется что это то что нужно, но как то на тестах и сами предсказание именно этого экстраполятора, очень слабо корелируют с действительностью, по крайней мере у меня так вышло...

Подскажите пожалуйста, а каков выбор экстраполяторов и какой из них наиболее точен? Я имею в виду наверно не только в ряд Фурье можно разложить, способов бесконечьно. К примеру можно с самих простых способов пойти и отталкиваться от пересечения МА или MACD и таким образом прогнозировать кривую, ну а если не лень то разными эмпирическими декомпозициями раскладывать, затем усреднять и вновь коппоновать... Я теоретически представляю как это сделать но если начну пытаться закодить то за год не управлюсь(((

 Прикольно бы было если бы экстраполятор задавал распределение вероятности по ближайщему будущему, а не линию рисовал.

 

 
Alex_Bondar:


 Прикольно бы было если бы экстраполятор задавал распределение вероятности по ближайщему будущему, а не линию рисовал.


Думаю как то так скорей всего, если поупражняться в фотошопе)))

 

 
Поначалу вроде неплохо предсказывал, но последнее время стал выдавать прямую линию, хотя на старых терминалах, которыми давно не пользовался даже лучше стал - красная линия идет почти рядом с ценой. Почему так происходит? наверно из -за обновлений или так закодирован что от временистареет
 

Интересный индикатор! Спасибо его творцу.

Для того, чтобы  было видно качество его предсказывания - в код добавил еще один параметр Start -  с какого бара начинать вместо нулевого.

Так же добавил обработчик события - на движение мыши.

Чтобы его запустить просто нужно нажать Ctrl и двигать мышкой (советую включить перекрестие) - её положение на графике и будет Start.

Очень забавно посмотреть на это в динамике.

Для выключения  - просто нажать любую клавишу кроме Ctrl

 

//+--------------------------------------------------------------------------------------+
//| Fourier_Extrapolator_of_Price.mq5 |
//| Copyright 2010, gpwr |
//+--------------------------------------------------------------------------------------+
// добавлена возможность сдвигать начало отсчета ( нажать 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; // С какого бара начинаем
//--- global variables
int N;
int key=0;
int start=0;
//--- indicator buffers
double ym[],xm[];
//+------------------------------------------------------------------+
//| Custom indicator initialization 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);
}

//--- initialize 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;

//--- initialize 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);
}
}

return(rates_total);
}
//--- обработчик события нажатия Ctrl и движения мыши
void OnChartEvent(const int id, // идентификатор события
const long& lparam, // параметр события типа long
const double& dparam, // параметр события типа double
const string& sparam // параметр события типа 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;

//--- initialize 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*Ss)-(Sxs-Sx*Ss)*(Scc-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:

...

Вставляйте, пожалуйста, код правильно. Воспринимать правильно вставленный код намного приятнее: Правильно вставляем код на форуме