Canale di regressione lineare - pagina 17

 

Credo volentieri che sia possibile fare molte funzioni con il calcolo accelerato. Come sottrarre un valore dalla fine di un periodo e aggiungere un nuovo valore all'inizio, senza un ciclo.

In particolare, ecco un esempio di come è possibile calcolare diversi tipi di filtro, dal semplice ondeggiamento alla regressione lineare senza 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);
}
//********************************************************************

Qui a N=0 - SMA normale, N=1 - ponderato lineare, N=3 - regressione lineare. E si possono anche ottenere valori intermedi poiché N è frazionario. Ho anche calcolato l'RMS in modo simile. Penso che la regressione polinomiale possa essere fatta allo stesso modo. Sarebbe una necessità pratica. Almeno, non sono ancora riuscito a usare la regressione polinomiale in Expert Advisors redditizi. I canali su EMA sono più semplici e funzionano bene nella pratica.

Ecco una variante leggermente artificiosa di regressione lineare su mq4 con RMS senza ciclo. C'è un ciclo una volta all'inizio, o più precisamente, quando si calcola la prima serie di valori, e questo è tutto, - poi ci sono solo somme e differenze. Naturalmente, è molto più veloce che con i cicli. Una sottigliezza è che il periodo è specificato in ore e viene ricalcolato quando si cambia l'orario.

#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:

Perché Fedoseyev si è autodistrutto, ragionando correttamente?

Perché ha ragionato in modo sbagliato.
Leggi il thread.

 
Cosa fa il "no loop" per te?

Quanto accelera l'esecuzione del codice?
 
danminin:
Cosa fa il "no loop" per te?

Quanto più velocemente fa girare il vostro codice?
Molto, in realtà. Lo misuravo con GetTickCount(). Ma si nota bene quando si devono fare molte ottimizzazioni. Una cosa è quando devi contare un sacco di varianti per diverse ore, e un'altra cosa è quando devi farlo in diverse decine o unità di minuti. Ma è raramente necessario. Ecco perché non ci si può preoccupare troppo.
 
ANG3110:

Credo volentieri che molte funzioni possono essere fatte con un calcolo accelerato. Come sottrarre un valore dalla fine di un periodo e aggiungere un nuovo valore all'inizio, senza un ciclo.

In particolare, ecco un esempio di come è possibile calcolare diversi tipi di filtro, dalla semplice ondulazione alla regressione lineare, senza ciclo.

Qui a N=0 - SMA normale, N=1 - ponderato lineare, N=3 - regressione lineare. E si possono anche ottenere valori intermedi poiché N è frazionario. Ho anche calcolato l'RMS in modo simile. Penso che la regressione polinomiale possa essere fatta allo stesso modo. Sarebbe una necessità pratica. Almeno, non sono ancora riuscito a usare la regressione polinomiale in Expert Advisors redditizi. I canali su EMA sono più semplici e funzionano bene nella pratica.

Ecco una variante leggermente modificata della regressione lineare in mq4 con RMS senza loop. C'è un ciclo una volta all'inizio, o più precisamente, quando si calcola la prima lettura, e questo è tutto - poi ci sono solo somme e differenze. Naturalmente calcola molte volte più velocemente che con i cicli.

Sì, è corretto. Questo è un esempio reale di calcolo RMS senza ciclo nella regressione lineare.
È vero, c'è un piccolo errore da qualche parte nell'algoritmo, che porta tutte e tre le linee (centro, limite superiore e inferiore del canale) ad essere spostate verso l'alto.


 
Nikolai Semko:

Sì, è corretto. Questo è un esempio reale di calcolo RMS senza ciclo nella regressione lineare.
È vero, c'è un piccolo errore da qualche parte nell'algoritmo, che porta tutte e tre le linee (centro, limite superiore e inferiore del canale) ad essere spostate verso l'alto.


E c'è solo metà dello spread sommato. L'ho fatto una volta, per testare un Expert Advisor di trading per avere l'allineamento relativo a - Ask-Bid. Se impostate SPR=0, non ci sarà alcun offset. Conterà solo sui prezzi delle offerte.
 
danminin:
Cosa fa questo "no loop" per te?

Quanto più velocemente fa girare il vostro codice?

Il solo calcolo RMS può dare un guadagno da circa 10 a 1.000 volte, a seconda del periodo.

 
ANG3110:
E c'è solo metà dello spread aggiunto. L'ho fatto una volta per testare un Expert Advisor di trading per avere un allineamento relativo a - Ask-Bid. Se impostiamo SPR=0, non ci sarà alcun offset. Conterà solo sui prezzi delle offerte.

Sì, esattamente. Una corrispondenza perfetta con la mia implementazione della regressione lineare.

 
Yousufkhodja Sultonov:


Come sta andando l'indicatore Sultonov? Ha già rotto il retro del forex o è in corso?
 
Vladimir Baskakov:
Come sta andando l'indicatore Sultonov? Ha già rotto il retro del forex o è in procinto di farlo?

L'indicatore funziona su un conto reale di un centesimo all'UPU su una base "run and forget" con un deposito di 48 c.u. Il secondo mese è stato in bilico intorno a 50, apparentemente, aspettando il suo momento. È impossibile ricevere più del 10 % all'anno sul Forex, in modo stabile e senza rischi, a condizione di reinvestire i profitti per molti anni - queste sono le mie conclusioni sulla spina dorsale del Forex. Le conclusioni affrettate di 8 anni fa sono infrante dalla realtà del mercato. Il potente modello di regressione universale ha fallito miseramente, producendo profitti bancari. L'URM fa un ottimo lavoro su tutti i processi tecnici, sociali, minerari (estrazione dell'oro da minerali poveri) e altri, tranne l'elemento del mercato. La conclusione è che i modelli di regressione hanno un potenziale limitato per estrarre profitti dal mercato.