Canal de regressão linear - página 17

 

Acredito de bom grado que é possível fazer muitas funções com cálculo acelerado. Como subtrair um valor do final de um período e acrescentar um novo valor ao início, sem um ciclo.

Em particular, aqui está um exemplo de como você pode calcular vários tipos de filtro desde a simples ondulação até a regressão linear sem um ciclo.

#property indicator_chart_window 
#property indicator_buffers 2 
#property indicator_plots   1  
#property indicator_type1   DRAW_COLOR_LINE 
#property indicator_color1  clrDeepSkyBlue,clrBisque 
#property indicator_width1  2 
//********************************************************************
input int    p = 24;
input double N = 3;
//********************************************************************
double ss[],col[];
double ci,sum1,sum2,c1,c2,mai,lwi,fxi;
 int w,fs;
//********************************************************************
int OnInit()
{
   SetIndexBuffer(0,ss,INDICATOR_DATA); 
   SetIndexBuffer(1,col,INDICATOR_COLOR_INDEX); 
   //------------------------------------------
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrDeepSkyBlue);
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,clrBisque);
   //------------------------------------------
   
   return(INIT_SUCCEEDED);
}
//********************************************************************
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[])
{
   //--------------------------------------------------------
   if (prev_calculated==rates_total) return(rates_total);
   int start=prev_calculated; 
   if (prev_calculated==0) 
   {
      start=p; 
      
      int k=0; w=0; sum1=0; sum2=0;
      for(int j=p-1; j>=0; j--)
      {
         k++;
         ci=open[start-j];
         sum1+=ci; 
         sum2+=k*ci; 
         w+=k; 
      }
      mai=sum2/w; ss[start]=mai; 
      ci=open[start]; 
      sum1-=ci; sum2-=ci*p;
      start++;
   }
   //--------------------------------------------------------
   for(int i=start; i<rates_total; i++)
   {
      c1=open[i-1];  
      c2=open[i-p]; 
      
      sum1+=c1-c2;
      sum2+=c1*p-c2-sum1;
         
      ci=open[i]; 
      
      lwi=(sum2+ci*p)/w;
      mai=(sum1+ci)/p;
      
      fxi=mai+(lwi-mai)*N;
      
      ss[i]=fxi;
      
      if (ss[i]>ss[i-1]) fs=0; else  
      if (ss[i]<ss[i-1]) fs=1; 
      
      if (fs==0) col[i]=0; else col[i]=1;   
   }
   //--------------------------------------------------------
   return(rates_total);
}
//********************************************************************

Aqui em N=0 - SMA normal, N=1 - ponderada linear, N=3 - regressão linear. E você também pode obter valores intermediários, pois N é fracionário. Também calculei o RMS de maneira semelhante. Acho que a regressão polinomial pode ser feita da mesma maneira. Seria uma necessidade prática. Pelo menos, ainda não consegui usar a regressão polinomial em Expert Advisors lucrativos. Os canais nos EMAs são mais simples e funcionam bem na prática.

Aqui está uma variante levemente arquitetada de regressão linear em mq4 com RMS sem ciclo. Há um ciclo uma vez no início, ou mais precisamente, ao calcular o primeiro conjunto de valores, e isso é tudo, - então há apenas somas e diferenças. É claro que é muito mais rápido do que com ciclos. Uma sutileza é que o período é especificado em horas e é recalculado ao trocar os períodos de tempo.

#property strict
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrOrangeRed
#property indicator_color3 clrLavender
#property indicator_color4 clrLavender
#property indicator_color5 clrMediumAquamarine
#property indicator_color6 clrMagenta
#property indicator_width1 2
#property indicator_width2 2
#property indicator_style5 2
#property indicator_type1 DRAW_LINE
#property indicator_type2 DRAW_LINE
#property indicator_type3 DRAW_LINE
#property indicator_type4 DRAW_LINE
#property indicator_type5 DRAW_LINE
#property indicator_type6 DRAW_LINE
//===========================
extern double hrLR = 12;
extern double ksq  = 1;
extern int    i0   = 1;
extern int    SPR  = 1;
//===========================
double ss[],ssL[],sH[],sL[],ma[],sU[];
double lri,sq,mai,ui,spr2;
int p,fs;
//******************************************************************
int init() 
{
   SetIndexBuffer(0,ss);
   SetIndexBuffer(1,ssL); SetIndexEmptyValue(1,0);
   SetIndexBuffer(2,sH);
   SetIndexBuffer(3,sL);
   SetIndexBuffer(4,ma);
   SetIndexBuffer(5,sU);
   //--------------------
   p=int(hrLR*60/Period()); if (p<3) p=3;
   if (SPR<0) spr2=-SPR*Point/2;
   
   return(0);
}
//******************************************************************
int start() 
{
   int cbi=Bars-IndicatorCounted()-1; if (cbi<0) return(-1);
   if (i0==1 && cbi==0) return(0); if (cbi==1) cbi=0;
   if (SPR>0) spr2=NormalizeDouble(Ask-Bid,Digits)/2;
   if (cbi>1)
   { 
      cbi=Bars-p-1; 
   
      af_LR0(0,cbi); ui=mai; 
   }
   //------------------------------
   for(int i=cbi; i>=0; i--) 
   { 
      lri=af_LR0(1,i);
      
      ss[i]=lri;
      sH[i]=lri+sq;
      sL[i]=lri-sq;
      ma[i]=mai;
      
      if (sL[i]>ui) ui=sL[i]; else if (sH[i]<ui) ui=sH[i];
      
      sU[i]=ui;
      
      if (ss[i]>ss[i+1]) fs=1;
      if (ss[i]<ss[i+1]) {if (fs==1) ssL[i+1]=ss[i+1]; fs=2;}
      if (fs==2) ssL[i]=ss[i]; else if (fs==1) ssL[i]=0.0; 
   }
   return(0);
}
//********************************************************************
double af_LR0(int index, int i)
{
   static double sx,syp,sxy,syyp,S;
   double ci=0,c1=0,cp=0,sy,syy,aa,bb;
   static int ti;
   
   if (index==1)
   {
      if (ti!=Time[i]) 
      {
         if (i0==0) {c1=Close[i+1]+spr2; cp=Close[i+p]+spr2;} else
         if (i0==1) {c1=Open[i+1]+spr2; cp=Open[i+p]+spr2;} else
         if (i0==2) {c1=(High[i+1]+Low[i+1])/2+spr2; cp=(High[i+p]+Low[i+p])/2+spr2;}
         
         sxy+=syp+c1-p*cp; 
         syp+=c1-cp;
         syyp+=c1*c1-cp*cp; 
         ti=int(Time[i]);
      }
   }
   else
   {
      int j;
      double sxx;
      
      sx=0.0; sxx=0.0; 
      for (j=0; j<p; j++) {sx+=j; sxx+=j*j;} 
      S=sx*sx-p*sxx;
      
      syp=0.0; sxy=0.0; syyp=0.0;
      for (j=1; j<p; j++) 
      {
         if (i0==0) ci=Close[i+j]+spr2; else
         if (i0==1) ci=Open[i+j]+spr2; else
         if (i0==2) ci=(High[i+j]+Low[i+j])/2+spr2;
         
         syp+=ci; 
         sxy+=j*ci;
         syyp+=ci*ci;
      }
      
      ti=int(Time[i]);
   }
   
   if (i0==0) ci=Close[i]+spr2; else
   if (i0==1) ci=Open[i]+spr2; else
   if (i0==2) ci=(High[i]+Low[i])/2+spr2;
         
   sy=syp+ci; 
   syy=syyp+ci*ci;
   
   aa=(sx*sy-p*sxy)/S; 
   bb=(sy-aa*sx)/p;
   
   sq = (syy - aa*sxy - bb*sy)/(p-2); 
   if (sq>=0) sq = MathSqrt(sq)*ksq;
   
   mai=sy/p;
      
   return(bb);
}
//********************************************************************

 
Yousufkhodja Sultonov:

Por que Fedoseyev se auto-excluiu, raciocinando corretamente?

Porque ele raciocinou de forma incorreta.
Leia a linha.

 
O que o "no loop" faz por você?

Quanto acelera a execução do código?
 
danminin:
O que o "no loop" faz por você?

Quanto mais rápido ele faz seu código funcionar?
Muito, na verdade. Eu costumava medi-lo com GetTickCount(). Mas é bem perceptível quando se precisa fazer muitas otimizações. Uma coisa é quando você tem que contar muitas variantes durante várias horas, e outra coisa é quando você tem que fazê-lo em várias dezenas ou unidades de minutos. Mas raramente é necessário. É por isso que talvez você não se preocupe muito com isso.
 
ANG3110:

Acredito de bom grado que muitas funções podem ser feitas com cálculo acelerado. Como subtrair um valor do final de um período e acrescentar um novo valor ao início, sem um ciclo.

Em particular, aqui está um exemplo de como você pode calcular vários tipos de filtro desde a simples ondulação até a regressão linear, sem ciclo.

Aqui em N=0 - SMA normal, N=1 - ponderada linear, N=3 - regressão linear. E você também pode obter valores intermediários, pois N é fracionário. Também calculei o RMS de maneira semelhante. Acho que a regressão polinomial pode ser feita da mesma maneira. Seria uma necessidade prática. Pelo menos, ainda não consegui usar a regressão polinomial em Expert Advisors lucrativos. Os canais nos EMAs são mais simples e funcionam bem na prática.

Aqui está uma variante ligeiramente modificada da regressão linear em mq4 com RMS sem loops. Há um ciclo uma vez na iniciação, ou mais precisamente, ao calcular a primeira leitura, e é isso - então há apenas somas e diferenças. É claro que ele calcula muitas vezes mais rápido do que com ciclos.

Sim. Isso é correto. Este é um exemplo real de cálculo de RMS sem ciclo em regressão linear.
É verdade que há um pequeno erro em algum lugar no algoritmo, levando a que as três linhas (centro, limite superior e inferior do canal) sejam deslocadas para cima.


 
Nikolai Semko:

Sim. Isso é correto. Este é um exemplo real de cálculo de RMS sem ciclo em regressão linear.
É verdade que há um pequeno erro em algum lugar no algoritmo, levando a que as três linhas (centro, limite superior e inferior do canal) sejam deslocadas para cima.


E há apenas a metade do spread somado. Fiz isso uma vez, para testar um Expert Advisor comercial para ter alinhamento relativo a - Ask-Bid. Se você definir SPR=0, não haverá compensação. Contará apenas com os preços de licitação.
 
danminin:
O que este "sem loop" faz por você?

Quanto mais rápido ele faz seu código funcionar?

Só o cálculo do RMS pode dar um ganho de cerca de 10 a 1.000 vezes, dependendo do período.

 
ANG3110:
E há apenas a metade do spread adicionado. Fiz isso uma vez para testar um Expert Advisor comercial para ter alinhamento relativo a - Ask-Bid. Se definirmos SPR=0, não haverá compensação. Contará apenas com os preços de licitação.

Sim, exatamente. Uma correspondência completa com minha implementação de regressão linear.

 
Yousufkhodja Sultonov:


Como está indo o indicador Sultonov? Já quebrou a parte de trás do câmbio ou está em andamento?
 
Vladimir Baskakov:
Como está indo o indicador Sultonov? Já quebrou a parte de trás do câmbio ou está em vias de fazê-lo?

O indicador funciona em uma conta real de um centavo na UPU em uma base de "correr e esquecer" com um depósito de 48 u.c. No segundo mês, ele tem pairado em torno de 50, aparentemente, esperando pelo seu tempo. É impossível receber mais de 10% ao ano no Forex, de forma estável e sem risco, desde que os lucros sejam reinvestidos por muitos anos - estas são minhas conclusões sobre a espinha dorsal do Forex. As conclusões apressadas de 8 anos atrás são abaladas pela realidade do mercado. O poderoso modelo de regressão universal falhou miseravelmente, produzindo lucros bancários. O URM faz um ótimo trabalho em todos os processos técnicos, sociais, de mineração (extração de ouro de minérios pobres) e outros processoso exceto o elemento mercado. A conclusão é que os modelos de regressão têm um potencial limitado para extrair lucros do mercado.