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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Dmitiry Ananiev
9282
Dmitiry Ananiev  

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

Как встроить его расчет в советник и получить данные на 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
Maxim Dmitrievsky
19164
Maxim Dmitrievsky  
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++; } }
Georgiy Merts
9182
Georgiy Merts  
Даже если не использовать ООП - я бы разбил код на ряд функций по смыслу. 
Nikolai Semko
6556
Nikolai Semko  

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

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


Rashid Umarov
Админ
16668
Rashid Umarov  

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

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

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

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

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

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

Nikolai Semko
6556
Nikolai Semko  
Yuriy Asaulenko:

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

улыбнуло ))
Yuriy Asaulenko
9360
Yuriy Asaulenko  
Nikolai Semko:
улыбнуло ))

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

Georgiy Merts
9182
Georgiy Merts  
Nikolai Semko:

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

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

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

Не верю !!!

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

Dmitry Fedoseev
56827
Dmitry Fedoseev  
Nikolai Semko:

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

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


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

Nikolai Semko
6556
Nikolai Semko  
Georgiy Merts:

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

Не верю !!!

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

Dmitry Fedoseev:

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

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

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

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

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