MQL4 및 MQL5에 대한 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 - 페이지 19

 
Andrey F. Zelinsky :

이 실수를 수정하려면 공식을 이해해야 합니다. 무엇을, 왜, 어떻게 생각해야 합니다.

그래야만 알고리즘을 반복하고 범위를 벗어난 배열 을 제거할 수 있습니다.

"포크"방법을 사용하고 공식을 오해하면 오류가 제거되지만 계산이 잘못됩니다.

ps 생각하는 내용과 이유를 자세히 설명하십시오. 코드에 대해 자세히 설명할 수 있습니다. 그러면 이 오류를 수정하는 방법을 이해할 수 있습니다.


종가에서 피어슨 상관 계수 값을 기반으로 하는 지표가 필요합니다. 우리는 2개의 통화에 대해 첫 번째 막대부터 시작하여 24개의 막대(내 경우에는 변수 n)의 배열을 사용합니다. 24개의 막대에 대한 상관 관계를 계산해 보겠습니다. 첫 번째 막대에서 값을 얻습니다. 그런 다음 24개의 막대에 대한 상관 관계를 계산하지만 두 번째 막대부터 시작하는 방식으로 시작합니다.
1. 종가(i 요소와 p 차원)로 2차원 배열을 가져왔습니다.
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;

코드에서 int 제거

#property strict를 반환해야 합니다.

그런 다음 다시 컴파일을 시작하십시오.

그런 다음 실행하는 동안 오류를 찾습니다.

그런 다음 배열의 경계를 넘어서는 경우 코드의 어느 줄을 봅니다(숫자는 줄 자체에도 관심이 있음). 이전에는 라인 번호가 90이었습니다.

오류는 배열에 24개의 값이 있고 24번째 인덱스를 요청하면 ...이 오류가 발생한다는 것을 의미합니다. 그것을 알아 내려고 노력하십시오. 인덱스 번호 매기기는 0부터 시작합니다. 귀하의 경우 0,1,...23.

우리가 이해할 수 없다면, 우리는 여기에 이 줄을 던집니다, 우리는 생각할 것입니다

 
Renat Akhtyamov :

int i와 int p를 한 번 선언하는 것으로 충분합니다. init() 이전에도

"프로그래밍 지옥으로 가는 길은 전역 변수로 포장되어 있습니다 ." S. 맥코넬.
 
Alexey Kozitsyn :
"프로그래밍 지옥으로 가는 길은 전역 변수로 포장되어 있습니다 ." S. 맥코넬.
때로는 그것들이 없으면 더 어렵지만 논의 된 지표의 경우에는 그렇지 않습니다.
 
Artyom Trishkin :
때로는 그것들이 없으면 더 어렵지만 논의 된 지표의 경우에는 그렇지 않습니다.
동의합니다. 때때로 당신은 그것들 없이는 전혀 할 수 없습니다. 하지만 이 경우에는 그렇지 않습니다.
 
Alexey Kozitsyn :
동의합니다. 때때로 당신은 그것들 없이는 전혀 할 수 없습니다. 하지만 이 경우에는 그렇지 않습니다.

이 경우 필요 이상으로 많은 코드가 작성됩니다.

그건 그렇고, 변수의 이름이 같더라도 각 변수 앞에 유형을 쓸 수도 있습니다. .... 하지만 이것은 올바른 코드 구성이 아닙니다.

 
Renat Akhtyamov :
이 경우 필요 이상으로 많은 코드가 작성됩니다.
페이지의 공간이 부족하지 않은지 확인하십시오...
 
Renat Akhtyamov :

그건 그렇고, 변수의 이름이 같더라도 각 변수 앞에 유형을 쓸 수도 있습니다. .... 하지만 이것은 올바른 코드 구성이 아닙니다.

이것은 실제로 내가 하는 일입니다. 아마도 이렇게 하는 것이 좋지 않을 것입니다. 그러나 몇 가지 문제가 발생하면 결정을 재고하게 될 것입니다.
 
Alexey Kozitsyn :
이것은 실제로 내가 하는 일입니다. 아마도 이렇게 하는 것이 좋지 않을 것입니다. 그러나 몇 가지 문제가 발생하면 결정을 재고하게 될 것입니다.
for ( int i= 1 ; int i< int n; int i++)                                                                  
...
그래서??? 제발.
 
Renat Akhtyamov :

이 경우 필요 이상으로 많은 코드가 작성됩니다.

그건 그렇고, 변수의 이름이 같더라도 각 변수 앞에 유형을 쓸 수도 있습니다. .... 하지만 이것은 올바른 코드 구성이 아닙니다.

각 변수에는 고유한 범위가 있습니다. 중괄호 안에도 - 이 범위에서 선언된 변수에 대한 자체 범위 - 중괄호 안에도 있습니다. 예를 들어, 교차하지 않고 "i"와 같은 변수의 이름을 사용하는 것이 충분하고 습관적이라는 것을 알고 있는데, 예를 들어 프로그램의 다른 위치에서 다른 이름을 가진 주기 인덱스 변수를 생성해야 하는 이유는 무엇입니까?