Indicadores: Extrapolação Fourier de preço - página 4

 

Olá, indicador interessante. Estou gostando do aspecto matemático de realmente usar um modelo de projeção nos gráficos. Como ainda não tenho muita experiência com código, gostaria de saber como você configuraria o modelo para "voltar" e fazer a curva de previsão que ele teria feito há um determinado número de ticks (digamos, 100). Dessa forma, ele poderia ser aplicado a vários gráficos e dar uma ideia de quanto a realidade varia em relação ao modelo, talvez usar isso para identificar algumas características de um mercado em que o modelo funciona bem etc.

 
Saidar:
Sim, eu uso o Windows 7, vou dar uma olhada

talvez você queira executar o mt5 no modo portátil:

terminal.exe /portable

você obterá o indicador funcionando no diretório atual do mt5 - útil para a instalação do pendrive

 

modificação para fazer com que ele se desloque para trás no tempo para testar sua capacidade de previsão:

na linha 32, insira:
input int TimeShift = 10; // quantas barras são deslocadas para trás, útil para avaliar a previsibilidade do indicador

na linha 54 substitua:
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut);
por:
PlotIndexSetInteger(0, PLOT_SHIFT, Nfut - TimeShift);

na linha 55 insira:
PlotIndexSetInteger(1, PLOT_SHIFT, -TimeShift);

na linha 87 replace:
if(CopyRates(NULL, 0, 0, Npast, rates) <= 0) return(0);
with:
if(CopyRates(NULL, 0, TimeShift, Npast, rates) <= 0) return(0);

 

Vale a pena dar uma olhada.

Quem o utiliza nas negociações?

Eu o analisei no histórico e descobri que o indicador não leva em conta a tendência, ele previu contra a tendência por vários milhares de pontos de cinco dígitos. Na minha opinião, ele deve ser usado com um indicador como MA/CCI/Bollinger Bands, em que o extrapolador confirmará o sinal, caso contrário, ele pode se tornar um ralo

Supõe-se que ele seja mais bem utilizado em períodos de tempo mais altos. No D1, ele previu com incrível precisão durante um mês, mas quando a tendência começou, fiquei muito desapontado (veja o último parágrafo).

 

Obrigado

 
lazarev-d-m:

Vale a pena dar uma olhada.

Quem o utiliza no comércio?


Também estou muito curioso, se alguém usa extrapoladores em seu TS, como exatamente? E quão promissora é essa direção de busca do Graal?

De forma puramente intuitiva, parece que isso é o que é necessário, mas, de alguma forma, os testes e as previsões desse extrapolador não se correlacionam muito bem com a realidade, pelo menos para mim foi o que aconteceu...

Você poderia me dizer qual é a escolha dos extrapoladores e qual deles é o mais preciso? Quero dizer, provavelmente não apenas as séries de Fourier podem ser decompostas, as formas são infinitas. Por exemplo, você pode ir das formas mais simples e começar a partir do cruzamento de MA ou MACD e, assim, prever a curva, e se você não for preguiçoso, então diferentes decomposições empíricas, em seguida, a média e, em seguida, novamente copponing.... Teoricamente, posso imaginar como fazer isso, mas se eu começar a tentar codificá-lo, não conseguirei fazê-lo em um ano((((

Seria legal se o extrapolador definisse a distribuição de probabilidade para o futuro próximo em vez de desenhar uma linha.

 
Alex_Bondar:


Seria legal se o extrapolador definisse a distribuição de probabilidade para o futuro próximo, em vez de desenhar uma linha.


Acho que poderia ser assim, se você praticar no photoshop)))))

 
No início, ele parecia prever bem, mas recentemente começou a apresentar uma linha reta, embora nos terminais antigos, que não uso há muito tempo, fosse ainda melhor - a linha vermelha fica quase ao lado do preço. Por que isso acontece? Provavelmente por causa das atualizações ou porque está tão codificado que fica velho com o tempo.
 

Indicador interessante! Agradeço ao seu criador.

Para ver a qualidade de sua previsão, adicionei mais um parâmetro Start ao código - a partir de qual barra começar em vez da barra zero.

Também adicionei um manipulador de eventos para o movimento do mouse.

Para iniciá-lo, basta pressionar Ctrl e mover o mouse (aconselho a ativar a mira) - sua posição no gráfico será Start.

É muito engraçado observá-lo em dinâmica.

Para desativá-lo, basta pressionar qualquer tecla, exceto Ctrl

//+--------------------------------------------------------------------------------------+
//| Fourier_Extrapolator_of_Price.mq5 |
//| Copyright 2010, gpwr |
//+--------------------------------------------------------------------------------------+
// adicionada a possibilidade de deslocar o Start (pressione CTRL)
#property copyright "gpwr"
#property version "1.00"
#property description "Extrapolação de preços abertos por modelo trigonométrico (multitone)"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//--- outputs do modelo futuro
#property indicator_label1 "Modeled future"
#property indicator_type1 DRAW_LINE
#property indicator_color1 Red
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- saídas de modelos passados
#property indicator_label2 "Modeled past"
#property indicator_type2 DRAW_LINE
#property indicator_color2 Blue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- constantes globais
#define pi 3.141592653589793238462643383279502884197169399375105820974944592
//--- entradas do indicador
input int Npast =300; // Barras passadas, às quais a série trigonométrica é ajustada
input int Nfut =50; // Barras futuras previstas
input int Nharm =20; // Narmônicos no modelo
input double FreqTOL =0.00001; // Tolerância dos cálculos de frequência
input int Start =0; // A partir de qual barra começamos
//--- variáveis globais
int N;
int key=0;
int start=0;
//--- buffers de indicadores
double ym[],xm[];
//+------------------------------------------------------------------+
//| Função de inicialização personalizada do indicador |
//+------------------------------------------------------------------+
void OnInit()
{
//--- inicializar variáveis globais
N=MathMax(Npast,Nfut+1);

//--- mapeamento de buffers de indicadores
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;
}
//+------------------------------------------------------------------+
//| Função de iteração de indicador personalizado |
//+------------------------------------------------------------------+
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[])
{
{ // Verificar se há dados insuficientes

if(rates_total<Npast)
{
Print("Error: não há barras suficientes no histórico!");
return(0);
}

//--- inicializar os buffers do indicador para EMPTY_VALUE
ArrayInitialize(xm,EMPTY_VALUE);
ArrayInitialize(ym,EMPTY_VALUE);

//--- disponibilizar todos os preços
MqlRates rates[];
ArraySetAsSeries(rates,true);
if(CopyRates(NULL,0,start,Npast,rates)<=0) return(0);

//--- ciclo principal
//--- preparar dados de entrada
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;

//--- inicializar as saídas do modelo
for(int i=0;i<N<N;i++)
{
{ xm[i+start]=av;
if(i<=Nfut) ym[i+start]=av;
}

//--- ajustar o modelo trigonométrico e calcular as previsões
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);
}
//--- manipulador de eventos para pressionar Ctrl e mover o mouse
void OnChartEvent(const int id, // identificador de evento
const long& lparam, // parâmetro de evento do tipo long
const double& dparam, // parâmetro de evento do tipo double
const string& sparam // parâmetro de evento do tipo 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,", 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;

//--- inicialize as saídas do modelo
for(int i=0;i<N;i++)
{
xm[i+start]=av;
if(i<=Nfut) ym[i+start]=av;
}

//--- ajuste o modelo trigonométrico e calcule as previsões
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);
}
}
}
}


//+------------------------------------------------------------------+
//| Algoritmo de Quinn e Fernandes para encontrar a frequência |
//+------------------------------------------------------------------+
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);
}
//+------------------------------------------------------------------+
//| Ajuste de mínimos quadrados de séries trigonométricas |
//+------------------------------------------------------------------+
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
{
// calculando a, b e 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);
}
}

Arquivos anexados:
 
Nikolay7ko:

...

Por favor, insira o código corretamente. É muito mais agradável perceber o código inserido corretamente: Inserção correta de código no fórum