線形回帰の記述を支援する - ページ 4

 
アルゴリズムの性能差ではなく、計算速度の話なので、単純な関数を比較すればよいのです。添付の指標はあくまでも指標であり、その計算の妥当性がここで争点となる。単純な関数を、カスタムインジケータとして、またコード内で呼び出される関数として、2つの方法で実装する必要があります。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()呼び出しによるものです。
 
この例では、testが(コードに直接挿入されるのではなく)関数として呼び出されることと、testの内容が貧弱であること(配列処理がない)の2点が異なっていますね。ですから、iCustomを 使うべきかどうかという問いに対する答えは、まだ状況に依存するように見えます。
追伸:私の例では、2つのバリエーションで操作回数にそれほど本質的な違いはありません。「サービングコード」は一度だけ動作し、ループは同じです。
 
1.手続き型プログラミングは、モジュール型プログラミング、オブジェクト指向プログラミングに次ぐスタイルです。ですから、計算アルゴリズムを別の関数にするのは理にかなったことなのです。

また、なぜ組み込み関数で配列を扱う必要があるのでしょうか?コードに埋め込まれたカスタム関数と、iCustom()を通して呼び出された外部関数の呼び出しコストの差の話です。
 
Rosh:
1.手続き型プログラミングは、モジュール型プログラミング、オブジェクト指向プログラミングに次ぐスタイルです。ですから、計算アルゴリズムを別の関数にするのは理にかなったことなのです。

また、なぜ組み込み関数で配列を扱う必要があるのでしょうか?コードに埋め込まれたカスタム関数と、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秒です。 でも、コードを開発するのはずっと簡単です
 
線形回帰のパラメータを求めるというテーマで、さらに詳しくご紹介します。ここから引用 -Linear Regression Channel
 
Rosh:
ここでは、線形回帰のパラメータの求め方について詳しく説明します。ここから引用 - Linear Regression Channel

そして、説明したアルゴリズムを実装した関数がこちらです(もしかしたら誰かが使ってくれるかもしれません)。

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

このような関数が呼び出されます。

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

nX[nI]が棒グラフの場合、nIをインクリメントすると逆向きになることに注意:)

リーズナブル。

ボルト

 

デンマーク王国がおかしい

前の投稿を削除させていただきました。アルゴリズムにエラーがあります。

私は多くの人々がこの手順を使用することを知っているが、......エラーの理由を見つけることができないHELP ME。

以下はそのスクリプトです。A係数とB 係数は2回計算されます。

//+------------------------------------------------------------------+
//|                                                       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.333333 傾き = 5.00000000

切片 = -1102.16914108 傾き = 0.00000091

そして、こちらも同じく、MathCadで 計算したものです。青色は結果が一致し、赤色は一致しない(。

Mathcadでは組み込み関数なので、MT4ではエラーになる可能性が高いのですが、どこで?

ファイル:
scripts.rar  15 kb
 
Prival писал (а)>>

デンマーク王国がおかしい

前の投稿を削除させていただきました。アルゴリズムにエラーがあります。

私は多くの人々がこの手順を使用することを知っているが、......エラーの理由を見つけることができないHELP ME。

以下はそのスクリプトです。A係数とB 係数は2回計算されます。

結果は以下の通りです。

切片=-3.333333 傾き = 5.00000000

切片 = -1102.16914108 傾き = 0.00000091

そして、こちらも同じく、MathCadで 計算したものです。青色は結果が一致し、赤色は一致しない(。

これはMathcadの組み込み関数なので、MT4のエラーである可能性が高いのですが、どこが?

以下は、Excel 2007の表示です。




そのため、Matcadの確認が必要な場合があります。

 

線形回帰の実装の一つで、多項式の次数を20、計算点の数と開始点のオフセットを設定し...

出力はチャンネルの深さをポイントで設定し、深さ0では回帰曲線そのものを出力する

ファイル: