Doğrusal regresyon yazmaya yardımcı olun - sayfa 4

 
Algoritmaların işleyişindeki farktan değil, hesaplama hızından bahsettiğimiz için basit fonksiyonları karşılaştırmamız gerekiyor. Ekli göstergeler, hesaplamalarının doğruluğu burada tartışılan hala göstergelerdir. Basit bir işlevi almanız ve onu iki şekilde uygulamanız gerekir - özel bir gösterge olarak ve kodda çağrılan bir işlev olarak. Ben zaten benzer bir kontrol yaptım ve bunun hakkında yazdım - MQL4'teki göstergeleri hesaplama hızı hakkında

İşte test.mq4 göstergesi

 //+------------------------------------------------------------------+
//|                                                         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 ) ;
  }
//+------------------------------------------------------------------+
ve işte test algoritmasını hesaplama hızını ölçen bir komut dosyası

 //+------------------------------------------------------------------+
//|                                             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 ) ;
  }
//+------------------------------------------------------------------+
iCustom() ve test() çağrısı yoluyla.
 
Örneklerde iki fark görüyorum: test bir fonksiyon olarak adlandırılıyor (doğrudan koda eklenmek yerine) ve testin içeriği daha zayıf (dizilerle çalışma yok). Yani, iCustom kullanmanın tavsiye edilebilirliği sorusunun cevabı, belirli duruma bağlı görünmeye devam ediyor.
PS Örneğimde, iki seçenek için işlem sayısında çok önemli bir fark yoktur - sonuçta "servis kodu" bir kez çalışır ve döngüler aynıdır.
 
1. Prosedürel programlama tarzı, verimlilik açısından yalnızca modüler ve nesne yönelimli olandan sonra ikinci sıradadır. Bu nedenle, hesaplama algoritmasının ayrı bir fonksiyona kaldırılması doğaldır.

2. Neden yerleşik bir işlevde dizilerle çalışmalısınız? Kodda yerleşik olarak bulunan özel bir işlevi çağırmanın ve iCustom () aracılığıyla harici bir işlevi çağırmanın maliyeti arasındaki farktan bahsediyoruz.
 
Rosh :
1. Prosedürel programlama tarzı, verimlilik açısından yalnızca modüler ve nesne yönelimli olandan sonra ikinci sıradadır. Bu nedenle, hesaplama algoritmasının ayrı bir fonksiyona kaldırılması doğaldır.

2. Neden yerleşik bir işlevde dizilerle çalışmalısınız? Kodda yerleşik olarak bulunan özel bir işlevi çağırmanın ve iCustom () aracılığıyla harici bir işlevi çağırmanın maliyeti arasındaki farktan bahsediyoruz.

1. Bu, büyük projeler için tam olarak nihai verimliliktir. Sadece hız açısından yetersiz.
2. Benzer şekilde. Beni ilgilendiren nihai sonuçtur. MQL durumunda, bu genellikle geliştirme süresi artı test cihazındaki test süresidir. Gerçek bir hesapla bir terminal yüklerken ekstra saniye beklemek de çok pahalıya mal olabilir. Sinirler açısından, herkes ticaret konusunda doğru görüşe sahip değil :)
 
İşte farkı kontrol etmek için bir komut dosyası.
 //+------------------------------------------------------------------+
//|                                        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 ) ;
  }
//+------------------------------------------------------------------+

Ve işte senaryonun sonuçları.





Gördüğünüz gibi, ayrı bir işlevin kullanımı oldukça haklı - bir milyar geçiş döngüsü için zaman farkı sadece bir saniyedir. Ama kodlamak ne kadar kolay!
 
İşte lineer regresyon parametrelerini bulma konusunda daha fazlası. Buradan alınan - Lineer Regresyon Kanalı
 
Rosh :
İşte lineer regresyon parametrelerini bulma konusunda daha fazlası. Buradan alınan - Lineer Regresyon Kanalı

Ve burada açıklanan algoritmayı uygulayan bir işlev var (belki birisi için kullanışlı olacaktır):

 void f LinearRegr ( 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 ;
}

Fonksiyon şöyle çağrılır:

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

nX[nI] çubuk sayılar ise, o zaman nI artışının geçmişe götürdüğünü unutmayın! :)

Saygılarımızla,

Volt

 

Danimarka Krallığı'nda bir şeyler ters gidiyor.

Bir önceki mesajımı silmek zorunda kaldım. Algoritmada bir hata var.

Birçok kişinin bu prosedürü kullandığını biliyorum ama .... YARDIM hatasının nedenini bulamıyorum.

İşte senaryo. A ve B katsayıları iki kez hesaplanır.

 //+------------------------------------------------------------------+
//|                                                       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 ;
}

İşte sonuç

kesişim = -3.33333333 eğim = 5.000000000

kesişim = -1102.16914108 eğim = 0.00000091

Ve burada da, ancak MathCad'de hesaplanmıştır. Mavi - sonuçlar eşleşir, kırmızı - hayır (.

Matcad'de bunlar yerleşik işlevlerdir, bu nedenle büyük olasılıkla MT4'te bir hata var ama nerede?

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

Danimarka Krallığı'nda bir şeyler ters gidiyor.

Bir önceki mesajımı silmek zorunda kaldım. Algoritmada bir hata var.

Birçok kişinin bu prosedürü kullandığını biliyorum ama .... YARDIM hatasının nedenini bulamıyorum.

İşte senaryo. A ve B katsayıları iki kez hesaplanır.

İşte sonuç

kesişim = -3.33333333 eğim = 5.000000000

kesişim = -1102.16914108 eğim = 0.00000091

Ve burada da, ancak MathCad'de hesaplanmıştır. Mavi - sonuçlar eşleşir, kırmızı - hayır (.

Matkad'da bunlar yerleşik işlevlerdir, bu nedenle büyük olasılıkla MT4'te bir hatadır, ancak nerede?

İşte Excel 2007'nin ürettiği şey




Bu nedenle, Matkad'ı kontrol etmeniz gerekebilir.

 

Lineer regresyon uygulamalarından biri olan polinomun derecesi 20'dir, hesaplama noktalarının sayısı ve başlangıç noktasının ofseti belirtilir.

çıkış, kanal derinliği noktalar olarak ayarlanarak gerçekleştirilir..derinlik 0 ise, sadece regresyon eğrisinin kendisi görüntülenir

Dosyalar: