Канал линейной регрессии - страница 17

 

Я охотно верю, что можно сделать очень многие функции с ускоренным расчетом. Типа отнять от конца периода значение и прибавить к началу новое значение, без цикла.

В частности вот пример как можно без цикла посчитать несколько видов фильтра от простой машки до линейной регрессии, без цикла.

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

Здесь при N=0 - обычная SMA, N=1 - линейно-взвешанная, N=3 - линейная регрессия. А также можно получить промежуточные значения, поскольку N - дробная. СКО я тоже считал подобным способом. Думаю и полиномиальную регрессию можно сделать так же. Была бы практическая необходимость. По крайней мере мне пока не удалось использовать полиномиальную регрессию в прибыльных советниках. Каналы на ЕМА-шке как то проще и практически хорошо работают.

Вот тут немного навороченный вариант линейной регрессии на mq4 с СКО без циклов. Цикл есть один раз при инициации или точнее расчете первого заначения и все, - потом только суммы и разности. Считает конечно во много раз быстрее, чем с циклами.  Одна тонкость, что период задан в часах и пересчитывается при переключении таймфрейма.

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

Почему Федосеев самоудалился, рассуждая правильно?

Потому что рассуждал неправильно. 
Читайте ветку.

 
А что это "без цикла" вам дает?

На много это ускоряет выполнение кода?
 
danminin:
А что это "без цикла" вам дает?

На много это ускоряет выполнение кода?
Вообще-то намного. Я раньше измерял при помощи GetTickCount(). Но это хорошо заметно когда нужно делать большое количество оптимизаций. Одно дело когда считаешь несколько часов кучу вариантов, другое дело за несколько десятков или единиц минут. Но это обычно редко нужно. Поэтому можно с этим особо не заморачиваться.
 
ANG3110:

Я охотно верю, что можно сделать очень многие функции с ускоренным расчетом. Типа отнять от конца периода значение и прибавить к началу новое значение, без цикла.

В частности вот пример как можно без цикла посчитать несколько видов фильтра от простой машки до линейной регрессии, без цикла.

Здесь при N=0 - обычная SMA, N=1 - линейно-взвешанная, N=3 - линейная регрессия. А также можно получить промежуточные значения, поскольку N - дробная. СКО я тоже считал подобным способом. Думаю и полиномиальную регрессию можно сделать так же. Была бы практическая необходимость. По крайней мере мне пока не удалось использовать полиномиальную регрессию в прибыльных советниках. Каналы на ЕМА-шке как то проще и практически хорошо работают.

Вот тут немного навороченный вариант линейной регрессии на mq4 с СКО без циклов. Цикл есть один раз при инициации или точнее расчете первого заначения и все, - потом только суммы и разности. Считает конечно во много раз быстрее, чем с циклами.

Да. Все верно. Это реальный пример безциклового расчета СКО в линейной регрессии. 
Правда в алгоритме где-то маленькая ошибка, ведущая к сдвижке всех трех линий (центральная, верхняя и нижняя границы канала) вверх.  


 
Nikolai Semko:

Да. Все верно. Это реальный пример безциклового расчета СКО в линейной регрессии. 
Правда в алгоритме где-то маленькая ошибка, ведущая к сдвижке всех трех линий (центральная, верхняя и нижняя границы канала) вверх.  


А там просто пол спреда прибавлено. Это я когда-то делал, для проверки торгового советника, чтобы была центровка относительно - Ask-Bid. Там если поставить SPR=0, то смещения не будет. Будет считать чисто по бидовым ценам.
 
danminin:
А что это "без цикла" вам дает?

На много это ускоряет выполнение кода?

только за счет расчета СКО выйгрыш примерно в 10-1000 раз в зависимости от периода.

 
ANG3110:
А там просто пол спреда прибавлено. Это я когда-то делал, для проверки торгового советника, чтобы была центровка относительно - Ask-Bid. Там если поставить SPR=0, то смещения не будет. Будет считать чисто по бидовым ценам.

да, точно. Полное совпадение с моей реализацией по линейной регрессии.

 
Yousufkhodja Sultonov:


Как там индикатор Султонова поживает,? Сломал хребет форексу уже или в процессе?
 
Vladimir Baskakov:
Как там индикатор Султонова поживает,? Сломал хребет форексу уже или в процессе?

Индикатр работает на одном центовом реальном счете на ВПС по принципу "запустил и забыл" с депозитом в 48 у.е.. Второй месяц болтается вокруг 50-ти, видимо, ждет своего часа. На Форексе невозможно стабильно и без риска получать свыше 10-ти %-тов годовых при условии реинвестирования прибыли за долгие годы - вот мои выводы на счет хребта Форекса. Скоропалительные выводы 8-ми летней давности разбиты реальностью рынка. Мощнейшая универсальная регрессионная модель не справилась с задачей, выдавая банковский профит. УРМ отлично справляется со всеми процессами технического, социального, горного (извлечение золота из бедных руд) и прочих процессо, кроме рыночной стихии. Вывод - регрессионные модели имеют ограниченный потенциал в вопросах  извлечения прибыли с рынка.