Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 19

 
Andrey F. Zelinsky:

Чтобы эту ошибку исправить -- надо понимать вашу формулу -- что, зачем и как вы считаете.

И только тогда получится перебрать ваш алгоритм и устранить выход за пределы массива

Методом "тыка" и непониманием формулы -- вы устраните ошибку, но сделаете неправильным расчёт.

p.s. Распишите словами подробно что и зачем вы считаете -- можете подробно прокомментировать свой код -- и тогда поймём как надо исправить эту ошибку.


Нужен индикатор, который строится по значениям коэффициента корреляции по Пирсону по ценам закрытия. Берем массив из 24 баров (в моем случае это переменная n), начиная с первого бара - для 2х валют. Просчитаем корреляцию за 24 бара - получим значение на первом баре. Затем просчитываем корреляцию за 24 бара, но уже начиная со второго и так далее. 
1. Я взял двумерный массив по ценам закрытия(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;

в коде int убрать

#property strict нужно вернуть обратно

затем снова запустить компиляцию

затем посмотреть на ошибки при работе

затем, в случае выхода за границы массива, смотрим - в какой строке кода (номер интересует и сама строка). Раньше у Вас это была строка номер 90

Ошибка означает, что если у Вас в массиве 24 значения, а Вы запрашиваете 24-ый индекс, то ... это ошибка. Попробуйте разобраться в этом. Нумерация индекса начинается с нуля, т.е. в Вашем случа 0,1,...23.

если не можем понять - кидаем сюда эту строчку, будем думать

 
Renat Akhtyamov:

int i и int p достаточно объявить один раз - еще до init()

"Дорога в ад программирования вымощена глобальными переменными". С. Макконнелл.
 
Alexey Kozitsyn:
"Дорога в ад программирования вымощена глобальными переменными". С. Макконнелл.
Иногда без них сложнее, но не в случае с обсуждаемым индикатором.
 
Artyom Trishkin:
Иногда без них сложнее, но не в случае с обсуждаемым индикатором.
Согласен, иногда без них совсем не обойтись. Но не в данном случае.
 
Alexey Kozitsyn:
Согласен, иногда без них совсем не обойтись. Но не в данном случае.

В данном случае написано кода больше, чем необходимо и достаточно.

Кстати Вы тоже можете перед каждой переменной писать тип, даже если имя у переменной одно и то же...., однако это не есть верное построение кода.

 
Renat Akhtyamov:
В данном случае написано кода больше, чем нужно.
Смотрите, чтобы место на странице не кончилось...
 
Renat Akhtyamov:

Кстати Вы тоже можете перед каждой переменной писать тип, даже если имя у переменной одно и то же...., однако это не есть верное построение кода.

Вообще-то я так и делаю, Вам, видимо, этого советовать не стоит, но, возможно, Вы пересмотрите свое решение, когда столкнетесь с некоторыми проблемами.
 
Alexey Kozitsyn:
Вообще-то я так и делаю, Вам, видимо, этого советовать не стоит, но, возможно, Вы пересмотрите свое решение, когда столкнетесь с некоторыми проблемами.
for(int i=1; int i<int n; int i++)                                                                  
...
так??? Извольте.
 
Renat Akhtyamov:

В данном случае написано кода больше, чем необходимо и достаточно.

Кстати Вы тоже можете перед каждой переменной писать тип, даже если имя у переменной одно и то же...., однако это не есть верное построение кода.

У каждой переменной есть своя область видимости. Даже внутри фигурных скобок - своя область видимости для переменной, объявленной в этой области - внутри фигурных скобок. Так зачем мне, например, в разных местах программы плодить переменные индекса цикла с разными именами, если я знаю, что они не пересекаются, и достаточно, и привычно, использовать имя такой переменной как "i" ?
Причина обращения: