Канал линейной регрессии

 

Есть индикатор линейной регрессии

Как встроить его расчет в советник и получить данные на 0 баре или на 1. 

Пытался сделать вот так: 

enum ENUM_Polynomial
  {
   linear=1,      // linear 
   parabolic=2,   // parabolic 
   Third_power=3, // third-power 
  };
input ENUM_Polynomial degree=linear;
input double kstd=2.0;
input int bars=250;
input int shift=0;

double Ask,Bid;
double h,l;
double sqh_buffer[];
double fx_buffer[];
double sql_buffer[];
double close[];

double ai[10,10],b[10],x[10],sx[20];
double sum;
int p,n,f;
double qq,mm,tt;
int ii,jj,kk,ll,nn;
double sq;

int i0=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   
   ArrayResize(fx_buffer,1000);
   ArrayResize(sqh_buffer,1000);
   ArrayResize(sql_buffer,1000);
   
   ArraySetAsSeries(fx_buffer,true);
   ArraySetAsSeries(sqh_buffer,true);
   ArraySetAsSeries(sql_buffer,true);
   
   ArrayResize(close,1000);
   ArraySetAsSeries(close,false);
   
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol,Tick);

   Ask = Tick.ask;
   Bid = Tick.bid;
   
   
   iStdev
   for (int i =0; i<1000;i++)
   {
     // Print (i, "   ",ArraySize(close)); 
    close[i] = iClose(_Symbol,0,0);
   }
   
  // ArraySetAsSeries(close,true);
   int mi;
   p=bars;
   sx[1]=p+1;
   nn=degree+1;
   
   //--- sx 
   for(mi=1;mi<=nn*2-2;mi++)
     {
      sum=0;
      for(n=i0;n<=i0+p;n++)
        {
         sum+=MathPow(n,mi);
        }
      sx[mi+1]=sum;
     }
//--- syx 
   for(mi=1;mi<=nn;mi++)
     {
      sum=0.00000;
      for(n=i0;n<=i0+p;n++)
        {
         if(mi==1)
            sum+=close[n];
         else
            sum+=close[n]*MathPow(n,mi-1);
        }
      b[mi]=sum;
     }
//--- Matrix 
   for(jj=1;jj<=nn;jj++)
     {
      for(ii=1; ii<=nn; ii++)
        {
         kk=ii+jj-1;
         ai[ii,jj]=sx[kk];
        }
     }
//--- Gauss 
   for(kk=1; kk<=nn-1; kk++)
     {
      ll=0;
      mm=0;
      for(ii=kk; ii<=nn; ii++)
        {
         if(MathAbs(ai[ii,kk])>mm)
           {
            mm=MathAbs(ai[ii,kk]);
            ll=ii;
           }
        }
     
      if(ll!=kk)
        {
         for(jj=1; jj<=nn; jj++)
           {
            tt=ai[kk,jj];
            ai[kk,jj]=ai[ll,jj];
            ai[ll,jj]=tt;
           }
         tt=b[kk];
         b[kk]=b[ll];
         b[ll]=tt;
        }
      for(ii=kk+1;ii<=nn;ii++)
        {
         qq=ai[ii,kk]/ai[kk,kk];
         for(jj=1;jj<=nn;jj++)
           {
            if(jj==kk)
               ai[ii,jj]=0;
            else
               ai[ii,jj]=ai[ii,jj]-qq*ai[kk,jj];
           }
         b[ii]=b[ii]-qq*b[kk];
        }
     }
   x[nn]=b[nn]/ai[nn,nn];
   for(ii=nn-1;ii>=1;ii--)
     {
      tt=0;
      for(jj=1;jj<=nn-ii;jj++)
        {
         tt=tt+ai[ii,ii+jj]*x[ii+jj];
         x[ii]=(1/ai[ii,ii])*(b[ii]-tt);
        }
     }
//---
   for(n=i0;n<=i0+p;n++)
     {
      sum=0;
      for(kk=1;kk<=degree;kk++)
        {
         sum+=x[kk+1]*MathPow(n,kk);
        }
      fx_buffer[n]=x[1]+sum;
     }
//--- Std 
   sq=0.0;
   for(n=i0;n<=i0+p;n++)
     {
      sq+=MathPow(close[n]-fx_buffer[n],2);
     }
   sq=MathSqrt(sq/(p+1))*kstd;

   for(n=i0;n<=i0+p;n++)
     {
      sqh_buffer[n]=fx_buffer[n]+sq;
      sql_buffer[n]=fx_buffer[n]-sq;
     }
     
     h = sqh_buffer[
0];
     l = sql_buffer[0];

Но что-то не то выдает...

Файлы:
i-Regr.mq5  12 kb
 
void calcPolynomialRegression(double &PricesArray[],double &RegressionArray[], int power) {
 ArrayResize(RegressionArray, ArraySize(PricesArray)); ArraySetAsSeries(RegressionArray,ArrayGetAsSeries(PricesArray));
 double summ_x_value[21],summ_y_value[11],constant[11],matrix[11][11];
 ArrayInitialize(summ_x_value,0); ArrayInitialize(summ_y_value,0);
 ArrayInitialize(constant,0); ArrayInitialize(matrix,0);

 double summ=0,summ_x=0,summ_y=0;
 int pos=ArraySize(PricesArray)-1;
 summ_x_value[0]=ArraySize(PricesArray);
 for(int exp_n=1; exp_n<=2*power; exp_n++) {
  summ_x=0;
  summ_y=0;
  for(int k=1; k<=ArraySize(PricesArray); k++) {
   summ_x+=MathPow(k,exp_n);
   if(exp_n==1) summ_y+=PricesArray[pos-k+1];
   else if(exp_n<=power+1) summ_y+=PricesArray[pos-k+1]*MathPow(k,exp_n-1); }
  summ_x_value[exp_n]=summ_x;
  if(summ_y!=0) summ_y_value[exp_n-1]=summ_y; }

 for(int row=0; row<=power; row++)
  for(int col=0; col<=power; col++)
    matrix[row][col]=summ_x_value[row+col];

 int initial_row=1;
 int initial_col=1;
 for(int i=1; i<=power; i++) {
  for(int row=initial_row; row<=power; row++) {
   summ_y_value[row]=summ_y_value[row]-(matrix[row][i-1]/matrix[i-1][i-1])*summ_y_value[i-1];
   for(int col=initial_col; col<=power; col++)
     matrix[row][col]=matrix[row][col]-(matrix[row][i-1]/matrix[i-1][i-1])*matrix[i-1][col]; }
   initial_col++;
   initial_row++; }
   
 int j=0;
 for(int i=power; i>=0; i--) {
  if(j==0) constant[i]=summ_y_value[i]/matrix[i][i];
  else {
   summ=0;
   for(int k=j; k>=1; k--) summ+=constant[i+k]*matrix[i][i+k];
   constant[i]=(summ_y_value[i]-summ)/matrix[i][i]; }
  j++; }
  
 int k=1;
 for(int i=ArraySize(PricesArray)-1; i>=0; i--) {
  summ=0;
  for(int n=0; n<=power; n++) summ+=constant[n]*MathPow(k,n);
  RegressionArray[i]=summ;
  k++; } }
 
Даже если не использовать ООП - я бы разбил код на ряд функций по смыслу. 
 

я реализовал расчет регрессии (не только линейной) вообще без циклов. Точнее цикл нужет только один раз при инициализации. 
В результате скорость расчета в тысячи раз быстрее.

и код  короче. 
Но прошу прощения, код не выложу. Секрет.
Просто говорю, что это реально.


 

Есть две статьи, они помогут

Пример разработки спредовой стратегии на фьючерсах Московской биржи
Пример разработки спредовой стратегии на фьючерсах Московской биржи
  • www.mql5.com
MetaTrader 5 позволяет разрабатывать и тестировать роботов, торгующих одновременно на нескольких инструментах. Встроенный в платформу тестер стратегий автоматически скачивает с торгового сервера брокера тиковую историю и учитывает спецификацию контрактов  —  разработчику ничего не нужно делать руками. Это позволяет легко и максимально...
 
Nikolai Semko:

я реализовал расчет регрессии (не только линейной) вообще без циклов. Точнее цикл нужет только один раз при инициализации. 
В результате скорость расчета в тысячи раз быстрее.

и код  короче. 
Но прошу прощения, код не выложу. Секрет.
Просто говорю, что это реально.

Код оч прост. Прибавляем текущие квадраты, вычитаем выходящие из интервала. Все. Весь секрет.)

Можно еще интересней сделать, но на других принципах.

 
Yuriy Asaulenko:

Код оч прост. Прибавляем текущие квадраты, вычитаем выходящие из интервала. Все. Весь секрет.)

улыбнуло ))
 
Nikolai Semko:
улыбнуло ))

Чтобы совсем смешно стало, можно было бы рассказать не о канале, а о том, как линию полином регрессии без циклов сделать. Но, вот это точно не буду делать.)) Это вам ни к чему.

 
Nikolai Semko:

я реализовал расчет регрессии (не только линейной) вообще без циклов. Точнее цикл нужет только один раз при инициализации. 
В результате скорость расчета в тысячи раз быстрее.

и код  короче. 
Но прошу прощения, код не выложу. Секрет.
Просто говорю, что это реально.

В тысячи раз быстрее, и без цикла перебора входных значений ???

Не верю !!!

Как минимум, цикл перебора входных параметров обязательно требуется !

 
Nikolai Semko:

я реализовал расчет регрессии (не только линейной) вообще без циклов. Точнее цикл нужет только один раз при инициализации. 
В результате скорость расчета в тысячи раз быстрее.

и код  короче. 
Но прошу прощения, код не выложу. Секрет.
Просто говорю, что это реально.


И даже без цикла суммирования x*y? А если x и y не прямые линии?

 
Georgiy Merts:

В тысячи раз быстрее, и без цикла перебора входных значений ???

Не верю !!!

Как минимум, цикл перебора входных параметров обязательно требуется !

Dmitry Fedoseev:

И даже без цикла суммирования x*y? А если x и y не прямые линии?

Не верьте на здоровье.
Рашид же сбросил статьи. Читаем внимательно. Там есть ссылка еще на одну статью:
https://www.mql5.com/ru/articles/270

если поднапрячь мозги на уровне математики 7-8 класса, то аналогичным способом без цикла можно получать среднеквадратичное отклонение для получения канала, а не только скользящей. У меня это реализовано для полинома любой степени, а не только первой (линейная регрессия). Можете пощупать в демо версии на маркете. 

ЗЫ Я писал, что цикл нужен один раз при инициализации. 

В тысячи раз быстрее - это с учетом расчета величины среднеквадратического отклонения (т.е. ширины канала)