Canal de régression linéaire - page 17

 

Je crois volontiers qu'il est possible de faire beaucoup de fonctions avec un calcul accéléré. Comme soustraire une valeur de la fin d'une période et ajouter une nouvelle valeur au début, sans cycle.

En particulier, voici un exemple de la façon dont vous pouvez calculer plusieurs types de filtres, de la simple ondulation à la régression linéaire, sans cycle.

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

Ici à N=0 - SMA normal, N=1 - linéaire pondéré, N=3 - régression linéaire. Et vous pouvez également obtenir des valeurs intermédiaires puisque N est fractionnaire. J'ai également calculé la RMS de manière similaire. Je pense que la régression polynomiale peut être faite de la même manière. Ce serait une nécessité pratique. En tout cas, je n'ai pas encore réussi à utiliser la régression polynomiale dans des Expert Advisors rentables. Les canaux sur les EMA sont plus simples et fonctionnent bien dans la pratique.

Voici une variante légèrement inventée de la régression linéaire sur mq4 avec RMS sans cycle. Il y a un cycle une fois à l'initiation, ou plus précisément, lors du calcul de la première série de valeurs, et c'est tout, - ensuite il n'y a que des sommes et des différences. Bien sûr, c'est beaucoup plus rapide qu'avec les cycles. Une subtilité est que la période est spécifiée en heures et qu'elle est recalculée lors du changement de période.

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

Pourquoi Fedoseyev s'est-il désisté, en raisonnant correctement ?

Parce qu'il a raisonné de manière incorrecte.
Lisez le fil de discussion.

 
Que fait "no loop" pour vous ?

Dans quelle mesure cela accélère-t-il l'exécution du code ?
 
danminin:
Que fait "no loop" pour vous ?

Votre code s'exécutera-t-il plus rapidement ?
Beaucoup, en fait. J'avais l'habitude de le mesurer avec GetTickCount(). Mais c'est bien visible quand on doit faire beaucoup d'optimisations. Une chose est que vous devez compter un grand nombre de variantes pendant plusieurs heures, et une autre chose est que vous devez le faire en plusieurs dizaines ou unités de minutes. Mais c'est rarement nécessaire. C'est pourquoi vous ne devez pas trop vous en soucier.
 
ANG3110:

Je crois volontiers qu'il est possible de faire beaucoup de fonctions avec un calcul accéléré. Comme soustraire une valeur de la fin d'une période et ajouter une nouvelle valeur au début, sans cycle.

En particulier, voici un exemple de la façon dont vous pouvez calculer plusieurs types de filtres, de la simple ondulation à la régression linéaire, sans cycle.

Ici à N=0 - SMA normal, N=1 - linéaire pondéré, N=3 - régression linéaire. Et vous pouvez également obtenir des valeurs intermédiaires puisque N est fractionnaire. J'ai également calculé la RMS de manière similaire. Je pense que la régression polynomiale peut être faite de la même manière. Ce serait une nécessité pratique. En tout cas, je n'ai pas encore réussi à utiliser la régression polynomiale dans des Expert Advisors rentables. Les canaux sur les EMA sont plus simples et fonctionnent bien dans la pratique.

Voici une variante légèrement complexe de la régression linéaire dans mq4 avec RMS sans boucles. Il y a un cycle une fois à l'initiation, ou plus précisément, lors du calcul de la première lecture, et c'est tout - ensuite il n'y a que des sommes et des différences. Bien sûr, il calcule plusieurs fois plus vite qu'avec des cycles.

Oui. C'est exact. Il s'agit d'un exemple réel de calcul de la valeur efficace sans cycle dans une régression linéaire.
Il est vrai qu'il y a une petite erreur quelque part dans l'algorithme, ce qui fait que les trois lignes (centre, limites supérieure et inférieure du canal) sont décalées vers le haut.


 
Nikolai Semko:

Oui. C'est exact. Il s'agit d'un exemple réel de calcul de la valeur efficace sans cycle dans une régression linéaire.
Il est vrai qu'il y a une petite erreur quelque part dans l'algorithme, ce qui fait que les trois lignes (centre, limites supérieure et inférieure du canal) sont décalées vers le haut.


Et il n'y a que la moitié de l'écart qui s'additionne. Je l'ai fait une fois, pour tester un Conseiller Expert de trading pour avoir un alignement relatif à - Ask-Bid. Si vous définissez SPR=0, il n'y aura pas de décalage. Il ne comptera que sur les prix des offres.
 
danminin:
Que fait ce "no loop" pour vous ?

Votre code s'exécutera-t-il plus rapidement ?

Le seul calcul de la valeur efficace peut donner un gain d'environ 10 à 1 000 fois, selon la période.

 
ANG3110:
Et il n'y a que la moitié de l'écart ajouté. Je l'ai fait une fois pour tester un Conseiller Expert de trading pour avoir un alignement relatif à - Ask-Bid. Si nous définissons SPR=0, il n'y aura pas de décalage. Il ne comptera que sur les prix des offres.

Oui, exactement. Une correspondance complète avec mon implémentation de la régression linéaire.

 
Yousufkhodja Sultonov:


Comment se porte l'indicateur Sultonov ? A-t-il déjà cassé le dos du forex ou est-il en cours ?
 
Vladimir Baskakov:
Comment se porte l'indicateur Sultonov ? A-t-il déjà cassé le dos du forex ou est-il sur le point de le faire ?

L'indicateur fonctionne sur un compte réel d'un centime à l'UPU sur une base "run and forget" avec un dépôt de 48 c.u.. Le deuxième mois, il a oscillé autour de 50, apparemment en attendant son heure. Il est impossible de recevoir plus de 10 % par an sur le Forex, de manière stable et sans risque, à condition de réinvestir les bénéfices pendant de nombreuses années - telles sont mes conclusions sur l'épine dorsale du Forex. Les conclusions hâtives d'il y a 8 ans sont battues en brèche par la réalité du marché. Le puissant modèle de régression universel a échoué lamentablement, produisant des bénéfices bancables. L'URM fait un excellent travail sur tous les processus techniques, sociaux, miniers (extraction de l'or de minerais pauvres) et autres, à l'exception de l'élément marché. La conclusion est que les modèles de régression ont un potentiel limité pour extraire des bénéfices du marché.

Raison: