В скриптах напрямую доступны все данные Quik'а, кроме греков с доски опционов. Но есть возможность рассчитывать их по формуле Блэка-Шоулза, исходя из доступных значений базы, страйка, дюрации и волатильности.
Чтобы удостовериться в совпадении греков с доски и расчётных, пришлось в скрипте отваять на Lua C API сервер DDE для приёма экспорта от доски опционов. И вот картинка
Разница в самом главном Греке — Дельте — менее 1%.
Через Lua в Quik'е доступны все возможности Windows.
local Titles, Entries, Desk = {}, {}, {}
local Wn1_Hndl
local Wn1_Field1, Wn1_Field2, Wn1_Field3, Wn1_Field4, Wn1_Field5
= "Код CALL", "Страйк", "Дельта CALL", "Дельта расч", "Теор. расч"
function OnInit (scriptPath)
qu = require ("QuikUtil(qu)") -- qc, lu, tu
blk = require ("BlackScholes(blk)")
glb_ScriptDir, glb_ScriptName = lu.SplitPath (scriptPath)
message (glb_ScriptName .." started")
server = require ("OptionDesk")
end -- OnInit()
function OnStop (signal)
if Wn1_Hndl then DestroyTable (Wn1_Hndl) end
StopFlag = true
return 1000 -- 1 sec
end
local function ShowWin (cols)
for k = 1, #Desk do
local calCode = Desk[k][Entries[Wn1_Field1]]
if calCode:sub (3,3) == "0" then
calCode = calCode:sub (1,2) . <a name="cut"></a> . calCode:sub (4)
end
local strike = Desk[k][Entries[Wn1_Field2]]
local deltaDesk = Desk[k][Entries[Wn1_Field3]]
local base = Desk[k][Entries["Цена баз. актива"]]
local dura = qu.GetParamNum (qc.SPBOPT, calCode, qc.DAYS_TO_MAT_DATE) / 365
local vola = qu.GetParamNum (qc.SPBOPT, calCode, qc.VOLATILITY) / 100
local deltaCalc = blk.BS_CDELTA (base, strike, dura, 0, vola)
local theorCalc = blk.BS_CALL (base, strike, dura, 0, vola)
SetCell (Wn1_Hndl, k, 1, calCode)
SetCell (Wn1_Hndl, k, 2, tostring (strike))
SetCell (Wn1_Hndl, k, 3, string.format (cols[3][4], deltaDesk))
SetCell (Wn1_Hndl, k, 4, string.format (cols[3][4], deltaCalc))
SetCell (Wn1_Hndl, k, 5, string.format (cols[5][4],theorCalc))
local clr = math.abs (deltaCalc / deltaDesk - 1) > 0.01
and RGB (223,127,127) or QTABLE_DEFAULT_COLOR
SetColor (Wn1_Hndl, k, 4, clr
,QTABLE_DEFAULT_COLOR, QTABLE_DEFAULT_COLOR, QTABLE_DEFAULT_COLOR)
end -- for k
end -- ShowWin()
function main()
local res = server.start (glb_ScriptDir .. glb_ScriptName ..".log")
if not res then
message ("Server.start failed ".. tostring (res))
return
end
while not StopFlag do
if Wn1_Hndl and IsWindowClosed (Wn1_Hndl) then break end
local tbl = server.event()
if type (tbl) == "table" then
local s = "#tbl ".. #tbl
if #Titles == 0 then
s = s .. " #Titles ".. #Titles
for i = 1, #tbl[1] do
Titles[i] = tbl[1][i]
end
message (s .."\n".. table.concat (tbl[1], "\n")
.."\n#Titles ".. #Titles)
Entries = {}
for i = 1,#tbl[1] do
Entries[tbl[1][i]] = i
end
message ("Entries\n".. lu.Serialize (Entries, "\n"))
elseif #Desk == 0 then
s = s .." #tbl[1] ".. #tbl[1]
for i = 1, #tbl do
Desk[i] = {}
for j = 1, #tbl[i] do
Desk[i][j] = tbl[i][j]
end
if i < 3 then
message (table.concat (Desk[i], "\n"))
end
end
message (s)
local caption = glb_ScriptName
local rowNum = #Desk
local cols = {
{Wn1_Field1, QTABLE_STRING_TYPE, 15, "%s"}
,{Wn1_Field2, QTABLE_DOUBLE_TYPE, 12, "%f"}
,{Wn1_Field3, QTABLE_DOUBLE_TYPE, 15, "%.5f"}
,{Wn1_Field4, QTABLE_DOUBLE_TYPE, 15, "%.5f"}
,{Wn1_Field5, QTABLE_DOUBLE_TYPE, 15, "%.2f"}
}
Wn1_Hndl = qu.MakeWin (caption, rowNum, cols)
ShowWin (cols)
end -- if #Titles == 0 .. else
end -- if type (tbl) == "table"
end -- while not StopFlag
server.stop()
message ("StopFlag ".. tostring (StopFlag))
end -- main()
…
«В геометрию нет царского пути» Эвклид ©
ничего не смыслю в скриптах, но если автор сумел такое отваять, то!!!
learn.microsoft.com/en-us/windows/win32/dataxchg/about-the-ddeml
roboex.narod.ru/olderfiles/1/ex4g_dde_018.zip
www.lua.org/download.html
«Программирование на языке LUA. 3-е изд.pdf»
arqatech.com/ru/products/quik/capabilities/integration/programming-languages/
«Интерпретатор языка Lua.pdf»
Руководство пользователя:
«Раздел 6. Совместная работа с другими приложениями.pdf»
«Раздел 8. Алгоритмический язык QPILE.pdf»