вторник, 31 мая 2022 г.
суббота, 21 мая 2022 г.
Lua, Script, Sint, Bonds
Sint, Bonds c Валютой
- -- Synthetic Bonds For QUIK
- -- v1.0
- -- (c) Aphelion, 2021
- --[[
- Для корректной работы скрипта необходимо в настройках заказать получение данных по классам:
- SPBFUT (FORTS), TQBR (МБ ФР: T+ Акции и Др) и FQBR (МБ ФР: T+ Ин.Акции и Др)
- Фильтры по инструментам и параметрам должны быть выключены.
- ]]--
- local requiredYield = 8 -- Показывать синт. облигации с доходностью не ниже X % годовых
- local requiredDaysToMaturity = 30 -- Показывать синт. облигации со сроком жизни не меньше X дней
- local symbols = {
- -- Код фьючерса = {Класс Акции, Код Акции}
- AF = {'TQBR', 'AFLT'},
- AL = {'TQBR', 'ALRS'},
- CH = {'TQBR', 'CHMF'},
- FS = {'TQBR', 'FEES'},
- GZ = {'TQBR', 'GAZP'},
- GK = {'TQBR', 'GMKN'},
- HY = {'TQBR', 'HYDR'},
- LK = {'TQBR', 'LKOH'},
- MN = {'TQBR', 'MGNT'},
- ME = {'TQBR', 'MOEX'},
- MT = {'TQBR', 'MTSS'},
- NM = {'TQBR', 'NLMK'},
- NK = {'TQBR', 'NVTK'},
- RN = {'TQBR', 'ROSN'},
- RT = {'TQBR', 'RTKM'},
- SP = {'TQBR', 'SBERP'},
- SR = {'TQBR', 'SBER'},
- SG = {'TQBR', 'SNGSP'},
- SN = {'TQBR', 'SNGS'},
- TT = {'TQBR', 'TATN'},
- TN = {'TQBR', 'TRNFP'},
- VB = {'TQBR', 'VTBR'},
- MG = {'TQBR', 'MAGN'},
- PZ = {'TQBR', 'PLZL'},
- YN = {'TQBR', 'YNDX'},
- AK = {'TQBR', 'AFKS'},
- IR = {'TQBR', 'IRAO'},
- PO = {'TQBR', 'POLY'},
- TI = {'TQBR', 'TCSG'},
- FV = {'TQBR', 'FIVE'},
- ML = {'TQBR', 'MAIL'},
- OZ = {'TQBR', 'OZON'},
- PI = {'TQBR', 'PIKK'},
- BA = {'FQBR', 'BABA-RM'},
- BI = {'FQBR', 'BIDU-RM'}
- }
- local running = true
- local bondsTable = nil
- local index = {}
- function main()
- local result = indexFutures()
- if not result then
- message('SBonds: Failed To Index Futures', 3)
- do return end
- end
- createSyntheticBondsTable()
- while running do
- calculateYields()
- sleep(1000)
- end
- end
- function indexFutures()
- local SPBFUT = getClassSecurities('SPBFUT')
- local matches = string.gmatch(SPBFUT, '([^,]+)')
- local count = 0
- for futures in matches do
- local futuresCode = string.sub(futures, 1, 2)
- if symbols[futuresCode] ~= nil then
- if index[futuresCode] == nil then
- index[futuresCode] = {}
- count = count + 1
- end
- index[futuresCode][#index[futuresCode] + 1] = {
- code = futures,
- scale = getSecurityInfo('SPBFUT', futures).scale,
- size = getSecurityInfo('SPBFUT', futures).lot_size,
- expiration = string.format('%.0f', getParamEx('SPBFUT', futures, 'MAT_DATE').param_value)
- }
- end
- end
- if count == 0 then
- return false
- end
- return true
- end
- function calculateYields()
- local tableIndex = {}
- local rows, _ = GetTableSize(bondsTable)
- for i = 1, rows do
- local cell = GetCell(bondsTable, i, 0)
- tableIndex[cell.image] = i
- end
- for futuresCode, items in pairs(index) do
- if symbols[futuresCode] ~= nil then
- for _, item in pairs(items) do
- local class = symbols[futuresCode][1]
- local stock = symbols[futuresCode][2]
- if isTrading(class, stock) and isTrading('SPBFUT', item.code) then
- local futuresBid = tonumber(getParamEx('SPBFUT', item.code, 'BID').param_value)
- local stockAsk = tonumber(getParamEx(class, stock, 'OFFER').param_value)
- if futuresBid > 0 and stockAsk > 0 then
- local term = timeToMaturity(item.expiration)
- local yield = (futuresBid - stockAsk * item.size) / term / (stockAsk * item.size) * 100
- if term >= requiredDaysToMaturity / 365 and yield >= requiredYield then
- local bond = stock .. ' x ' .. item.code
- local row = tableIndex[bond]
- if row == nil then
- row = InsertRow(bondsTable, -1)
- SetCell(bondsTable, row, 0, bond)
- end
- local stockScale = getSecurityInfo(class, stock).scale
- SetCell(bondsTable, row, 1, string.format('%.' .. stockScale .. 'f', stockAsk), stockAsk)
- SetCell(bondsTable, row, 2, string.format('%.' .. item.scale .. 'f', futuresBid), futuresBid)
- SetCell(bondsTable, row, 3, string.format('%.0f', term * 365), term * 365)
- SetCell(bondsTable, row, 4, string.format('%.2f', yield) .. '%', yield)
- tableIndex[bond] = nil
- end
- end
- end
- end
- end
- end
- for _, row in pairs(tableIndex) do
- DeleteRow(bondsTable, row)
- end
- end
- function OnStop()
- DestroyTable(bondsTable)
- running = false
- return 0
- end
- function createSyntheticBondsTable()
- bondsTable = AllocTable()
- AddColumn(bondsTable, 0, 'Bond', true, QTABLE_STRING_TYPE, 17)
- AddColumn(bondsTable, 1, 'Stock Ask', true, QTABLE_DOUBLE_TYPE, 12)
- AddColumn(bondsTable, 2, 'Futures Bid', true, QTABLE_DOUBLE_TYPE, 12)
- AddColumn(bondsTable, 3, 'Days', true, QTABLE_DOUBLE_TYPE, 10)
- AddColumn(bondsTable, 4, 'Yield', true, QTABLE_DOUBLE_TYPE, 12)
- CreateWindow(bondsTable)
- SetWindowCaption(bondsTable, 'Synthetic Bonds')
- SetWindowPos(bondsTable, 0, 0, 460, 230)
- SetTableNotificationCallback(bondsTable, tableNotificationCallback)
- end
- function tableNotificationCallback(sender, event, param1, param2)
- if sender == bondsTable and event == QTABLE_CLOSE then
- running = false
- end
- end
- function isTrading(class, security)
- local status = tonumber(getParamEx(class, security, class == 'SPBFUT' and 'STATUS' or 'TRADINGSTATUS').param_value)
- return status == 1
- end
- function timeToMaturity(string)
- local year = string.sub(string, 1, 4)
- local month = string.sub(string, 5, 6)
- local day = string.sub(string, 7, 8)
- local date = os.time({
- day = tonumber(day),
- year = tonumber(year),
- month = tonumber(month),
- hour = 18,
- min = 45,
- sec = 0
- })
- local time = os.difftime(date, os.time()) / (365 * 24 * 60 * 60)
- return time
- end
Подписаться на:
Комментарии (Atom)