線形回帰チャネル

 

線形回帰の 指標を持っています。

EAにその計算を組み込み、0 barまたは1 barでデータを取得する方法。

こんな感じでやってみました。

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++; } }
 
たとえOOPを 使わないとしても - 私なら、コードをいくつかの関数に分割して意味を持たせます。
 

回帰計算(線形だけでなく)を全くサイクルなしで実装しています。より正確には、初期化時に一度だけ必要なサイクルである。
その結果、計算速度が1000倍速くなりました。

そして、コードも短くなりました。
でも、申し訳ありませんが、コードは掲載しません。それは秘密です。
それが現実だと言っているのです。


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

回帰の計算(線形だけでなく)を全くサイクルなしで実装しました。より正確には、ループは初期化時に一度だけ必要です。
その結果、計算速度が1000倍も速くなったのです。

そして、コードも短くなりました。
でも、申し訳ありませんが、コードは掲載しません。それは秘密です。
それが現実だと言っているのです。

コードはとてもシンプルです。現在の四角を足し、区間から四角を引いていく。それだけです。それが全ての秘訣です)

もっと面白いことができるのに、違う原理でやっている。

 
Yuriy Asaulenko:

コードはとてもシンプルです。現在の四角を足し、区間から四角を引いていく。それだけです。それが秘訣です)

面白い )))
 
Nikolai Semko:
それは面白いですね ))

さらに面白いのは、チャンネルのことではなく、サイクルのない多項回帰線の作り方について伝えることです。でも、絶対にそんなことはしない。必要ないでしょ。

 
Nikolai Semko:

回帰計算(線形だけでなく)を全くサイクルなしで実装しています。より正確には、このサイクルは初期化時に一度だけ必要である。
その結果、計算速度が数千倍も速くなりました。

そして、コードも短くなりました。
でも、申し訳ありませんが、コードは掲載しません。それは秘密です。
それが現実だと言っているのです。

数千倍高速化、入力値のループなし ?

信じられない!!!

最低限、入力パラメータのループは必須です !

 
Nikolai Semko:

回帰計算(線形だけでなく)を全くサイクルなしで実装しています。より正確には、ループは初期化時に一度だけ必要である。
その結果、計算速度が1000倍速くなりました。

そして、コードも短くなりました。
でも、申し訳ありませんが、コードは掲載しません。それは秘密です。
それが現実だと言っているのです。


また、x*yの和算ループがなくても?また、xとyが直線でない場合は?

 
Georgiy Merts:

数千倍高速化、入力値のループなし ?

信じられない!!!

少なくとも、入力パラメータに対するループは必須です !

ドミトリー・フェドセーエフ

また、x*yの和算ループがなくても ?xとyが直線でない場合はどうするか?

全力で信じてはいけない。
ラシードが記事を落とした。よく読んでみてください。そこには、別の記事へのリンクがあります。
https://www.mql5.com/ru/articles/270

中学1~8年生レベルの数学で頭を働かせれば、周期がなくても同じようにスライド平均だけでなく、標準偏差でチャンネルを求めることができるのです。1次(線形回帰)だけでなく、任意の次数の多項式に対して実装しています。 マーケットプレイスの体験版で体感してください。

HH 初期化時に一度だけループが必要だと書きました。

数千倍高速化 - これには標準偏差(チャンネル幅)の計算も含まれます。
理由: