Canal de regresión lineal - página 17

 

Creo de buen grado que es posible hacer muchas funciones con cálculo acelerado. Como restar un valor al final de un período y añadir un nuevo valor al principio, sin un ciclo.

En particular, aquí hay un ejemplo de cómo se pueden calcular varios tipos de filtro, desde la simple ondulación hasta la regresión lineal sin 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);
}
//********************************************************************

Aquí en N=0 - SMA normal, N=1 - ponderado lineal, N=3 - regresión lineal. Y también se pueden obtener valores intermedios ya que N es fraccionario. También calculé el RMS de forma similar. Creo que la regresión polinómica puede hacerse de la misma manera. Sería una necesidad práctica. Al menos, aún no he conseguido utilizar la regresión polinómica en Asesores Expertos rentables. Los canales en las EMA son más sencillos y funcionan bien en la práctica.

He aquí una variante ligeramente artificiosa de la regresión lineal en mq4 con RMS sin ciclo. Hay un ciclo una vez al inicio, o más exactamente, al calcular el primer conjunto de valores, y eso es todo, - luego sólo hay sumas y diferencias. Por supuesto, es mucho más rápido que con los ciclos. Una sutileza es que el periodo se especifica en horas y se recalcula al cambiar de marco temporal.

#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 qué Fedoseyev se ha autodirigido, razonando correctamente?

Porque razonó incorrectamente.
Lee el hilo.

 
¿Qué hace el "no loop" por ti?

¿Cuánto acelera la ejecución del código?
 
danminin:
¿Qué hace el "no loop" por ti?

¿Cuánto más rápido hace funcionar su código?
Mucho, en realidad. Lo medía con GetTickCount(). Pero se nota mucho cuando hay que hacer muchas optimizaciones. Una cosa es cuando hay que contar muchas variantes durante varias horas, y otra cosa es cuando hay que hacerlo en varias decenas o unidades de minutos. Pero rara vez es necesario. Por eso, es posible que no se moleste demasiado en ello.
 
ANG3110:

Creo de buena gana que es posible hacer muchas funciones con cálculo acelerado. Como restar un valor al final de un período y añadir un nuevo valor al principio, sin un ciclo.

En particular, aquí hay un ejemplo de cómo se pueden calcular varios tipos de filtro, desde la simple ondulación hasta la regresión lineal, sin ciclo.

Aquí en N=0 - SMA normal, N=1 - ponderado lineal, N=3 - regresión lineal. Y también se pueden obtener valores intermedios ya que N es fraccionario. También calculé el RMS de forma similar. Creo que la regresión polinómica puede hacerse de la misma manera. Sería una necesidad práctica. Al menos, aún no he conseguido utilizar la regresión polinómica en Asesores Expertos rentables. Los canales en las EMA son más sencillos y funcionan bien en la práctica.

Aquí hay una variante ligeramente modificada de la regresión lineal en mq4 con RMS sin bucles. Hay un ciclo una vez al inicio, o más exactamente, al calcular la primera lectura, y eso es todo - luego sólo hay sumas y diferencias. Por supuesto, calcula muchas veces más rápido que con los ciclos.

Sí. Eso es correcto. Este es un ejemplo real de cálculo de RMS sin ciclos en la regresión lineal.
Es cierto que hay un pequeño error en alguna parte del algoritmo, que hace que las tres líneas (límites central, superior e inferior del canal) se desplacen hacia arriba.


 
Nikolai Semko:

Sí. Eso es correcto. Este es un ejemplo real de cálculo de RMS sin ciclos en la regresión lineal.
Es cierto que hay un pequeño error en alguna parte del algoritmo, que hace que las tres líneas (límites central, superior e inferior del canal) se desplacen hacia arriba.


Y ahí está sólo la mitad de la extensión sumada. Hice esto una vez, para probar un Asesor Experto de comercio para tener la alineación relativa a - Ask-Bid. Si se establece SPR=0, no habrá desplazamiento. Contará únicamente con los precios de las ofertas.
 
danminin:
¿Qué hace este "no loop" por ti?

¿Cuánto más rápido hace funcionar su código?

El cálculo del valor eficaz por sí solo puede dar una ganancia de entre 10 y 1.000 veces, según el periodo.

 
ANG3110:
Y sólo se ha añadido la mitad de la extensión. Hice esto una vez para probar un Asesor Experto de comercio para tener la alineación relativa a - Ask-Bid. Si ponemos SPR=0, no habrá desplazamiento. Contará únicamente con los precios de las ofertas.

Sí, exactamente. Una completa coincidencia con mi implementación de regresión lineal.

 
Yousufkhodja Sultonov:


¿Cómo va el indicador Sultonov? ¿Ha roto ya la parte trasera del forex o está en proceso?
 
Vladimir Baskakov:
¿Cómo va el indicador Sultonov? ¿Ha roto ya la espalda del forex o está en proceso de hacerlo?

El indicador funciona con una cuenta real de un céntimo en la UPU sobre la base de "correr y olvidar" con un depósito de 48 c.u. El segundo mes ha estado rondando los 50, aparentemente, esperando su momento. Es imposible recibir más del 10% anual en Forex, de forma estable y sin riesgo, siempre que se reinviertan los beneficios durante muchos años - estas son mis conclusiones sobre la columna vertebral de Forex. Las conclusiones apresuradas de hace 8 años quedan destrozadas por la realidad del mercado. El poderoso modelo de regresión universal ha fracasado estrepitosamente, produciendo beneficios bancarios. La URM hace un gran trabajo en todos los procesos técnicos, sociales, mineros (extracción de oro de minerales pobres) y otros, excepto el elemento de mercado. La conclusión es que los modelos de regresión tienen un potencial limitado para extraer beneficios del mercado.