Karim
Karim личный блог
02 ноября 2017, 16:21

Quik. Индикатор корреляции

Написал на досуге по просьбе одного из участников смартлаба индикатор корреляции.
Индикатор простенький, считает коэффициент корреляции Пирсона
для двух выбранных инструментов на заданном таймфрейме.
Выкладываю исходный код. Может кому то пригодится.

Settings= 
{ 
Name = "Piton", 
N = 100,
legend = "price2",
line = 
	{ 
		{ Name = "Sint", 
		  Color = RGB(0, 132, 0), 
		  Type = TYPE_LINE, 
		  Width = 1 
		}		
	} 
} 

function Init() 
return 1
end 

Candles = {};


function OnCalculate(index) 
	local numCandles = getNumCandles(Settings.legend);
	if index <= Settings.N or numCandles <= Settings.N then
		return nil;
	end
	
	Candles, n, _ = getCandlesByIndex(Settings.legend, 0, index - Settings.N, Settings.N);
	if n ~= Settings.N then
        return nil;
    end
	
	-- Предварительный расчет
	sum1, sum2, sum3 = advancePaynemt(index);
	
	-- расчет коэффициента корреляции Пирсона
	r = sum3/math.sqrt(sum1*sum2);
	
	return r;
end

--  Предварительный расчет
----------------------------------------
function advancePaynemt(index)	
	local sum1 = 0;
	local sum2 = 0;	
	local sum3 = 0;
	local j    = 0;
	
	--  Вычислить среднее арифметическое
	for i=index - Settings.N + 1, index, 1 do
		sum1 = sum1 + C(i);			
		sum2 = sum2 + Candles[j].close;
		j = j + 1;
	end
	aver1 = sum1/Settings.N;
	aver2 = sum2/Settings.N;
	
	-- Вычислить сумму квадратов отклонений
	sum1 = 0;
	sum2 = 0;
	j 	 = 0;
	for i=index - Settings.N+1, index, 1 do
		sum1 = sum1 + math.pow(C(i) - aver1, 2);
		sum2 = sum2 + math.pow(Candles[j].close - aver2, 2);
		j = j + 1;
	end
	
	--  Вычислить сумму произведений разности
	j=0;
	for i=index - Settings.N+1, index, 1 do
		sum3 = sum3 + (aver1 - C(i))*(aver2 - Candles[j].close);
		j = j + 1;
	end
	
	return sum1, sum2, sum3;
end

Как запустить и настроить:


Архив исходника на QLua: https://yadi.sk/d/OxDvAekV3PLn2z
25 Комментариев
  • Robot-Scalper.ru
    02 ноября 2017, 17:00
    Поддержу своими четырьмя плюсиками! ))

    А что за массив C(i)? Где он инициализируется? 
      • Константин
        02 ноября 2017, 17:16
        Karim, напишите индикатор рассчитывающий коинтеграцию
          • Константин
            02 ноября 2017, 19:08
            Karim, могу дать класс коинтеграции написанный на MQL5 (по сути тот же С++`98) или R
              • Константин
                02 ноября 2017, 19:41
                Karim, ))) я с коинтеграцией мучился около трех недель на MQL5 когда писал, т.к. библиотека AlgLib на которой основывался, в MQL5 не на 100% портирована правильно, пришлось много чего дописывать )) а знакомый на R скрипт быстро накидал, но он математик ))

                PS. как напишите киньте сообщение в ЛС, если не затруднит
                  • Константин
                    02 ноября 2017, 21:03
                    Karim, завтра буду на связи в Telegram, там можно и переговорить ))
      • Robot-Scalper.ru
        02 ноября 2017, 17:17
        Karim, понял. Спасибо! Интересный пример. Жаль что практически на этой паре не применимый для торговли. Корреляция слабая, или практически отсутствует, так как RI только рассчитывается в баксах, а в целом содержит голубые фишки. Они то и дают раскорреляцию. Результат был ожидаем. 

        Интересно сравнить корреляции Si и фьючерсов компаний у которых выручка в баксах. Вполне возможно, что она будет сильнее. 
      • Albus
        05 ноября 2017, 15:31
        Karim, спасибо за индикатор. Я как раз увлёкся корелляциями.
        Индикатор пишет ошибку в строке 53. Видимо, он не может найти C(i)


        У вас судя по интерфейсу старенькая версия КВИКа. У меня 7.12. Возможно в новой версии надо что-то переписать в коде?
        П.С. Странно. Проверил обе переменных C(i) и sum1. Все они имеют тип number.
    • Константин
      02 ноября 2017, 17:14
      Robot-Scalper.ru,
      А что за массив C(i)? Где он инициализируется? 

      это функция языка QLUA )) справку откройте, она есть в каталоге установленного терминала:
      Функции O, H, L, C, V, T

       

      Функции в качестве параметра принимают индекс свечи и возвращают соответствующее значение. Время свечи возвращается с точностью до миллисекунд в виде таблицы с полями:

      {year, month, day, week_day, hour, min, sec, ms, count}

      Где:

      • count – количество тиковых интервалов в секунду. Может принимать значения от «1» до «10000» включительно.

      Пример:

      Open = ds:O(1)
      High = ds:H(1)
      Low = ds:L(1)
      Close = ds:C(1)
      Volume = ds:V(1)
      week_day = ds:T(1).week_day
      count = ds:T(1).count
      
      • Robot-Scalper.ru
        02 ноября 2017, 17:25
        Константин, я понял. Спасибо. 
        Я чуть сложнее получаю закрытия. 

        t,n,i=getCandlesByIndex(indInstr, 0, N-MCandles, MCandles);
        Close = t[0].close;
        Тоже работает, как часы. Но, возьму на заметку более простой вариант! ))
  • iuiu
    02 ноября 2017, 17:18
    Спасибо, спасибо, спасибо
  • егорка
    02 ноября 2017, 18:53
    патентуйте.будете красной икрой стены штукатурить.
  • Zmey
    02 ноября 2017, 20:52
    Сложный какой-то код. Сразу видно, что прога не для математики.
  • MonMon
    20 февраля 2023, 16:20
    Добрый день!
    Спасибо за индикатор!
    Но я не могу его запустить — выходит ошибка «C:\QUIK\LuaIndicators\Piton.lua:65: attempt to call a nil value (field 'pow')»/
    Менял значение N на 1, 2, 10, 50, 200, без результата.
    Quik версии 9.7.1.10.
    Сможете помочь?
      • MonMon
        24 февраля 2023, 05:04
        Запустился, спасибо!
        Но ругается на 53 строку.
  • Damirrrr
    28 декабря 2023, 19:47
    Karim, здраствуйте подскажите пожалуйста что делать если индикатор ругается на 53 строчку
  • Damirrrr
    28 декабря 2023, 19:55
    изменение значения N не помогает

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн