Скачать MetaTrader 5

Ишю формулу (алгоритм)

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Нужен торговый робот? Закажи его в сервисе Фриланс!
Prival
4548
Prival 2010.05.04 00:32 

Ищу итерационную формулу расчета коэффициента корреляции или готовый алгоритм.

Есть вот такая процедура (https://ru.wikipedia.org/wiki/Корреляция)

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 10.05.2008                                                     |
//|  Описание : Возвращает корреляцию двух рядов.                              |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    x - массив значений первого ряда                                        |
//|    y - массив значений второго ряда                                        |
//+----------------------------------------------------------------------------+
double Correlation(double& x[], double& y[]) {
  double co=0, sa=0, sb=0, sc=0, xs=0, ys=0;
  int    i, k=MathMin(ArraySize(x), ArraySize(y));

  if (k>0) {
    for (i=0; i<k; i++) {
      xs+=x[i]; ys+=y[i];
    }
    xs/=k; ys/=k;
    for (i=0; i<k; i++) {
      sa+=(x[i]-xs)*(y[i]-ys);
      sb+=(x[i]-xs)*(x[i]-xs);
      sc+=(y[i]-ys)*(y[i]-ys);
    }
    sb=MathSqrt(sb*sc);
    if (sb!=0) co=sa/sb;
  }
  return(co);
} 

Но при больших массивах комп тормозит. Есть ли более быстрые алгоритмы ?

Заранее Спасибо.

timbo
3139
timbo 2010.05.04 00:40  
Вместо первого цикла можно использовать встроенную функцию MA on Array. Вместо вычислений sc и sb - StD on Array. Функции для ковариации, к сожалению нет, всё равно приходится считать в цикле.
Evgeniy Logunov
716
Evgeniy Logunov 2010.05.04 00:45  
Prival писал(а) >>

Ищу итерационную формулу расчета коэффициента корреляции или готовый алгоритм.



Ю.П. Лукашин "Адаптивные методы краткосрочного прогнозирования временных рядов" М. "Финансы и статистика", 2003.
Там кое-что есть на счет итерационного вычисления коэффициента корреляции. Правда нужно проверять, подходит ли предложенный там алгоритм под ваши нужды, т.к. он весьма необычен.

keekkenen
1135
keekkenen 2010.05.04 00:47  
Пирсона можно попробовать, не сильно быстрее будет
double Pearson(double arr1[], double arr2[],int count, int startIndex=0){
   double sumXY = 0, sumX = 0, sumY = 0,sumXs = 0, sumYs = 0, res = 0;     
   
   for(int i = startIndex; i < count + startIndex; i++){
      sumXY += arr1[i] * arr2[i];
      sumX += arr1[i];
      sumY += arr2[i];
      sumXs += arr1[i] * arr1[i];
      sumYs += arr2[i] * arr2[i];     
   }    
   res = NormalizeDouble( (count * sumXY - sumX * sumY) /
                                    MathSqrt( (count * sumXs - sumX * sumX) *
                                    (count * sumYs - sumY * sumY) ),8);       
   return(res);
}
Avals
3183
Avals 2010.05.04 05:10  

Здесь есть через БПФ https://www.mql5.com/go?link=http://dmilvdv.narod.ru/SpeechSynthesis/index.html?correlation.html
Вроде реализовано на mql здесь: https://www.mql5.com/ru/code/9696
void fastcorellation(double& signal[], int signallen, double& pattern[], int patternlen);

Prival
4548
Prival 2010.05.04 07:07  

Спасибо за помощь, но

Avals

Использование БПФ накладывает ограничение на длину массива, должен быть кратен 2^n, но даже в этом случае он медленнее.

Keekkenen

Алгоритмов где есть вот такое sumX * sumY старайся избегать там есть подводный камень, вот тут эти грабли показаны

https://www.mql5.com/ru/forum/107476/page46#101579

https://www.mql5.com/ru/forum/107017/page5

lea

спасибо буду рыться.

timbo

спасибо за идею попробую, пусть это и не кардинальное решение, но хоть чуть быстрее будет и то лучше.

 

З.Ы. задача вроде бы проста, пришла новая котировка, в одном из массивов измениться только первый элемент, остальные сдвинуться (последний элемент ушол), и из-за этого пересчитывать КК по новой ((. Как то не эффективно, должно быть что то. более быстрое…

PapaYozh
3768
PapaYozh 2010.05.04 08:00  

З.Ы. задача вроде бы проста, пришла новая котировка, в одном из массивов измениться только первый элемент, остальные сдвинуться (последний элемент ушол), и из-за этого пересчитывать КК по новой ((. Как то не эффективно, должно быть что то. более быстрое…


Не надо на каждом тике гонять циклы по пересчету сумм.
Надо вычитать 1-ый элемент суммы и добавлять новый последний.
Полностью суммы надо пересчитывать периодически, иначе погрешность копится.

Candid
1630
Candid 2010.05.04 08:45  
Prival >>:
Использование БПФ накладывает ограничение на длину массива, должен быть кратен 2^n, но даже в этом случае он медленнее.

Это очень странно, должно быть быстрее.

Во втором цикле почему-то по три раза вычисляются x[i]-xs и y[i]-ys, их можно и нужно вычислить один раз.

Возможно можно обойтись и без второго цикла, но, как уже сказал выше PapaYozh, придётся предохраняться от накопления погрешности.

hrenfx
3672
hrenfx 2010.10.27 18:01  
Prival:

Ищу итерационную формулу расчета коэффициента корреляции или готовый алгоритм.

Если использовать такую  формулу расчета ковариации, несложно вывести рекурентную формулу ковариации.

Поскольку Corr(X, Y) = Cov(X, Y) / Sqrt(Cov(X, X) * Cov(Y, Y)), то для рекурентного получения КК достаточно знать рекурентный расчет ковариации.

Для расчета КК понадобится с собой таскать только ковариационную матрицу 2x2, или 3 (Cov(X, X), Cov(Y, Y), Cov(X, Y)) значения (4-е повторяется) ковариации.

Проблем с накоплением ошибки никаких нет даже после десятков тысяч итераций. Единственный нюанс, если Cov(X, X) <= 0, присваивать ноль ковариации и КК. 

Андрей
1890
Андрей 2010.10.27 18:42  
Если это повторяющиеся рассчеты- то можно их закэшировать в массиве.
Cache[время рассчета][параметр 1][параметр 2][ ... ] = Результат
Время на вычисления впоследствии будет равно 0.
hrenfx
3672
hrenfx 2010.10.27 18:44  
В рекурентной формуле повторяющихся расчетов нет.
12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий