선형 회귀 작성 도움말 - 페이지 4

 
알고리즘 연산의 차이가 아니라 연산 속도에 대한 이야기이기 때문에 간단한 함수를 비교할 필요가 있다. 첨부 된 지표는 여전히 지표이며 계산의 정확성은 여기에서 논쟁의 여지가 있습니다. 간단한 함수를 가져와서 두 가지 방식으로 구현해야 합니다. 사용자 지정 표시기와 코드에서 호출되는 함수입니다. 나는 이미 유사한 검사를 수행하고 그것에 대해 썼습니다 - MQL4의 지표 계산 속도에 대해

다음은 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 ) ;
  }
//+------------------------------------------------------------------+
다음은 테스트 알고리즘 계산 속도를 측정하는 스크립트입니다.

 //+------------------------------------------------------------------+
//|                                             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() 및 test() 호출을 통해.
 
예제에서 두 가지 차이점이 있습니다. 테스트가 함수로 호출되고(코드에 직접 삽입되지 않고) 테스트 내용이 더 열악합니다(배열에 대한 작업이 없음). 즉, iCustom 을 사용하는 것이 바람직하다는 질문에 대한 대답은 특정 상황에 따라 계속 달라집니다.
추신: 제 예에서는 두 가지 옵션에 대한 작업 수에 큰 차이가 없습니다. "서비스 코드"는 모두 한 번 작동하고 주기는 동일합니다.
 
1. 절차적 프로그래밍 스타일은 효율성 면에서 모듈형 및 객체 지향형 다음으로 두 번째입니다. 따라서 별도의 함수로 계산 알고리즘을 제거하는 것은 당연합니다.

2. 내장 함수에서 배열을 사용하는 이유는 무엇입니까? 코드에 내장된 커스텀 함수를 호출하는 비용과 iCustom ()을 통해 외부 함수를 호출하는 비용의 차이에 대해 이야기하고 있습니다.
 
Rosh :
1. 절차적 프로그래밍 스타일은 효율성 면에서 모듈형 및 객체 지향형 다음으로 두 번째입니다. 따라서 별도의 함수로 계산 알고리즘을 제거하는 것은 당연합니다.

2. 내장 함수에서 배열을 사용하는 이유는 무엇입니까? 코드에 내장된 커스텀 함수를 호출하는 비용과 iCustom ()을 통해 외부 함수를 호출하는 비용의 차이에 대해 이야기하고 있습니다.

1. 이것이 바로 대규모 프로젝트의 최종 효율성입니다. 다만 속도면에서 열등하다.
2. 유사하게. 내가 관심을 갖는 것은 최종 효율성입니다. MQL의 경우 일반적으로 개발 시간에 테스터의 테스트 시간을 더한 시간입니다. 실제 계정으로 터미널을 로드할 때 추가로 몇 초 동안 대기하는 것도 비용이 많이 들 수 있습니다. 신경의 측면에서 모든 사람이 거래에 대한 올바른 견해를 갖고 있는 것은 아닙니다. :)
 
다음은 차이점을 확인하는 스크립트입니다.
 //+------------------------------------------------------------------+
//|                                        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 ) ;
  }
//+------------------------------------------------------------------+

다음은 스크립트의 결과입니다.





보시다시피 별도의 기능을 사용하는 것은 매우 타당합니다. 10억 패스 주기의 시간 차이는 1초에 불과합니다. 그러나 코드를 개발하는 것이 훨씬 더 쉽습니다!
 
다음은 선형 회귀의 매개변수를 찾는 주제에 대한 자세한 내용입니다. 여기에서 가져옴 - 선형 회귀 채널
 
Rosh :
다음은 선형 회귀의 매개변수를 찾는 주제에 대한 자세한 내용입니다. 여기에서 가져옴 - 선형 회귀 채널

그리고 여기에 설명된 알고리즘을 구현하는 함수가 있습니다(누군가에게 유용할 수 있음).

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

함수는 다음과 같이 호출됩니다.

  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]가 막대 번호인 경우 nI 증분은 과거로 이어집니다! :)

문안 인사,

볼트

 

덴마크 왕국에 문제가 있습니다.

이전 게시물을 삭제해야했습니다. 알고리즘에 오류가 있습니다.

많은 분들이 이 절차를 사용하시는 것으로 알고 있습니다만.... HELP 오류의 원인을 찾을 수 없습니다.

여기 스크립트가 있습니다. 계수 A와 B 는 두 번 계산됩니다.

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

여기 결과가 있습니다

절편 = -3.33333333 기울기 = 5.00000000

절편 = -1102.16914108 기울기 = 0.00000091

여기에서도 MathCad 에서 계산됩니다. 파란색 - 결과 일치, 빨간색 - 아니요(.

matcad에서는 내장 함수이므로 MT4의 오류일 가능성이 높지만 어디에 있습니까?

파일:
scripts.rar  15 kb
 
Prival писал (а) >> 를 썼습니다.

덴마크 왕국에 문제가 있습니다.

이전 게시물을 삭제해야했습니다. 알고리즘에 오류가 있습니다.

많은 분들이 이 절차를 사용하시는 것으로 알고 있습니다만.... HELP 오류의 원인을 찾을 수 없습니다.

여기 스크립트가 있습니다. 계수 A와 B 는 두 번 계산됩니다.

결과는 다음과 같습니다.

절편 = -3.33333333 기울기 = 5.00000000

절편 = -1102.16914108 기울기 = 0.00000091

여기에서도 MathCad 에서 계산됩니다. 파란색 - 결과 일치, 빨간색 - 아니요(.

Matkad에서는 이러한 기능이 내장되어 있으므로 MT4의 오류일 가능성이 높지만 어디에 있습니까?

다음은 Excel 2007에서 생성한 것입니다.




따라서 Matkad를 확인해야 할 수도 있습니다.

 

선형 회귀의 구현 중 하나는 다항식의 차수가 20이고 계산 지점의 수와 시작점의 오프셋이 지정됩니다.

출력은 채널 깊이를 사용하여 수행됩니다. 깊이는 포인트로 설정됩니다. 깊이가 0이면 회귀 곡선 자체만 표시됩니다.

파일:
사유: