Help write a linear regression - page 4

 
Since we are talking about calculation speed and not about the difference in algorithm performance, we should compare simple functions. The attached indicators are still indicators, the validity of calculation of which is the point of contention here. We should take a simple function and implement it in two ways - as a custom indicator and as a function to be called in the code. I have already done and wrote about it - Aboutthe Calculation Speed of Indicators in MQL4.

Here is the indicator test.mq4

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/ru/"
 
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
 
extern int val=5;
//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----
   int    res_int=0,i;
   double res_double=0;
//----
   for(i=0;i<=10000000;i++)
     {
      res_int+=i*i;
      res_int++;
      res_double+=i*i;
      res_double++;
     }
   ExtMapBuffer1[0]=res_double;      
//----
   return(0);
  }
//+------------------------------------------------------------------+
Here is the script that measures the calculation speed of the test algorithm

//+------------------------------------------------------------------+
//|                                             CheckCustomSpeed.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
#property show_inputs
 
 
//+------------------------------------------------------------------+
//|  implemented Test functiom                                       |
//+------------------------------------------------------------------+
double test()
   {
   int    res_int=0,i;
   double res_double=0;
//----
   for(i=0;i<=10000000;i++)
     {
      res_int+=i*i;
      res_int++;
      res_double+=i*i;
      res_double++;
     }
   return(res_double);
   }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
  double Impl=test();
  double Custom=iCustom(NULL,0,"Test",5,0,0);
//----
   Print("Implemented retuns ",Impl,",   iCustom returns ",Custom,", diiff=",Impl-Custom);
   
//----
   int i,start,stop;
   //Measuring time for test function
   start=GetTickCount();
   for (i=0;i<100;i++) test();
   stop=GetTickCount();
   int testTime=(stop-start)/1000.0;
 
   //Measuring time for Custom function
   start=GetTickCount();
   for (i=0;i<100;i++) Custom=iCustom(NULL,0,"Test",i,0,0);
   stop=GetTickCount();
   int customTime=(stop-start)/1000.0;
   string text=StringConcatenate("Time for implemented function test() is ",testTime,"  seconds");
   text=StringConcatenate(text,"\n Time for custom function iCustom(\"test\") is ",customTime,"  seconds");
   Comment(text);
 
//----
   return(0);
  }
//+------------------------------------------------------------------+
through iCustom() and through test() call.
 
I see two differences in the examples: test is called as a function (rather than inserted directly into the code) and the content of test is poorer (no array handling). So, the answer to the question of whether iCustom should be used still looks situation-dependent.
P.S. In my example there is not so essential difference in number of operations for two variants - "serving code" works once, and loops are the same.
 
1. The procedural programming style is second only to modular and object-oriented programming. So, putting the computation algorithm into a separate function is a logical step.

And why should you work with arrays in a built-in function? We are talking about the difference in the cost of calling a custom function embedded into the code and an external function called through iCustom().
 
Rosh:
1. The procedural programming style is second only to modular and object-oriented programming. So, putting the computation algorithm into a separate function is a logical step.

And why should you work with arrays in a built-in function? We are talking about the difference in the cost of calling a custom function embedded into the code and an external function called through iCustom().

1. it is exactly the resulting efficiency for large projects. It is just inferior in terms of speed.
2. similarly. It is the final efficiency I'm interested in. In case of MQL, it is usually the time needed for development plus the time needed for testing in the tester. Although, the extra seconds of waiting for the terminal to load the real account may also be very expensive. I mean nerves, not everyone has the right view on trading :)
 
Here's a script to check the difference.
//+------------------------------------------------------------------+
//|                                        CheckCalculationSpeed.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/ru/"
 
#property show_inputs
 
 
//+------------------------------------------------------------------+
//|  implemented Test functiom                                       |
//+------------------------------------------------------------------+
double test()
   {
   int    res_int=0,i;
   double res_double=0;
//----
   for(i=0;i<=10000000;i++)
     {
      res_int+=i*i;
      res_int++;
      res_double+=i*i;
      res_double++;
     }
   return(res_double);
   }
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
  double Impl=test();
  double Custom=iCustom(NULL,0,"Test",5,0,0);
//----
   Print("Implemented retuns ",Impl,",   iCustom returns ",Custom,", diiff=",Impl-Custom);
   
//----
   int i,start,stop;
   //Measuring time for test function
   start=GetTickCount();
   for (i=0;i<100;i++) test();
   stop=GetTickCount();
   int testTime=(stop-start)/1000.0;
 
   //Measuring time for direct calculation
   int    res_int=0,j;
   double res_double=0;
 
   start=GetTickCount();
   for (j=0;j<100;j++) 
      {
      for(i=0;i<=10000000;i++)
        {
         res_int+=i*i;
         res_int++;
         res_double+=i*i;
         res_double++;
        }
     }     
   stop=GetTickCount();
   int customTime=(stop-start)/1000.0;
   string text=StringConcatenate("Time for implemented function test() is ",testTime,"  seconds");
   text=StringConcatenate(text,"\n Time for direct Calculation block  is ",customTime,"  seconds");
   Comment(text);
 
//----
   return(0);
  }
//+------------------------------------------------------------------+

And here are the results of the script.





As you can see, using a separate function is justified - the time difference for a billion passes cycle is only one second. But it is much easier to develop the code!
 
Here's more on the subject of finding linear regression parameters. Taken from here - Linear Regression Channel
 
Rosh:
Here is more on how to find parameters of a linear regression. Taken from here - Linear Regression Channel

And here's a function that implements the algorithm described (maybe someone can use it):

void fLinearRegr(int nX[], double dY[], int nN, double& dA, double& dB)
{ //*************************************************************************
  //  Аппроксимация до прямой:
  //
  //  dY[nI] = dA + dB * nX[nI] - общая формула прямой
  //  
  //  dB = (nN*dSumXY - dSumX*dSumY) / (nN*dSumX2 - dSumX*dSumX)
  //
  //  dA = (dSumY - dB*dSumX) / nN
  //
  //  dSumXY = nX[0]*dY[0] + nX[1]*dY[1] + ... + nX[nN-1]*dY[nN-1]
  //
  //  dSumX  = nX[0] + nX[1] + ... + nX[nN-1]
  //  
  //  dSumY  = dY[0] + dY[1] + ... + dY[nN-1]  
  //  
  //  dSumX2 = nX[0]*nX[0] + nX[1]*nX[1] + ... + nX[nN-1]*nX[nN-1]
  //    
  //  Функция  вычисляет  коэффициенты  аппроксимирующей прямой.     
  //  
  //  Входные параметры:
  //      nX  -   массив  целых чисел с нумерацией элементов от 0 до N-1.
  //              Содержит набор абсцисс, в которых известны значения функции.
  //      dY   -  массив  вещественных  чисел с нумерацией элементов от 0 до N-1.
  //              Содержит набор значений функции.
  //      nN   -  число точек. N>=1
  //                                  
  //  Выходные параметры:
  //      dA, dB - коэффициенты аппроксимирующей прямой y=a+b*x
  //
  //  Реализация функции: Volt ( voltair@inbox.ru ) 
  //*************************************************************************/
  double dSumXY=0.0, dSumX=0.0, dSumY=0.0, dSumX2=0.0;
  for (int nI=0; nI<nN; nI++)
  { // вычисляем dSumXY
    dSumXY = dSumXY + nX[nI]*dY[nI];
    // вычисляем dSumX
    dSumX  = dSumX  + nX[nI];
    // вычисляем dSumY
    dSumY  = dSumY  + dY[nI];
    // вычисляем dSumX2
    dSumX2 = dSumX2 + nX[nI]*nX[nI];
  }
  // вычисляем dB
  dB = (nN*dSumXY - dSumX*dSumY) / (nN*dSumX2 - dSumX*dSumX);
  // вычисляем dA
  dA = (dSumY - dB*dSumX) / nN;
}

The function is called like this:

  int nX[5];
  double dY[5];
  // . . .
  nX[0] = nBar;
  dY[0] = High[nBar]; 
  // . . .
  nX[4] = nBar+4;
  dY[4] = High[nBar+4]; 
  // . . .
  fLinearRegr(nX, dY, 5, dA, dB);

Note that if nX[nI] are bar numbers, then increment nI leads backwards! :)

Regards,

Volt

 

There issomething wrong in the Danish kingdom.

I had to delete my previous post. There is an error in the algorithm.

I know a lot of people use this procedure but .... can't find the reason for the error HELP me.

Here is the script. The A and B coefficients are calculated twice.

//+------------------------------------------------------------------+
//|                                                       LinReg.mq4 |
//|                                                    Привалов С.В. |
//|                                             Skype -> privalov-sv |
//+------------------------------------------------------------------+
#property copyright "Привалов С.В."
#property link      "Skype -> privalov-sv"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   int      N=6;                 // Размер массива
   double   Y[],X[],A=0,B=0;
   
  ArrayResize(X,N);
  ArrayResize(Y,N);
      
    for ( int i = 0; i < N; i ++ )
    {
    // массивы Y и X для проверки работоспособности
    // intercept = -3.33333333 slope = 5.00000000

    X[i]=i;
    Y[i]=i*i;
    }
  LinearRegr(X, Y, N, A, B);
  
  Print("intercept = ", DoubleToStr(A,8)," slope = ",DoubleToStr(B,8));
// вторая проверка
    X[0]=1216640160;
    X[1]=1216640100;
    X[2]=1216640040;
    X[3]=1216639980;
    X[4]=1216639920;
    X[5]=1216639860;
    
    Y[0]=1.9971;
    Y[1]=1.9970;    
    Y[2]=1.9967;
    Y[3]=1.9969;    
    Y[4]=1.9968;    
    Y[5]=1.9968;
    
    A=0;
    B=0;
    
  LinearRegr(X, Y, N, A, B);
  
  Print("intercept = ", DoubleToStr(A,8)," slope = ",DoubleToStr(B,8));
           
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| y(x)=A+B*x                                                       |
//| используються формулы https://forum.mql4.com/ru/10780/page4       |
//+------------------------------------------------------------------+

void LinearRegr(double X[], double Y[], int N, double& A, double& B)
{
      double sumY = 0.0, sumX = 0.0, sumXY = 0.0, sumX2 = 0.0;
      
    for ( int i = 0; i < N; i ++ )
    {
        sumY   +=Y[i];
        sumXY  +=X[i]*Y[i];
        sumX   +=X[i];
        sumX2  +=X[i]*X[i];
    }
   B=(sumXY*N-sumX*sumY)/(sumX2*N-sumX*sumX);
   A=(sumY-sumX*B)/N;
}

The result is as follows

intercept = -3.33333333 slope = 5.00000000

intercept = -1102.16914108 slope = 0.00000091

And here is the same, but calculated in MathCad. In blue the results match, in red they don't (.

In Mathcad these are built-in functions, so most likely an error in MT4, but where ?

Files:
scripts.rar  15 kb
 
Prival писал (а) >>

There issomething wrong in the Danish kingdom.

I had to delete my previous post. There is an error in the algorithm.

I know a lot of people use this procedure but .... can't find the reason for the error HELP me.

Here is the script. The A and B coefficients are calculated twice.

The result is as follows

intercept = -3.33333333 slope = 5.00000000

intercept = -1102.16914108 slope = 0.00000091

And here is the same, but calculated in MathCad. In blue the results match, in red they don't (.

This is a built-in function in Mathcad, so most likely an error in MT4, but where ?

Here is what Excel 2007 shows




So, it may be necessary to check Matcad.

 

One of the linear regression implementations, the degree of polynomial is 20, the number of calculation points and the offset of the starting point is set...

output is done using a channel depth is set in points... at a depth of 0 only the regression curve itself is output

Files: