Вывел опционы в текущую таблицу - там нет таких параметров как волатильность и теор цена
Зайдите в пункт меню Настройки/Основные/Программа/Получение данных/ и выберите пункт "Исходя из настроек открытых пользователем таблиц" После создайте таблицу снова и проверьте, параметры должны быть.
Вывел опционы в текущую таблицу - там нет таких параметров как волатильность и теор цена
Зайдите в пункт меню Настройки/Основные/Программа/Получение данных/ и выберите пункт "Исходя из настроек открытых пользователем таблиц" После создайте таблицу снова и проверьте, параметры должны быть.
Спасибо пересоздал все появилось Только греков нету
Вывел опционы в текущую таблицу - там нет таких параметров как волатильность и теор цена
Зайдите в пункт меню Настройки/Основные/Программа/Получение данных/ и выберите пункт "Исходя из настроек открытых пользователем таблиц" После создайте таблицу снова и проверьте, параметры должны быть.
Спасибо пересоздал все появилось Только греков нету
Egor Zaytsev пишет: Греки только в доске опционов.
В доске нет греков Они только в "Таблице параметров опционов"
Здравствуйте, Если Вам нужны греки в LUA единственный способ их получить это рассчитать по формулам. У нас есть готовый пример скрипта, можете взять формулы от туда:
Скрытый текст
Код
--[[
Что делает:
По Таблице текущих параметров строит таблицу опционов с расcчитанными греками
Формулы взяты отсюда:
http://en.wikipedia.org/wiki/Black%96Scholes
http://en.wikipedia.org/wiki/Greeks_%28finance%29
Как использовать:
откройте Таблицу Текущих Параметров (меню Таблицы -> Текущая Таблица)
Укажите настройки, после чего, запустите скрипт (меню Таблицы - Lua - Доступные скрипты)
чтобы сохранить в CSV файл, текущее состояние таблицы, нужно нажать комбинацию клавиш Ctrl+S файл сохраняется в папку со скриптом, с именем HHHMMDD.csv
]]
-------------------------------НАСТРОЙКИ-------------------------------
RiskFree=0/100 --безрисковая ставка %, Указывается вручную
BaseClassCode = "SPBFUT" --Класс базового актива
ClassCode = "SPBOPT" --Класс опционов
--Список базовых активов, через запятую, по которым отображать опционы:
BaseSecList = "RIU5" --getClassSecurities(BaseClassCode) --все сразу
--Список опционов через запятую:
SecList = getClassSecurities(ClassCode) --все сразу
INTERVAL = 1000 --Интервал обновления таблицы
doLogging=false --включает запись в файл, формата csv.
log_file=getScriptPath() .. "\\Greek.csv" --путь к csv файлу
-----------------------------------------------------------------------
-------------------------------ТО ЧТО НИЖЕ, ТРОГАТЬ НЕ НАДО------------------------------------------------------------------
--Параметры таблицы
tbl = {
["caption"]="Greek",
[1]="Название",
[2]="Код опциона",
[3]="Тип опциона",
[4]="Баз. актив",
[5]="Расчетная цена",
[6]="Страйк",
[7]="Волатильность",
[8]="До исполнения",
[9]="Дельта",
[10]="Гамма(%)",
[11]="Тэта",
[12]="Вега",
[13]="Ро",
["t_id"]=0
}
abTable = {}
BaseCol = {}
Sec2row = {}
file = nil
Sep = ";"
YearLen=365.0 --Число дней в году
WORK = true
CALC = false
G_ROW = -1
if (BaseSecList == "") or (BaseSecList == nil) then
BaseSecList = getClassSecurities(BaseClassCode)
end
if (SecList == "") or (SecList == nil) then
SecList = getClassSecurities(ClassCode)
end
-------------------------------ФУНКЦИИ------------------------------------------------------------------
function Logging(str) --Пишет лог
if file~=nil and doLogging then
file:write(str .. "\n")
file:flush()
end
end
function N(x) --Нормальное среднее
if (x > 10) then
return 1
elseif (x < -10) then
return 0
else
local t = 1 / (1 + 0.2316419 * math.abs(x))
local p = 0.3989423 * math.exp(-0.5 * x * x) * t * ((((1.330274 * t - 1.821256) * t + 1.781478) * t - 0.3565638) * t + 0.3193815)
if x > 0 then
p=1-p
end
return p
end
end
function pN(x) --производная от функции нормального среднего
return math.exp(-0.5 * x * x) / math.sqrt(2 * math.pi)
end
function Greek(tmpParam)
local b = tmpParam.volatility / 100 --"b" волатильность доходности (квадратный корень из дисперсии) базисной акции.
local S = tmpParam.settleprice --"S" текущая цена базисной акции;
local Tt = tmpParam.DAYS_TO_MAT_DATE / YearLen --"T-t" время до истечения срока опциона (период опциона);
local K = tmpParam.strike --"K" цена исполнения опциона;
local r = RiskFree --"r" безрисковая процентная ставка;
local d1 = (math.log(S / K) + (r + b * b * 0.5) * Tt) / (b * math.sqrt(Tt))
local d2 = d1-(b * math.sqrt(Tt))
local Delta = 0
local Gamma = 0
local Theta = 0
local Vega = 0
local Rho = 0
local e = math.exp(-1 * r * Tt)
Gamma = pN(d1) / (S * b * math.sqrt(Tt))
Vega = S * e * pN(d1) * math.sqrt(Tt)
Theta = (-1 * S * b * e * pN(d1)) / (2 * math.sqrt(Tt))
if tmpParam.Optiontype == "Call" then
Delta = e * N(d1)
Theta = Theta - (r * K * e * N(d2)) + r * S * e * N(d1)
----Theta = Theta - (r * K * e * N(d2))
Rho = K * Tt * e * N(d2)
else
Delta = -1 * e * N(-1*d1)
Theta = Theta + (r * K * e * N(-1 * d2)) - r * S * e * N(-1 * d1)
----Theta = Theta + (r * K * e * N(-1 * d2))
Rho = -1 * K * Tt * e * N(-1 * d2)
end
return {
["Delta"] = Delta,
["Gamma"] = 100 * Gamma,
["Theta"] = Theta / YearLen,
["Vega"] = Vega / 100,
["Rho"] = Rho / 100
}
end
function GetRow(ID,row) --возвращает строку таблицы
local rows, col = GetTableSize(ID)
local result = ""
if rows~=nil and row<=rows then
for i=1,col do
result=result..GetCell(ID,row,i).image .. Sep
end
end
return result
end
function CSV(T) --пишет таблицу в csv файл
function FTEXT(V) --ПРОВЕРЯЕМ КОРРЕКТНОСТЬ КОЛИЧЕСТВА СИМОЛОВ ПЕРЕМЕННОЙ
V=tostring(V)
if (string.len(V)==1) or (string.len(V)==5) then
V="0".. V
end
return V
end
local temp = os.date("*t")
local Fname =getScriptPath() .. "\\" .. FTEXT(temp.year) .. FTEXT(temp.month) .. FTEXT(temp.day) .. ".csv"
CSVFile = io.open(Fname, "w+")
if CSVFile~=nil then
local rows, col = GetTableSize(T.t_id)
for i=1,col do --расставляем заголовки
CSVFile:write(T[i] .. Sep)
end
CSVFile:write("\n")
for i=1,rows do --пишем таблицу
CSVFile:write(GetRow(T.t_id,i).."\n")
end
CSVFile:flush()
CSVFile:close()
message("Файл успешно сохранен:\n"..Fname, 1)
else
message("Ошибка при сохранении файла:\n"..Fname, 3)
end
end
function round(num, idp) --округляет до указанного количества знаков
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function comma_value(n) --ставит разделители в числах
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1 '):reverse())..right
end
function CreateDataSourceEX(Class,Sec,Par)
local ds,err = CreateDataSource(Class, Sec, INTERVAL_TICK, Par)
if ds==nil then
message("Ошибка при получении параметра "..Par..":\n"..err, 3)
return false
else
ds:SetEmptyCallback()
while ds:Size()==0 do
sleep(100)
end
return true
end
end
function Stop()
if doLogging then
file:close()
end
WORK = false
end
function Calculate(row,do_calc)
if (row~=nil) and (row>=0) and (do_calc) then
local T=BaseCol[row]
local tmpParam ={
["Optiontype"] = T.Optiontype,
["settleprice"] = getParamEx(BaseClassCode,T.Optionbase,"settleprice").param_value+0,
["strike"] = getParamEx(ClassCode,T.SecCode,"strike").param_value+0,
["volatility"] = getParamEx(ClassCode,T.SecCode,"volatility").param_value+0,
["DAYS_TO_MAT_DATE"] = T.DAYS_TO_MAT_DATE
}
local tmpGreek = Greek(tmpParam)
SetCell(tbl.t_id, row, 5, comma_value(tmpParam.settleprice), tmpParam.settleprice) -- "Расчетная цена",
SetCell(tbl.t_id, row, 6, comma_value(tmpParam.strike), tmpParam.strike) --"Страйк",
SetCell(tbl.t_id, row, 7, tostring(tmpParam.volatility), tmpParam.volatility) -- "Волатильность",
SetCell(tbl.t_id, row, 8, tostring(tmpParam.DAYS_TO_MAT_DATE), tmpParam.DAYS_TO_MAT_DATE) --"До исполнения",
SetCell(tbl.t_id, row, 9, tostring(round(tmpGreek.Delta,2)), tmpGreek.Delta) --"Дельта",
SetCell(tbl.t_id, row, 10, tostring(round(tmpGreek.Gamma,4)), tmpGreek.Gamma) -- "Гамма(%)",
SetCell(tbl.t_id, row, 11, tostring(round(tmpGreek.Theta,2)), tmpGreek.Theta) -- "Тэта",
SetCell(tbl.t_id, row, 12, tostring(round(tmpGreek.Vega,2)), tmpGreek.Vega) -- "Вега",
SetCell(tbl.t_id, row, 13, tostring(round(tmpGreek.Rho,2)), tmpGreek.Rho) -- "Ро",
Logging(os.date().. Sep .. GetRow(tbl.t_id,row))
end
return false
end
-------------------------------Колбэки------------------------------------------------------------------
function f_cb(t_id,msg,par1,par2) --событие на нажатие клавиш
if (msg==QTABLE_CHAR) and (par2==19) then --сохранить в CSV файл текущее состояние таблицы нужно нажать комбинацию клавиш Ctrl+S
CSV(tbl)
end
if (msg==QTABLE_CLOSE) then --закрытие окна
Stop()
end
end
function OnStop()
Stop()
DestroyTable(tbl.t_id)
end
function OnInit()
local STR = ""
if doLogging then
file = io.open(log_file, "w+")
end
tbl.t_id = AllocTable()
for i=1,table.maxn(tbl) do --добавляем колонки
if i<=4 then
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_CACHED_STRING_TYPE, string.len(tbl[i])*2)
else
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_DOUBLE_TYPE, 10)
end
if doLogging then
STR=STR..tbl[i]..Sep
end
end
Logging("Дата Время".. Sep .. STR)
CreateWindow(tbl.t_id)
SetWindowCaption(tbl.t_id,tbl.caption)
SetTableNotificationCallback(tbl.t_id, f_cb)
end
function OnParam(class, sec)
if (class==ClassCode) and (WORK) and (string.find(SecList,sec)~=nil) then
G_ROW = Sec2row[sec]
if (G_ROW~=nil) and (G_ROW>=0) then
Highlight(tbl.t_id, G_ROW, QTABLE_NO_INDEX, RGB(255,0,0), QTABLE_DEFAULT_COLOR, INTERVAL)
CALC=true
end
end
end
function main()
WORK = false
CALC=true
for SecCode in string.gmatch(SecList, "([^,]+)") do --перебираем опционы по очереди.
local Optionbase=getParamEx(ClassCode,SecCode,"optionbase").param_image
local Optiontype=getParamEx(ClassCode,SecCode,"optiontype").param_image
if (string.find(BaseSecList,Optionbase)~=nil) then
local row = InsertRow(tbl.t_id,-1)
local T={
["Name"] = getSecurityInfo(ClassCode,SecCode).name,
["SecCode"] = SecCode,
["Optiontype"] = Optiontype,
["Optionbase"] = Optionbase,
["DAYS_TO_MAT_DATE"] = getParamEx(ClassCode,SecCode,"DAYS_TO_MAT_DATE").param_value+0
}
BaseCol[row]=T
--заполняем статичные параметры
Sec2row[SecCode]=row
SetCell(tbl.t_id, row, 1, BaseCol[row].Name) -- "Название опциона",
SetCell(tbl.t_id, row, 2, BaseCol[row].SecCode) --"Код опциона",
SetCell(tbl.t_id, row, 3, BaseCol[row].Optiontype) -- "Тип опциона",
SetCell(tbl.t_id, row, 4, BaseCol[row].Optionbase) --"Баз. актив",
--заказ данных
CreateDataSourceEX(BaseClassCode,T.Optionbase,"settleprice")
CreateDataSourceEX(ClassCode,T.SecCode,"strike")
CreateDataSourceEX(ClassCode,T.SecCode,"volatility")
--заполняем динамичные параметры
CALC=Calculate(row,true)
end
end
WORK = true
while WORK do
CALC=Calculate(G_ROW,CALC)
sleep(INTERVAL)
end
end
Sergey Gorokhov пишет: Если Вам нужны греки в LUA единственный способ их получить это рассчитать по формулам. У нас есть готовый пример скрипта, можете взять формулы от туда:
Я так и делал. Только не скриптом, а другой формулой. Не суть.
Проблема в том, что они не бьются с данными в таблице "Параметров опционов", и расчетные заявки по опционам, например, выставленные в стакан, оказываются "съехавшими" на некоторое число пунктов, относительно транслируемых в "доске".
Я конечно знаю, что с 95% вероятностью получу ответ: "да у вас формула кривая". И, вероятно, вы будете правы. Поэтому вопрос не в том как посчитать греки самому, а как получить "те же цифры" из квика.
Egor Zaytsev пишет: Греки только в доске опционов.
В доске нет греков Они только в "Таблице параметров опционов"
Здравствуйте, Если Вам нужны греки в LUA единственный способ их получить это рассчитать по формулам. У нас есть готовый пример скрипта, можете взять формулы от туда: Скрытый текст
Код
--[[
Что делает:
По Таблице текущих параметров строит таблицу опционов с расcчитанными греками
Формулы взяты отсюда:
http://en.wikipedia.org/wiki/Black%96Scholes
http://en.wikipedia.org/wiki/Greeks_%28finance%29
Как использовать:
откройте Таблицу Текущих Параметров (меню Таблицы -> Текущая Таблица)
Укажите настройки, после чего, запустите скрипт (меню Таблицы - Lua - Доступные скрипты)
чтобы сохранить в CSV файл, текущее состояние таблицы, нужно нажать комбинацию клавиш Ctrl+S файл сохраняется в папку со скриптом, с именем HHHMMDD.csv
]]
-------------------------------НАСТРОЙКИ-------------------------------
RiskFree=0/100 --безрисковая ставка %, Указывается вручную
BaseClassCode = "SPBFUT" --Класс базового актива
ClassCode = "SPBOPT" --Класс опционов
--Список базовых активов, через запятую, по которым отображать опционы:
BaseSecList = "RIU5" --getClassSecurities(BaseClassCode) --все сразу
--Список опционов через запятую:
SecList = getClassSecurities(ClassCode) --все сразу
INTERVAL = 1000 --Интервал обновления таблицы
doLogging=false --включает запись в файл, формата csv.
log_file=getScriptPath() .. "\\Greek.csv" --путь к csv файлу
-----------------------------------------------------------------------
-------------------------------ТО ЧТО НИЖЕ, ТРОГАТЬ НЕ НАДО------------------------------------------------------------------
--Параметры таблицы
tbl = {
["caption"]="Greek",
[1]="Название",
[2]="Код опциона",
[3]="Тип опциона",
[4]="Баз. актив",
[5]="Расчетная цена",
[6]="Страйк",
[7]="Волатильность",
[8]="До исполнения",
[9]="Дельта",
[10]="Гамма(%)",
[11]="Тэта",
[12]="Вега",
[13]="Ро",
["t_id"]=0
}
abTable = {}
BaseCol = {}
Sec2row = {}
file = nil
Sep = ";"
YearLen=365.0 --Число дней в году
WORK = true
CALC = false
G_ROW = -1
if (BaseSecList == "") or (BaseSecList == nil) then
BaseSecList = getClassSecurities(BaseClassCode)
end
if (SecList == "") or (SecList == nil) then
SecList = getClassSecurities(ClassCode)
end
-------------------------------ФУНКЦИИ------------------------------------------------------------------
function Logging(str) --Пишет лог
if file~=nil and doLogging then
file:write(str .. "\n")
file:flush()
end
end
function N(x) --Нормальное среднее
if (x > 10) then
return 1
elseif (x < -10) then
return 0
else
local t = 1 / (1 + 0.2316419 * math.abs(x))
local p = 0.3989423 * math.exp(-0.5 * x * x) * t * ((((1.330274 * t - 1.821256) * t + 1.781478) * t - 0.3565638) * t + 0.3193815)
if x > 0 then
p=1-p
end
return p
end
end
function pN(x) --производная от функции нормального среднего
return math.exp(-0.5 * x * x) / math.sqrt(2 * math.pi)
end
function Greek(tmpParam)
local b = tmpParam.volatility / 100 --"b" волатильность доходности (квадратный корень из дисперсии) базисной акции.
local S = tmpParam.settleprice --"S" текущая цена базисной акции;
local Tt = tmpParam.DAYS_TO_MAT_DATE / YearLen --"T-t" время до истечения срока опциона (период опциона);
local K = tmpParam.strike --"K" цена исполнения опциона;
local r = RiskFree --"r" безрисковая процентная ставка;
local d1 = (math.log(S / K) + (r + b * b * 0.5) * Tt) / (b * math.sqrt(Tt))
local d2 = d1-(b * math.sqrt(Tt))
local Delta = 0
local Gamma = 0
local Theta = 0
local Vega = 0
local Rho = 0
local e = math.exp(-1 * r * Tt)
Gamma = pN(d1) / (S * b * math.sqrt(Tt))
Vega = S * e * pN(d1) * math.sqrt(Tt)
Theta = (-1 * S * b * e * pN(d1)) / (2 * math.sqrt(Tt))
if tmpParam.Optiontype == "Call" then
Delta = e * N(d1)
Theta = Theta - (r * K * e * N(d2)) + r * S * e * N(d1)
----Theta = Theta - (r * K * e * N(d2))
Rho = K * Tt * e * N(d2)
else
Delta = -1 * e * N(-1*d1)
Theta = Theta + (r * K * e * N(-1 * d2)) - r * S * e * N(-1 * d1)
----Theta = Theta + (r * K * e * N(-1 * d2))
Rho = -1 * K * Tt * e * N(-1 * d2)
end
return {
["Delta"] = Delta,
["Gamma"] = 100 * Gamma,
["Theta"] = Theta / YearLen,
["Vega"] = Vega / 100,
["Rho"] = Rho / 100
}
end
function GetRow(ID,row) --возвращает строку таблицы
local rows, col = GetTableSize(ID)
local result = ""
if rows~=nil and row<=rows then
for i=1,col do
result=result..GetCell(ID,row,i).image .. Sep
end
end
return result
end
function CSV(T) --пишет таблицу в csv файл
function FTEXT(V) --ПРОВЕРЯЕМ КОРРЕКТНОСТЬ КОЛИЧЕСТВА СИМОЛОВ ПЕРЕМЕННОЙ
V=tostring(V)
if (string.len(V)==1) or (string.len(V)==5) then
V="0".. V
end
return V
end
local temp = os.date("*t")
local Fname =getScriptPath() .. "\\" .. FTEXT(temp.year) .. FTEXT(temp.month) .. FTEXT(temp.day) .. ".csv"
CSVFile = io.open(Fname, "w+")
if CSVFile~=nil then
local rows, col = GetTableSize(T.t_id)
for i=1,col do --расставляем заголовки
CSVFile:write(T[i] .. Sep)
end
CSVFile:write("\n")
for i=1,rows do --пишем таблицу
CSVFile:write(GetRow(T.t_id,i).."\n")
end
CSVFile:flush()
CSVFile:close()
message("Файл успешно сохранен:\n"..Fname, 1)
else
message("Ошибка при сохранении файла:\n"..Fname, 3)
end
end
function round(num, idp) --округляет до указанного количества знаков
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function comma_value(n) --ставит разделители в числах
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1 '):reverse())..right
end
function CreateDataSourceEX(Class,Sec,Par)
local ds,err = CreateDataSource(Class, Sec, INTERVAL_TICK, Par)
if ds==nil then
message("Ошибка при получении параметра "..Par..":\n"..err, 3)
return false
else
ds:SetEmptyCallback()
while ds:Size()==0 do
sleep(100)
end
return true
end
end
function Stop()
if doLogging then
file:close()
end
WORK = false
end
function Calculate(row,do_calc)
if (row~=nil) and (row>=0) and (do_calc) then
local T=BaseCol[row]
local tmpParam ={
["Optiontype"] = T.Optiontype,
["settleprice"] = getParamEx(BaseClassCode,T.Optionbase,"settleprice").param_value+0,
["strike"] = getParamEx(ClassCode,T.SecCode,"strike").param_value+0,
["volatility"] = getParamEx(ClassCode,T.SecCode,"volatility").param_value+0,
["DAYS_TO_MAT_DATE"] = T.DAYS_TO_MAT_DATE
}
local tmpGreek = Greek(tmpParam)
SetCell(tbl.t_id, row, 5, comma_value(tmpParam.settleprice), tmpParam.settleprice) -- "Расчетная цена",
SetCell(tbl.t_id, row, 6, comma_value(tmpParam.strike), tmpParam.strike) --"Страйк",
SetCell(tbl.t_id, row, 7, tostring(tmpParam.volatility), tmpParam.volatility) -- "Волатильность",
SetCell(tbl.t_id, row, 8, tostring(tmpParam.DAYS_TO_MAT_DATE), tmpParam.DAYS_TO_MAT_DATE) --"До исполнения",
SetCell(tbl.t_id, row, 9, tostring(round(tmpGreek.Delta,2)), tmpGreek.Delta) --"Дельта",
SetCell(tbl.t_id, row, 10, tostring(round(tmpGreek.Gamma,4)), tmpGreek.Gamma) -- "Гамма(%)",
SetCell(tbl.t_id, row, 11, tostring(round(tmpGreek.Theta,2)), tmpGreek.Theta) -- "Тэта",
SetCell(tbl.t_id, row, 12, tostring(round(tmpGreek.Vega,2)), tmpGreek.Vega) -- "Вега",
SetCell(tbl.t_id, row, 13, tostring(round(tmpGreek.Rho,2)), tmpGreek.Rho) -- "Ро",
Logging(os.date().. Sep .. GetRow(tbl.t_id,row))
end
return false
end
-------------------------------Колбэки------------------------------------------------------------------
function f_cb(t_id,msg,par1,par2) --событие на нажатие клавиш
if (msg==QTABLE_CHAR) and (par2==19) then --сохранить в CSV файл текущее состояние таблицы нужно нажать комбинацию клавиш Ctrl+S
CSV(tbl)
end
if (msg==QTABLE_CLOSE) then --закрытие окна
Stop()
end
end
function OnStop()
Stop()
DestroyTable(tbl.t_id)
end
function OnInit()
local STR = ""
if doLogging then
file = io.open(log_file, "w+")
end
tbl.t_id = AllocTable()
for i=1,table.maxn(tbl) do --добавляем колонки
if i<=4 then
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_CACHED_STRING_TYPE, string.len(tbl[i])*2)
else
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_DOUBLE_TYPE, 10)
end
if doLogging then
STR=STR..tbl[i]..Sep
end
end
Logging("Дата Время".. Sep .. STR)
CreateWindow(tbl.t_id)
SetWindowCaption(tbl.t_id,tbl.caption)
SetTableNotificationCallback(tbl.t_id, f_cb)
end
function OnParam(class, sec)
if (class==ClassCode) and (WORK) and (string.find(SecList,sec)~=nil) then
G_ROW = Sec2row[sec]
if (G_ROW~=nil) and (G_ROW>=0) then
Highlight(tbl.t_id, G_ROW, QTABLE_NO_INDEX, RGB(255,0,0), QTABLE_DEFAULT_COLOR, INTERVAL)
CALC=true
end
end
end
function main()
WORK = false
CALC=true
for SecCode in string.gmatch(SecList, "([^,]+)") do --перебираем опционы по очереди.
local Optionbase=getParamEx(ClassCode,SecCode,"optionbase").param_image
local Optiontype=getParamEx(ClassCode,SecCode,"optiontype").param_image
if (string.find(BaseSecList,Optionbase)~=nil) then
local row = InsertRow(tbl.t_id,-1)
local T={
["Name"] = getSecurityInfo(ClassCode,SecCode).name,
["SecCode"] = SecCode,
["Optiontype"] = Optiontype,
["Optionbase"] = Optionbase,
["DAYS_TO_MAT_DATE"] = getParamEx(ClassCode,SecCode,"DAYS_TO_MAT_DATE").param_value+0
}
BaseCol[row]=T
--заполняем статичные параметры
Sec2row[SecCode]=row
SetCell(tbl.t_id, row, 1, BaseCol[row].Name) -- "Название опциона",
SetCell(tbl.t_id, row, 2, BaseCol[row].SecCode) --"Код опциона",
SetCell(tbl.t_id, row, 3, BaseCol[row].Optiontype) -- "Тип опциона",
SetCell(tbl.t_id, row, 4, BaseCol[row].Optionbase) --"Баз. актив",
--заказ данных
CreateDataSourceEX(BaseClassCode,T.Optionbase,"settleprice")
CreateDataSourceEX(ClassCode,T.SecCode,"strike")
CreateDataSourceEX(ClassCode,T.SecCode,"volatility")
--заполняем динамичные параметры
CALC=Calculate(row,true)
end
end
WORK = true
while WORK do
CALC=Calculate(G_ROW,CALC)
sleep(INTERVAL)
end
end
Запустил код. Таблица открылась но заполнились только первые четыре колонки до "базового актива" Греки не показывает
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
Для работы скрипта в таблице должны быть добавлены колонки "Расчетная цена", "Страйк", "До исполнения" и "Волатильность" И в этих колонках должны быть данные. Если их нет, проверьте настройки терминала. в меню Настройки - Основные - Программа - Получение данных, должно быть "Исходя из настроек открытых пользователем таблиц
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
В таблицу текущих параметров загнал фьюч и все опционы по этому фьючу Включил все параметры (и волу и теорию и пр) Потом запустил скрипт. Ничего не менял. Инструмент RIU5 и тп Опять не показывает Брокер Октрытие и Втб24 И там и там пусто
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
В таблицу текущих параметров загнал фьюч и все опционы по этому фьючу Включил все параметры (и волу и теорию и пр) Потом запустил скрипт. Ничего не менял. Инструмент RIU5 и тп Опять не показывает Брокер Октрытие и Втб24 И там и там пусто
Могу Вас уверить что данный скрипт прекрасно работает. Проблема именно в настройках о чем было сказано в последнем посте. Если упомянутая выше настройка не помогает, пришлите нам архив всей папки с Вашим терминалом (без ключей доступа) на адрес 911@quik.ru
Именно так и сделал. Опционы по RIU5 открыты в текущей таблице. Сам фьючерс тоже открыт Все равно не показывает греки. Выскакивает таблица а там одна строка и заполнены первые 4 столба
Скрипт останавливается до тех пор пока не получит нужные данные из таблицы текущих параметров. Соответственно, либо какие-либо параметры были указаны неверно (например несуществующий код инструмента опциона) либо доступа к этим данным нет. Если ТТП была открыта после запуска скрипта, попробуйте перезапустить скрипт. Если настройки скрипта менялись, верните их в изначальное положение
Подскажите какие настройки указывать в тек таблице ? Может в этом проблема
max max пишет: Подскажите какие настройки указывать в тек таблице ? Может в этом проблема
Цитата
Sergey Gorokhov пишет: в таблице должны быть добавлены колонки "Расчетная цена", "Страйк", "До исполнения" и "Волатильность" И в этих колонках должны быть данные.
max max пишет: Подскажите какие настройки указывать в тек таблице ? Может в этом проблема
Цитата
Sergey Gorokhov пишет: в таблице должны быть добавлены колонки "Расчетная цена", "Страйк", "До исполнения" и "Волатильность" И в этих колонках должны быть данные.
Все перепроверил. Все равно вот что вылезает
Название Код опциона Тип опциона Баз. актив RTS-9.15M150915CA 20000 RI20000BI5 Call RIU5
Sergey Gorokhov пишет: Если упомянутая выше настройка не помогает, пришлите нам архив всей папки с Вашим терминалом (без ключей доступа) на адрес 911@quik.ru
В текущей версии доступа к таблицы "Доска опционов" нет.
Подскажите когда планируется добавить доступ ? Есть ли возможность минуя доску получить данные по волатильности и теор цене ?
Пожелание зарегистрируем.
Добрый день, Мы рассмотрели Ваше пожелание. По итогам его анализа сообщаем Вам, что реализация пожелания признана потенциально целесообразной. Если по результатам дальнейшего анализа, включающего юридические аспекты, анализ на непротиворечивость с общей политикой компании, никаких возражений не возникнет, мы постараемся включить Ваше пожелание в план доработок при выпуске одной из следующих версий нашего ПО.
Imersio Arrigo написал: Я конечно знаю, что с 95% вероятностью получу ответ: "да у вас формула кривая". И, вероятно, вы будете правы. Поэтому вопрос не в том как посчитать греки самому, а как получить "те же цифры" из квика.
Доска опционов 1 раз в минуту обновляется, по этому у Вас не совпадают цифры
Imersio Arrigo написал: Я конечно знаю, что с 95% вероятностью получу ответ: "да у вас формула кривая". И, вероятно, вы будете правы. Поэтому вопрос не в том как посчитать греки самому, а как получить "те же цифры" из квика.
Доска опционов 1 раз в минуту обновляется, по этому у Вас не совпадают цифры
Здравствуйте, скажите пожалуйста данный скрипт на сегодня актуален, или что то поменялось в расчетах? Так как при запуске на реале и на демо дельту скрипт показывает отличную от дельты транслируемой терминалом на 0,08 - 0,10.
На всякий случай, код скрипта на котором проверяли:
Скрытый текст
Код
--[[
Что делает:
По Таблице текущих параметров строит таблицу опционов с расcчитанными греками
Формулы взяты отсюда:
http://en.wikipedia.org/wiki/Black%96Scholes
http://en.wikipedia.org/wiki/Greeks_%28finance%29
Как использовать:
откройте Таблицу Текущих Параметров (меню Таблицы -> Текущая Таблица)
Укажите настройки, после чего, запустите скрипт (меню Таблицы - Lua - Доступные скрипты)
чтобы сохранить в CSV файл, текущее состояние таблицы, нужно нажать комбинацию клавиш Ctrl+S файл сохраняется в папку со скриптом, с именем HHHMMDD.csv
]]
-------------------------------НАСТРОЙКИ-------------------------------
RiskFree=0/100 --безрисковая ставка %, Указывается вручную
BaseClassCode = "SPBFUT" --Класс базового актива
ClassCode = "SPBOPT" --Класс опционов
--Список базовых активов, через запятую, по которым отображать опционы:
BaseSecList = "RIU7" --getClassSecurities(BaseClassCode) --все сразу
--Список опционов через запятую:
SecList = getClassSecurities(ClassCode) --все сразу
INTERVAL = 1000 --Интервал обновления таблицы
doLogging=false --включает запись в файл, формата csv.
log_file=getScriptPath() .. "\\Greek.csv" --путь к csv файлу
-----------------------------------------------------------------------
-------------------------------ТО ЧТО НИЖЕ, ТРОГАТЬ НЕ НАДО------------------------------------------------------------------
--Параметры таблицы
tbl = {
["caption"]="Greek",
[1]="Название",
[2]="Код опциона",
[3]="Тип опциона",
[4]="Баз. актив",
[5]="Расчетная цена",
[6]="Страйк",
[7]="Волатильность",
[8]="До исполнения",
[9]="Дельта",
[10]="Гамма(%)",
[11]="Тэта",
[12]="Вега",
[13]="Ро",
["t_id"]=0
}
abTable = {}
BaseCol = {}
Sec2row = {}
file = nil
Sep = ";"
YearLen=365.0 --Число дней в году
WORK = true
CALC = false
G_ROW = -1
if (BaseSecList == "") or (BaseSecList == nil) then
BaseSecList = getClassSecurities(BaseClassCode)
end
if (SecList == "") or (SecList == nil) then
SecList = getClassSecurities(ClassCode)
end
-------------------------------ФУНКЦИИ------------------------------------------------------------------
function Logging(str) --Пишет лог
if file~=nil and doLogging then
file:write(str .. "\n")
file:flush()
end
end
function N(x) --Нормальное среднее
if (x > 10) then
return 1
elseif (x < -10) then
return 0
else
local t = 1 / (1 + 0.2316419 * math.abs(x))
local p = 0.3989423 * math.exp(-0.5 * x * x) * t * ((((1.330274 * t - 1.821256) * t + 1.781478) * t - 0.3565638) * t + 0.3193815)
if x > 0 then
p=1-p
end
return p
end
end
function pN(x) --производная от функции нормального среднего
return math.exp(-0.5 * x * x) / math.sqrt(2 * math.pi)
end
function Greek(tmpParam)
local b = tmpParam.volatility / 100 --"b" волатильность доходности (квадратный корень из дисперсии) базисной акции.
local S = tmpParam.settleprice --"S" текущая цена базисной акции;
local Tt = tmpParam.DAYS_TO_MAT_DATE / YearLen --"T-t" время до истечения срока опциона (период опциона);
local K = tmpParam.strike --"K" цена исполнения опциона;
local r = RiskFree --"r" безрисковая процентная ставка;
local d1 = (math.log(S / K) + (r + b * b * 0.5) * Tt) / (b * math.sqrt(Tt))
local d2 = d1-(b * math.sqrt(Tt))
local Delta = 0
local Gamma = 0
local Theta = 0
local Vega = 0
local Rho = 0
local e = math.exp(-1 * r * Tt)
Gamma = pN(d1) / (S * b * math.sqrt(Tt))
Vega = S * e * pN(d1) * math.sqrt(Tt)
Theta = (-1 * S * b * e * pN(d1)) / (2 * math.sqrt(Tt))
if tmpParam.Optiontype == "Call" then
Delta = e * N(d1)
Theta = Theta - (r * K * e * N(d2)) + r * S * e * N(d1)
----Theta = Theta - (r * K * e * N(d2))
Rho = K * Tt * e * N(d2)
else
Delta = -1 * e * N(-1*d1)
Theta = Theta + (r * K * e * N(-1 * d2)) - r * S * e * N(-1 * d1)
----Theta = Theta + (r * K * e * N(-1 * d2))
Rho = -1 * K * Tt * e * N(-1 * d2)
end
return {
["Delta"] = Delta,
["Gamma"] = 100 * Gamma,
["Theta"] = Theta / YearLen,
["Vega"] = Vega / 100,
["Rho"] = Rho / 100
}
end
function GetRow(ID,row) --возвращает строку таблицы
local rows, col = GetTableSize(ID)
local result = ""
if rows~=nil and row<=rows then
for i=1,col do
result=result..GetCell(ID,row,i).image .. Sep
end
end
return result
end
function CSV(T) --пишет таблицу в csv файл
function FTEXT(V) --ПРОВЕРЯЕМ КОРРЕКТНОСТЬ КОЛИЧЕСТВА СИМОЛОВ ПЕРЕМЕННОЙ
V=tostring(V)
if (string.len(V)==1) or (string.len(V)==5) then
V="0".. V
end
return V
end
local temp = os.date("*t")
local Fname =getScriptPath() .. "\\" .. FTEXT(temp.year) .. FTEXT(temp.month) .. FTEXT(temp.day) .. ".csv"
CSVFile = io.open(Fname, "w+")
if CSVFile~=nil then
local rows, col = GetTableSize(T.t_id)
for i=1,col do --расставляем заголовки
CSVFile:write(T[i] .. Sep)
end
CSVFile:write("\n")
for i=1,rows do --пишем таблицу
CSVFile:write(GetRow(T.t_id,i).."\n")
end
CSVFile:flush()
CSVFile:close()
message("Файл успешно сохранен:\n"..Fname, 1)
else
message("Ошибка при сохранении файла:\n"..Fname, 3)
end
end
function round(num, idp) --округляет до указанного количества знаков
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function comma_value(n) --ставит разделители в числах
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1 '):reverse())..right
end
function CreateDataSourceEX(Class,Sec,Par)
local ds,err = CreateDataSource(Class, Sec, INTERVAL_TICK, Par)
if ds==nil then
message("Ошибка при получении параметра "..Par..":\n"..err, 3)
return false
else
ds:SetEmptyCallback()
while (ds:Size()==0) and (WORK) do
sleep(100)
end
return true
end
end
function Stop()
if doLogging then
file:close()
end
WORK = false
end
function Calculate(row,do_calc)
if (row~=nil) and (row>=0) and (do_calc) then
local T=BaseCol[row]
local tmpParam ={
["Optiontype"] = T.Optiontype,
["settleprice"] = getParamEx(BaseClassCode,T.Optionbase,"settleprice").param_value+0,
["strike"] = getParamEx(ClassCode,T.SecCode,"strike").param_value+0,
["volatility"] = getParamEx(ClassCode,T.SecCode,"volatility").param_value+0,
["DAYS_TO_MAT_DATE"] = T.DAYS_TO_MAT_DATE
}
local tmpGreek = Greek(tmpParam)
SetCell(tbl.t_id, row, 5, comma_value(tmpParam.settleprice), tmpParam.settleprice) -- "Расчетная цена",
SetCell(tbl.t_id, row, 6, comma_value(tmpParam.strike), tmpParam.strike) --"Страйк",
SetCell(tbl.t_id, row, 7, tostring(tmpParam.volatility), tmpParam.volatility) -- "Волатильность",
SetCell(tbl.t_id, row, 8, tostring(tmpParam.DAYS_TO_MAT_DATE), tmpParam.DAYS_TO_MAT_DATE) --"До исполнения",
SetCell(tbl.t_id, row, 9, tostring(round(tmpGreek.Delta,2)), tmpGreek.Delta) --"Дельта",
SetCell(tbl.t_id, row, 10, tostring(round(tmpGreek.Gamma,4)), tmpGreek.Gamma) -- "Гамма(%)",
SetCell(tbl.t_id, row, 11, tostring(round(tmpGreek.Theta,2)), tmpGreek.Theta) -- "Тэта",
SetCell(tbl.t_id, row, 12, tostring(round(tmpGreek.Vega,2)), tmpGreek.Vega) -- "Вега",
SetCell(tbl.t_id, row, 13, tostring(round(tmpGreek.Rho,2)), tmpGreek.Rho) -- "Ро",
if doLogging then
Logging(os.date().. Sep .. GetRow(tbl.t_id,row))
end
end
return false
end
-------------------------------Колбэки------------------------------------------------------------------
function f_cb(t_id,msg,par1,par2) --событие на нажатие клавиш
if (msg==QTABLE_CHAR) and (par2==19) then --сохранить в CSV файл текущее состояние таблицы нужно нажать комбинацию клавиш Ctrl+S
CSV(tbl)
end
if (msg==QTABLE_CLOSE) then --закрытие окна
Stop()
end
if (msg==QTABLE_VKEY) and (par2==116) then --функция принудительного обновления таблицы при нажатии клавиши Ctrl+F5
for SecCode in string.gmatch(SecList, "([^,]+)") do --перебираем опционы по очереди.
Calculate(Sec2row[SecCode],true)
Highlight(tbl.t_id, Sec2row[SecCode], QTABLE_NO_INDEX, RGB(255,0,0), QTABLE_DEFAULT_COLOR, INTERVAL)
end
end
end
function OnStop()
Stop()
DestroyTable(tbl.t_id)
end
function OnInit()
local STR = ""
if doLogging then
file = io.open(log_file, "w+")
end
tbl.t_id = AllocTable()
for i=1,table.maxn(tbl) do --добавляем колонки
if i<=4 then
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_CACHED_STRING_TYPE, string.len(tbl[i])*2)
else
AddColumn(tbl.t_id, i, tbl[i], true, QTABLE_DOUBLE_TYPE, 10)
end
if doLogging then
STR=STR..tbl[i]..Sep
end
end
Logging("Дата Время".. Sep .. STR)
CreateWindow(tbl.t_id)
SetWindowCaption(tbl.t_id,tbl.caption)
SetTableNotificationCallback(tbl.t_id, f_cb)
end
function OnParam(class, sec)
if (class==ClassCode) and (WORK) and (string.find(SecList,sec)~=nil) then
G_ROW = Sec2row[sec]
if (G_ROW~=nil) and (G_ROW>=0) then
Highlight(tbl.t_id, G_ROW, QTABLE_NO_INDEX, RGB(255,0,0), QTABLE_DEFAULT_COLOR, INTERVAL)
CALC=true
end
end
end
function main()
WORK = false
CALC=true
for SecCode in string.gmatch(SecList, "([^,]+)") do --перебираем опционы по очереди.
local Optionbase=getParamEx(ClassCode,SecCode,"optionbase").param_image
local Optiontype=getParamEx(ClassCode,SecCode,"optiontype").param_image
if (string.find(BaseSecList,Optionbase)~=nil) then
local row = InsertRow(tbl.t_id,-1)
local T={
["Name"] = getSecurityInfo(ClassCode,SecCode).name,
["SecCode"] = SecCode,
["Optiontype"] = Optiontype,
["Optionbase"] = Optionbase,
["DAYS_TO_MAT_DATE"] = getParamEx(ClassCode,SecCode,"DAYS_TO_MAT_DATE").param_value+0
}
BaseCol[row]=T
--заполняем статичные параметры
Sec2row[SecCode]=row
SetCell(tbl.t_id, row, 1, BaseCol[row].Name) -- "Название опциона",
SetCell(tbl.t_id, row, 2, BaseCol[row].SecCode) --"Код опциона",
SetCell(tbl.t_id, row, 3, BaseCol[row].Optiontype) -- "Тип опциона",
SetCell(tbl.t_id, row, 4, BaseCol[row].Optionbase) --"Баз. актив",
--заказ данных
CreateDataSourceEX(BaseClassCode,T.Optionbase,"settleprice")
CreateDataSourceEX(ClassCode,T.SecCode,"strike")
CreateDataSourceEX(ClassCode,T.SecCode,"volatility")
--заполняем динамичные параметры
CALC=Calculate(row,true)
end
end
WORK = true
while WORK do
CALC=Calculate(G_ROW,CALC)
sleep(INTERVAL)
end
end
local Tt = tmpParam.DAYS_TO_MAT_DATE / YearLen --"T-t" время до истечения срока опциона (период опциона);
значение tmpParam.DAYS_TO_MAT_DATE является целым, то будет получаться погрешность при вычислении времени Tt до истечения срока опциона. Эта погрешность будет относительно небольшой, если до квартальной экспирации ещё долго (как сейчас), а непосредственно перед экспирацией это уже ощутимо. Биржа считает время до истечения точно, вычисляя разницу между текущим моментом и моментом экспирации и переводя в доли года. Давно исследовал этот вопрос, даже разбирался для RI момент экспирации считается 18:45 или 19:00.
c3po написал: Добрый день! Какие способы есть прочитать значения открытых позиций из доски опционов?
На всякий случай:
Цитата
Egor Zaytsev написал: В текущей версии доступа к таблицы "Доска опционов" нет.
Но выход есть. Доска опционов берет данные об открытых позициях из таблицы Позиции по клиентским счетам. А значит, чтобы получить нужную цифру, Вам достаточно обратиться к этой таблице через функцию getItem
c3po написал: Спасибо за ответ. Имелся в виду открытый интерес по страйкам. В текущей версии квика данная колонка названа открытыми позициями.
Прошу прощения, изначально вопрос был понят не правильно. Открытый интерес из таблицы текущих торгов можно получить функцией getParamEx с параметром NUMCONTRACTS