# Canale di regressione lineare

Ho un indicatore di regressione lineare.

Come costruire il suo calcolo nell'EA e ottenere dati su 0 bar o su 1.

Ho cercato di fare così:

```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 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);

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];```

Ma non dà qualcosa...

File:
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++; } }```

Anche se non usi OOP - romperei il codice in un certo numero di funzioni per dare un senso.

Ho implementato il calcolo della regressione (non solo lineare) senza cicli. Più precisamente, un ciclo è necessario solo una volta durante l'inizializzazione.
Di conseguenza, la velocità di calcolo è mille volte più veloce.

E il codice è più corto.
Ma mi dispiace, non posterò il codice. È un segreto.
Sto solo dicendo che è reale.

Ci sono due articoli che vi aiuteranno

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

Nikolai Semko:

Ho implementato il calcolo della regressione (non solo lineare) senza cicli. Per essere più precisi, il ciclo è necessario solo una volta all'inizializzazione.
Di conseguenza, la velocità di calcolo è mille volte più veloce.

E il codice è più corto.
Ma mi dispiace, non posterò il codice. È un segreto.
Sto solo dicendo che è reale.

Il codice è molto semplice. Aggiungiamo i quadrati attuali, sottraiamo i quadrati fuori dall'intervallo. Questo è tutto. Questo è tutto il segreto).

Può essere ancora più interessante, ma seguendo principi diversi.

Yuriy Asaulenko:

Il codice è molto semplice. Aggiungiamo i quadrati attuali, sottraiamo i quadrati fuori dall'intervallo. Questo è tutto. Questo è il segreto).

divertente )))

Nikolai Semko:
Questo è divertente ))

Per renderlo ancora più divertente, si potrebbe raccontare non del canale, ma di come fare una linea di regressione polinomiale senza cicli. Ma sicuramente non lo farò. Non ne hai bisogno.

Nikolai Semko:

Ho implementato il calcolo della regressione (non solo lineare) senza cicli. Più precisamente il ciclo è necessario solo una volta all'inizializzazione.
Di conseguenza, la velocità di calcolo è migliaia di volte più veloce.

E il codice è più corto.
Ma mi dispiace, non posterò il codice. È un segreto.
Sto solo dicendo che è reale.

Migliaia di volte più veloce, e senza un ciclo di valori di input?

Non ci credo!!!

Come minimo, un ciclo di parametri di input è obbligatorio!

Nikolai Semko:

Ho implementato il calcolo della regressione (non solo lineare) senza cicli. Più precisamente, il ciclo è necessario solo una volta all'inizializzazione.
Di conseguenza, la velocità di calcolo è mille volte più veloce.

E il codice è più corto.
Ma mi dispiace, non posterò il codice. È un segreto.
Sto solo dicendo che è reale.

E anche senza un ciclo di somma x*y? E se x e y non sono linee rette?

Georgiy Merts:

Migliaia di volte più veloce, e senza un ciclo di valori di input?

Non ci credo!!!

Almeno un ciclo sui parametri di ingresso è obbligatorio!

Dmitry Fedoseev:

E anche senza un ciclo di somma x*y ? E se x e y non sono linee rette?

Non crederci per tutto il suo valore.