Блог им. Karim

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

    • 02 ноября 2017, 16:21
    • |
    • Karim
  • Еще
Написал на досуге по просьбе одного из участников смартлаба индикатор корреляции.
Индикатор простенький, считает коэффициент корреляции Пирсона
для двух выбранных инструментов на заданном таймфрейме.
Выкладываю исходный код. Может кому то пригодится.

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
  • обсудить на форуме:
  • QUIK
★54
25 комментариев
Поддержу своими четырьмя плюсиками! ))

А что за массив C(i)? Где он инициализируется? 
avatar
Robot-Scalper.ru, Это цены закрытия основного графика на который накладывается индикатор. Инициализируется QLua, когда открывается график (O, H, L, C).
avatar
Karim, напишите индикатор рассчитывающий коинтеграцию
avatar
Константин, Будет свободное время — попробую.
avatar
Karim, могу дать класс коинтеграции написанный на MQL5 (по сути тот же С++`98) или R
avatar
Константин, Спасибо, не надо. Проще свое написать, чем разбираться в чужом.
avatar
Karim, ))) я с коинтеграцией мучился около трех недель на MQL5 когда писал, т.к. библиотека AlgLib на которой основывался, в MQL5 не на 100% портирована правильно, пришлось много чего дописывать )) а знакомый на R скрипт быстро накидал, но он математик ))

PS. как напишите киньте сообщение в ЛС, если не затруднит
avatar
Константин, Ок, но сначала нужно понять зачем это нужно. Можно ли на этом заработать.
avatar
Karim, завтра буду на связи в Telegram, там можно и переговорить ))
avatar
Karim, понял. Спасибо! Интересный пример. Жаль что практически на этой паре не применимый для торговли. Корреляция слабая, или практически отсутствует, так как RI только рассчитывается в баксах, а в целом содержит голубые фишки. Они то и дают раскорреляцию. Результат был ожидаем. 

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


У вас судя по интерфейсу старенькая версия КВИКа. У меня 7.12. Возможно в новой версии надо что-то переписать в коде?
П.С. Странно. Проверил обе переменных C(i) и sum1. Все они имеют тип number.
avatar
Albus, Возможно на недельном графике BRENT0118 нет какого значения (пустая свеча). Попробуйте найти это место, изменяя N.
avatar
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
avatar
Константин, я понял. Спасибо. 
Я чуть сложнее получаю закрытия. 

t,n,i=getCandlesByIndex(indInstr, 0, N-MCandles, MCandles);
Close = t[0].close;
Тоже работает, как часы. Но, возьму на заметку более простой вариант! ))
avatar
Спасибо, спасибо, спасибо
avatar
патентуйте.будете красной икрой стены штукатурить.
avatar
егорка, У меня уже черной заштукатурено.
avatar
Сложный какой-то код. Сразу видно, что прога не для математики.
avatar
Добрый день!
Спасибо за индикатор!
Но я не могу его запустить — выходит ошибка «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.
Сможете помочь?
avatar
MonMon, В Quik версии 9.7.1.10. стоит Lua 5.3.5. У него нет функции math.pow.
Замените на 
sum1 = sum1 + (C(i) — aver1)*(C(i) — aver1);
sum2 = sum2 + (Candles[j].close — aver2)*(Candles[j].close — aver2);
и все заработает. По крайней мере, у меня на 9.4.2.1 работает.

Удачной торговли!
avatar
Запустился, спасибо!
Но ругается на 53 строку.
avatar
MonMon, Проверьте количество свечек на графике.
avatar
Karim, здраствуйте подскажите пожалуйста что делать если индикатор ругается на 53 строчку
avatar
изменение значения N не помогает
avatar

теги блога Karim

....все тэги



UPDONW
Новый дизайн