MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 19

 
Andrey F. Zelinsky:

この誤りを正すには、何を、なぜ、どのようにカウントしているかという、計算式を理解する必要があります。

そうして初めて、アルゴリズムを練り上げ、誤差を なくすことができるのです。

計算式を理解せず、直感で計算すると、誤差はなくなるが、間違った計算をすることになる。

p.s. 何を計算しているのか詳しく説明し、コードを詳しくコメントし、そうすればあなたがどのようにエラーを修正するのかがわかるでしょう。


終値によるピアソンの相関係数を利用した指標が必要である。24本のバーの配列(私の場合は変数n)を取り、最初のバーから開始します - 2通貨分です。24本のバーの相関を計算する - 最初のバーで値を取得します。次に、24本の小節の相関を計算しますが、2本目からというように計算します。
1.終値の2次元配列(i要素、p次元)を取りました。
for(int i=1; i<n; i++)
      {
      for(int p=0; p<m; p++)
         {
         Price_CloseX[i][p]=iClose(sym_x, PERIOD_H1, i+p);
         Price_CloseY[i][p]=iClose(sym_y, PERIOD_H1, i+p);
        
         }
      }
2.各配列の終値の合計を計算します。
for(int i=1; i<n; i++)
      {    
      for(int p=0; p<m; p++)
         {  
         sum_x[i][p]=sum_x[i][p-1]+Price_CloseX[i][p];                                        
         sum_y[i][p]=sum_y[i][p-1]+Price_CloseY[i][p];
        
         }        
      }

3.各配列の24本の終値の平均値(n-1)

for(int i=1; i<n; i++)
      {    
      for(int p=0; p<m; p++)
         {      
         Mx[i][p]=sum_x[p+1][m-1]/(n-1);  
         My[i][p]=sum_y[p+1][m-1]/(n-1);
                
         }
       }

4. 各アレイの平均価格からの偏差値

for(int i=1; i<n; i++)
      {
      for(int p=0; p<m; p++)
         {
         dx[i][p]=Price_CloseX[i][p]-Mx[i][p];
         dy[i][p]=Price_CloseY[i][p]-My[i][p];
         }
      }

5.終値の平均値からの乖離の二乗

for(int i=1; i<n; i++)                                                                  
      {
      for(int p=0; p<m; p++)
         {
         dx2[i][p]=(dx[i][p]*dx[i][p]);
         dy2[i][p]=(dy[i][p]*dy[i][p]);
        
         }
      }

6.偏差の積、つまり通貨1の配列の各要素と通貨2の配列の同じ要素を掛け合わせたものです。
例:dx[1][0](通貨1)の値にdy[1][0](通貨2)を乗じる、dx[3][4]*dy[3][4]など。

for(int i=1; i<n; i++)                                                                  
      {
      for(int p=0; p<m; p++)
         {
         dxdy[i][p]=(dx[i][p]*dy[i][p]);
        
         }
      }  

7.偏差の二乗の和と偏差の積の和を計算する

for(int i=1; i<n; i++)                                                                  
      {
      for(int p=0; p<m; p++)
         {
         Edx2[i][p]=(Edx2[i-1][p]+dx2[i][p]);                                        
         Edy2[i][p]=(Edy2[i-1][p]+dy2[i][p]);
         Edxdy[i][p]=(Edxdy[i-1][p]+dxdy[i][p]);
         }
      }

8.さて、実際に相関係数をバッファに代入してみると

for(int p=0; p<m; p++)
         {
         Koef[p]=Edxdy[n-1][p]/sqrt(Edx2[n-1][p]*Edy2[n-1][p]);
         Buffer1[p]=Koef[p];
         }

__________________________________________________________________________________________
上に書いたように、エラーは配列のオーバーランです。同じコードで相関係数を計算するスクリプトでは、この係数を考慮します。

 
Timur1988:
property strictを書いたとき、コンパイラはfor()の各ループで「変数は型でなければならない」というエラーを発生させたので、各ループでint iとint pを書かなければなりませんでした。その後、コンパイラはエラーを出さなくなったが、その行はビルドされなかった。このとき、#property strictを削除すると、コンパイラは各ループで型宣言をする必要がなくなり、その行がビルドされるようになりました。

int i とint p は、init()の前に一度だけ宣言する必要があります。

このような行は、double Buffer1[]の前に書くことができます。

int i,p;

を削除してください。

#プロパティの厳密性を返す必要があります。

その後、再度コンパイルを実行します。

その後、エラーをチェックする

で、配列オーバーランの場合は、コードのどの行かを調べます(番号と行そのものに注目します)。先ほどは、コードの90行目でしたね。

このエラーは、配列に24個の値があり、24番目のインデックスを要求した場合、.はエラーになります。把握するようにしましょう。インデックス番号は0から始まり、例えばこの場合0,1,...23となります。

もし私たちが理解できないのなら、ここにこの行を投げて、私たちは考えるでしょう。

 
Renat Akhtyamov:

int i とint p は、init()の前に一度だけ宣言する必要があります。

"プログラミング地獄への道は、グローバル変数で 舗装されている"。S・マコーネル
 
Alexey Kozitsyn:
"プログラミング地獄への道は、グローバル 変数で舗装されている"。S・マコーネル
それがない方が難しい場合もありますが、問題の指標の場合はそうではありません。
 
Artyom Trishkin:
それがない方が難しい場合もありますが、問題の指標の場合はそうではありません。
そうですね、まったくなくても大丈夫な場合もありますね。しかし、この場合は違います。
 
Alexey Kozitsyn:
そうですね、まったくなくても大丈夫な場合もありますね。しかし、この場合は違います。

この場合、必要かつ十分な量以上のコードが書かれていることになります。

ちなみに、変数名が同じでも、各変数の前にtypeを書くこともできます・・・が、正しいコードの作り方ではありません。

 
Renat Akhtyamov:
この場合、必要以上にコードが書かれていることになります。
ページのスペースが足りなくならないように...。
 
Renat Akhtyamov:

ちなみに、変数名が同じでも、各変数の前にtypeを書くこともできます・・・が、これは正しいコードの作り方ではありません。

実際、私はそうしています。おそらく、あなたは助言されるべきではないでしょうが、おそらく、あなたはいくつかの問題に遭遇したときに、あなたの決定を再考するでしょう。
 
Alexey Kozitsyn:
実際に私はそうしています。おそらく、そうするように勧められることはないでしょうが、おそらく、何か問題が発生したときに、その決断を考え直すことになるでしょう。
for(int i=1; int i<int n; int i++)                                                                  
...
そうだろう?どういたしまして。
 
Renat Akhtyamov:

この場合、あなたは必要かつ十分な量のコードを書いています。

ちなみに、変数名が同じでも、各変数の前にtypeを書くこともできます・・・が、これは正しいコードの作り方ではありません。

すべての変数は独自のスコープを持っています。中括弧の中にも - そのスコープで宣言された変数には、別のスコープを - 中括弧の中にも。では、例えば、ループインデックス変数が重複せず、「i」のような変数名で十分であり、慣習となっていることが分かっている場合、なぜプログラムの様々な場所に異なる名前のループインデックス変数を作らなければならないのでしょうか。
理由: