В некоторых торговых стратегиях используются цены нескольких активов. Скажем, можно торговать фьючерс MX, глядя на цены фьючерсов MX, SR GZ и выполняя над ними некоторые арифметические преобразования. Например, построить график вида
Spread := price(MX) — 5 * price(SR) — 5 * price(GZ) — 50000
по текущим котировкам и строить торговые идеи на его основе.
Кому интересна визуализация подобных спредов в терминале QUIK 7-й версии с помощью lua-скриптов, добро пожаловать под кат.
Будем считать, что у нас есть график основного инструмента (MXH7) и графики двух дополнительных инструментов (SRH7, GZH7). Эти графики уже построены в терминале, установлен одинаковый таймфрейм (скажем, 1 минута) и им даны идентификаторы MXH7_1min, SRH7_1min, GZH7_1min.
Создадим в папке установки терминала подпапку LuaIndicators и поместим туда скрипт SpreadIndicator.lua, приведённый в конце поста (выделите код, скопируйте в блокнот и сохраните в файл с указанным именем). Добавим на график MXH7 индикатор «SpreadIndicator» и зададим ему параметры:
- tag1 — метка графика, откуда берётся цена дополнительного инструмента 1 (в нашем случае SRH7_1min);
- tag2 — метка графика, откуда берётся цена дополнительного инструмента 2 (в нашем случае GZH7_1min);
- коэффициенты k, k1, k2, a, по которым вычисляется спред spread.
Формула для вычисления спреда такова: spread := k * price(security) + k1 * price(tag1) + k2 * price(tag2) + a.
График спреда будет обновляться при обновлении графика основного инструмента.
Код несложно модифицировать для случая другого количества инструментов и формулы для расчёта спреда (см. функцию getSpread). Это хорошее упражнение для повышения Вашего уровня владения навыками программирования на lua.
--
-- Построение спреда по нескольким инструментам:
-- spread := k * price(security) + k1 * price(tag1) + k2 * price(tag2) + a.
-- Можно добавлять дополнительные инструменты, модифицируя код индикатора.
--
Settings = {
Name = "SpreadIndicator",
k = 1, -- коэффициент, с которым учитывается цена основного инструмента
tag1 = "SRH7_1min", -- метка графика, откуда берётся цена дополнительного инструмента 1
tag2 = "GZH7_1min", -- метка графика, откуда берётся цена дополнительного инструмента 2
k1 = -5, -- коэффициент, с которым учитывается цена дополнительного инструмента 1
k2 = -5, -- коэффициент, с которым учитывается цена дополнительного инструмента 2
a = 0, -- свободный член
line = { { Name = "Spread", Color = RGB(0, 0, 255), Type = TYPE_LINE, Width = 1, } }
}
function Init()
return 1
end
local function getTimeCode(dt)
return (dt.year * 10000 + dt.month * 100 + dt.day) * 1000000 + (dt.hour * 10000 + dt.min * 100 + dt.sec)
end
--- Найти свечу, относящуюся к заданному времени или предшествующую ему, если для заданного времени нет свечи.
-- @param tag строковый идентификатор графика или индикатора
-- @param timeCode метка времени в формате yyyymmddhhmmss
-- @return искомая свеча или nil, если свеча не найдена.
local function getCandleByTimeCode(tag, timeCode)
local numCandles = getNumCandles(tag)
if numCandles < 2 then
return nil
end
local lastCandle, n, _ = getCandlesByIndex(tag, 0, numCandles - 1, 1)
if n ~= 1 then
return nil
end
lastCandle = lastCandle[0]
if getTimeCode(lastCandle.datetime) <= timeCode then
return lastCandle
end
local b = numCandles - 1
local a = b - 1
local candle
while true do
local firstCandle, n, _ = getCandlesByIndex(tag, 0, a, 1)
if n ~= 1 then
return nil
end
firstCandle = firstCandle[0]
local firstTimeCode = getTimeCode(firstCandle.datetime)
if firstTimeCode == timeCode then
return firstCandle
elseif firstTimeCode < timeCode then
candle = firstCandle
break
elseif a == 0 then
return nil
else
a = math.max(0, 2 * a - b)
end
end
while true do
local c = math.floor((a + b) / 2)
if c == a then
return candle
else
local middleCandle, n, _ = getCandlesByIndex(tag, 0, c, 1)
if n ~= 1 then
return nil
end
middleCandle = middleCandle[0]
local middleTimeCode = getTimeCode(middleCandle.datetime)
if middleTimeCode == timeCode then
return middleCandle
elseif middleTimeCode < timeCode then
a, candle = c, middleCandle
else
b = c
end
end
end
end
--- Вычислить спред.
-- @param index номер свечи на графике
-- @return значение спреда или nil, если оно неопределено
local function getSpread(index)
local timeCode = getTimeCode(T(index))
local securityPrice = C(index)
if securityPrice == nil then
return nil
end
-- Получение свечей дополнительных инструментов
local candle1 = getCandleByTimeCode(Settings.tag1, timeCode)
local candle2 = getCandleByTimeCode(Settings.tag2, timeCode)
if candle1 == nil or candle2 == nil then
return nil
end
-- Получение цен дополнительных инструментов
local price1 = candle1.close
local price2 = candle2.close
if price1 == nil or price2 == nil then
return nil
end
-- Вычисление спреда
local spread = Settings.k * securityPrice
+ Settings.k1 * price1
+ Settings.k2 * price2
+ Settings.a
return spread
end
function OnCalculate(index)
if index > 1 then
local spread = getSpread(index - 1)
if spread then
SetValue(index - 1, 0, spread)
end
end
return getSpread(index)
end
Удачи!
Ниже приведу слова Ларри Вильямса:
«Золото может расти быстрее доллара США только до тех пор, пока оно не начнет падать. Эту взаимосвязь трудно увидеть, рассматривая графики, но вовсе не трудно обнаружить, когда вы посмотрите на взаимосвязь спрэда между этими рынками. Для обнаружения взаимосвязи, на которую мне нравиться смотреть, нужно взять недельный спрэд между этими двумя рынками, затем построить трехнедельное скользящее среднее и 21-недельное скользящее среднее этого спрэда. Чтобы увидеть маятниковые колебания рассматриваемого спреда, я вычитаю далее трехнедельное скользящее среднее из 21-недельного скользящего среднего. Деление полученного результата на 100 дает нам равномерный распределенный коэффицент; таким образом при подходящем масштабе можно увидеть любой момент времени. Проделывая эти вычисления, я заметил, что когда данный коэффициент переходит через край, т.е. когда отношение трехнедельного к 21-недельному спреду превышает 30%, то на рынке золота вскоре обнаруживается спад. Иными словами, золото может оказаться перекупленным по отношению к доллару США, и в этот момент времени крупные суммы денег профессионалов выходят на рынок, чтобы воспользоваться указанными дисбалансом путем продажи золота».
На просторах интернета нашел такой индикатор, но он для МТ4 и 5.
Вот пример:
«Из сказанного выше, можно получить формулу расчета этого инидкатора:
(SMA 21(IndexDollar-Gold) – SMA 3 (IndexDollar-Gold))/100
где:
SMA 21 — 21-периодичное простое скользящее среднее
SMA 3 — трехнедельное простое скользящее среднее
IndexDollar — индекс доллара
Gold – золото
ВАЖНОЕ ЗАМЕЧАНИЕ: это исключительно долгосрочный индикатор, лучше всего его использовать на недельных таймфреймах. Его задача указывать на будущие движения длящиеся 6 месяцев и более.»
Скажите пожалуйста, можно такой скрипт написать для КВИК?
Я не умею. Можете помочь?
forum.quik.ru/forum10/
то кто-нибудь может возьмётся за такое за недорого.
Есть ли индекс доллара в квике — не знаю, т.к. мой брокер его не транслирует.
www.bot4sale.ru/download-categories/2012-06-13-15-10-36/item/juggler.html
lua: spread_ind_1.lua:15: attempt to call global 'RGB' (a nil value)
stack traceback:
spread_ind_1.lua:15: in main chunk
[C]: in ?
"
Может кто-то объяснит?