Поймал ошибку "ACCESS VIOLATION" при вызове методов ParamRequest и CancelParamRequest из Lua скрипта индикатора.
Код
2 20:34:58 Function OnChangeSettings: ACCESS VIOLATION at address 00007FF8154C4F69
6 20:35:15 File E:\MOEX\QUIK\LuaIndicators\test.lua, function OnDestroy(): ACCESS VIOLATION at address 00007FFFC6378993
При вызове ParamRequest и CancelParamRequest из Lua скрипта (не индикатора) данная ошибка не наблюдается. Согласно документации, ParamRequest и CancelParamRequest доступны из скрипта индикатора:
Цитата
Список функций, доступных из скрипта индикатора ParamRequest – заказывает получение параметров Таблицы текущих торгов. CancelParamRequest – отменяет заказ на получение параметров Таблицы текущих торгов. getParamEx2 – получает значения всех параметров биржевой информации из Таблицы текущих торгов с возможностью в дальнейшем отказаться от получения определенных параметров.
QUIK версия 9.3.1.11 Lua версия 5.4.1 Код индикатора
Скрытый текст
Код
Settings={}
Settings.Name = "test"
local function pdump(tbl)
local res={} for k,v in pairs(tbl) do res[#res+1]=("%s=%s"):format(k,v) end
return '{'..table.concat(res,', ')..'}'
end
function Init() return 1 end
function OnCalculate(index)
if index == 1 then
message("[Indicator] getParamEx2 'PRICEMAX' " .. pdump(getParamEx2('SPBFUT', 'RIH2', 'PRICEMAX')))
end
return nil
end
function OnChangeSettings()
message("[Indicator] ParamRequest")
message("[Indicator] ParamRequest ".. tostring(ParamRequest('SPBFUT', 'RIH2', 'PRICEMAX')))
end
function OnDestroy()
message("[Indicator] CancelParamRequest")
message("[Indicator] CancelParamRequest ".. tostring(CancelParamRequest('SPBFUT', 'RIH2', 'PRICEMAX')))
end
Вывод индикатора Тип Время Сообщение 1 20:34:58 [Indicator] ParamRequest 2 20:34:58 Function OnChangeSettings: ACCESS VIOLATION at address 00007FF8154C4F69 3 20:34:58 [Indicator] getParamEx2 'PRICEMAX' {param_image=164,990, result=1, param_value=164990.000000, param_type=1} 5 20:35:15 [Indicator] CancelParamRequest 6 20:35:15 File E:\MOEX\QUIK\LuaIndicators\test.lua, function OnDestroy(): ACCESS VIOLATION at address 00007FFFC6378993 Код скрипта
Скрытый текст
Код
local function pdump(tbl)
local res={} for k,v in pairs(tbl) do res[#res+1]=("%s=%s"):format(k,v) end
return '{'..table.concat(res,', ')..'}'
end
function main()
message("[Script] ParamRequest ".. tostring(ParamRequest('SPBFUT', 'RIH2', 'PRICEMAX')))
message("[Script] getParamEx2 'PRICEMAX' " .. pdump(getParamEx2('SPBFUT', 'RIH2', 'PRICEMAX')))
message("[Script] CancelParamRequest ".. tostring(CancelParamRequest('SPBFUT', 'RIH2', 'PRICEMAX')))
end
Вывод скрипта Тип Время Сообщение 1 20:00:56 [Script] ParamRequest true 2 20:00:56 [Script] getParamEx2 'PRICEMAX' {param_image=164,990, param_value=164990.000000, param_type=1, result=1} 3 20:00:56 [Script] CancelParamRequest true
Есть более очевидный аргумент в пользу добавления нового параметра "Изменение открытого интереса" в таблицу обезличенных сделок - это возможность включить фильтрацию в таблице.
При включенном фильтре в таблице обезличенных сделок "Открытый интерес" сам по себе уже смысла не имеет. Нужно именно значение "Изменение открытого интереса" относительно предыдущей сделки, которая чаще всего в фильтр уже не попадает и не видна в таблице в данном случае.
Roman Azarov, в моем предыдущем примере точности до микросекунд не потребовалось. Но, все же это частный случай. Тот же тест с микросекундами + статистика
Скрытый текст
Код
local max,min,cnt,sum,prev = 0,999999,0,0,nil
local statmsg = [[
'sysdate.mcs' step-up:
max %d
min %d
mean %f
]]
local function fwrite(fmt, ...)
local file = io.open(getScriptPath() .. "\\testSysDate.txt", "a")
file:write(fmt:format(...))
file:flush()
file:close()
end
local function trace(level, msg)
local sysdate = os.sysdate()
if prev and prev.mcs ~= sysdate.mcs then
local delta = sysdate.mcs - prev.mcs
delta = delta < 0 and 1000000 + delta or delta
max = math.max(max, delta)
min = math.min(min, delta)
sum = sum + delta
cnt = cnt + 1
end
prev = sysdate
local local_t = ("%02d:%02d:%04d %02d:%02d:%02d.%06d"):format(
sysdate.day, sysdate.month, sysdate.year, sysdate.hour, sysdate.min, sysdate.sec, sysdate.mcs)
local _, clock_frac = math.modf(os.clock())
local ms = math.floor(clock_frac*1000)
fwrite("%s %d [%s] : %s\n", local_t, ms, level, msg)
end
local function testSysDate()
for i = 0,getNumberOf("classes") - 1 do
local code = getItem("classes", i).code
trace("info", "Class " .. code)
end
fwrite("\n\n")
fwrite(statmsg, max, min, sum/cnt)
end
function main() testSysDate() end
вывод:
Скрытый текст
12:04:2021 08:37:56.910212 935 [info] : Class CROSSRATE 12:04:2021 08:37:56.910212 939 [info] : Class EQOB 12:04:2021 08:37:56.910212 944 [info] : Class PSAU 12:04:2021 08:37:56.910212 948 [info] : Class PSBB 12:04:2021 08:37:56.925821 952 [info] : Class PSSU 12:04:2021 08:37:56.925821 957 [info] : Class EQDB 12:04:2021 08:37:56.925821 961 [info] : Class SMAL 12:04:2021 08:37:56.925821 965 [info] : Class TQBR 12:04:2021 08:37:56.941460 969 [info] : Class TQDE 12:04:2021 08:37:56.941460 972 [info] : Class TQOB 12:04:2021 08:37:56.941460 978 [info] : Class TQIF 12:04:2021 08:37:56.957085 981 [info] : Class TQTF 12:04:2021 08:37:56.957085 987 [info] : Class SPEQ 12:04:2021 08:37:56.957085 990 [info] : Class TQTD 12:04:2021 08:37:56.957085 994 [info] : Class TQOD 12:04:2021 08:37:56.972708 998 [info] : Class SPOB 12:04:2021 08:37:56.972708 3 [info] : Class TQBE 12:04:2021 08:37:56.972708 7 [info] : Class TQTE 12:04:2021 08:37:56.972708 11 [info] : Class TQCB 12:04:2021 08:37:56.988317 16 [info] : Class AFXCURR1 12:04:2021 08:37:56.988317 21 [info] : Class INDX 12:04:2021 08:37:56.988317 25 [info] : Class RTSIDX 12:04:2021 08:37:57.003941 29 [info] : Class USDRUB 12:04:2021 08:37:57.003941 33 [info] : Class CETS 12:04:2021 08:37:57.003941 37 [info] : Class INDXC 12:04:2021 08:37:57.003941 42 [info] : Class SPBFUT 12:04:2021 08:37:57.019581 46 [info] : Class SPBOPT 12:04:2021 08:37:57.019581 52 [info] : Class FUTSPREAD 12:04:2021 08:37:57.019581 57 [info] : Class INSTR 12:04:2021 08:37:57.035188 63 [info] : Class INOS 12:04:2021 08:37:57.035188 67 [info] : Class INOSNV 12:04:2021 08:37:57.035188 70 [info] : Class SPBXM 12:04:2021 08:37:57.050813 76 [info] : Class TQOE 12:04:2021 08:37:57.050813 79 [info] : Class TQRD 12:04:2021 08:37:57.050813 85 [info] : Class TQUD 12:04:2021 08:37:57.050813 88 [info] : Class TQED 12:04:2021 08:37:57.066457 94 [info] : Class TQIR 12:04:2021 08:37:57.066457 97 [info] : Class TQIU 12:04:2021 08:37:57.066457 103 [info] : Class TQIE 12:04:2021 08:37:57.082060 106 [info] : Class TQPI 12:04:2021 08:37:57.082060 112 [info] : Class INSTR_SYSTEM 12:04:2021 08:37:57.082060 117 [info] : Class FQBR 12:04:2021 08:37:57.097701 122 [info] : Class FQDE 12:04:2021 08:37:57.097701 127 [info] : Class PSBB_EQ 12:04:2021 08:37:57.097701 131 [info] : Class TQFD 12:04:2021 08:37:57.097701 136 [info] : Class TQFE 12:04:2021 08:37:57.113308 140 [info] : Class TQPD 12:04:2021 08:37:57.113308 145 [info] : Class TQPE
'sysdate.mcs' step-up: max 15644 min 15603 mean 15622.769231
'sysdate.mcs' step-up: 'sysdate.mcs' step-up: 'sysdate.mcs' step-up: max 15644 max 17826 max 15640 min 15603 min 3049 min 1065 mean 15622.769231 mean 13450.000000 mean 12378.941176 Сейчас уже лучше видно, что os.sysdate имеет реальную точность ~16 msec +/-, как и было отмечено выше уже.
Цитата
Roman Azarov написал: os.sysdate в отличие от os.clock вызывает в довесок к winapi'шной GetSystemTimeAsFileTime ещё и конвертацию через FileTimeToSystemTime. В последней и происходит округление миллисекунд.
т.е. пока получается, что реализация в полной мере не соответствует заявленному поведению в документациии в документации нет примечания, что есть определенная погрешность в результате, выдаваемом функцией
Sergey Gorokhov написал: в терминале версии 7.16 добавлена функция os.sysdate, позволяющая получить локальное время с точностью до микросекунд
обнаружил, что полученные из os.sysdate миллисекунды/микросекунды прирастают неравномерно, скачкообразно ниже сравнил вывод sysdate.ms с os.clock() версия QUIK 8.12.0.41
Код
function trace(level, msg)
local sysdate = os.sysdate()
local local_t = ("%02d:%02d:%04d %02d:%02d:%02d.%03d"):format(
sysdate.day, sysdate.month, sysdate.year, sysdate.hour, sysdate.min, sysdate.sec, sysdate.ms)
local _, clock_frac = math.modf(os.clock())
local ms = ("%d"):format(math.floor(clock_frac*1000))
local file = io.open(getScriptPath() .. "\\testSysDate.txt", "a")
file:write(("%s %s [%s] : %s\n"):format(local_t, ms, level, msg))
file:flush()
file:close()
end
function testSysDate()
for i = 0,getNumberOf("classes") - 1 do
local code = getItem("classes", i).code
trace("info", "Class " .. code)
end
end
function main() testSysDate() end
вывод
Скрытый текст
28:03:2021 02:00:46.340 210 [info] : Class CROSSRATE 28:03:2021 02:00:46.342 220 [info] : Class EQOB 28:03:2021 02:00:46.358 228 [info] : Class PSAU 28:03:2021 02:00:46.358 236 [info] : Class PSBB 28:03:2021 02:00:46.358 242 [info] : Class PSSU 28:03:2021 02:00:46.373 247 [info] : Class EQDB 28:03:2021 02:00:46.373 254 [info] : Class SMAL 28:03:2021 02:00:46.389 260 [info] : Class TQBR 28:03:2021 02:00:46.389 265 [info] : Class TQDE 28:03:2021 02:00:46.389 272 [info] : Class TQOB 28:03:2021 02:00:46.405 278 [info] : Class TQIF 28:03:2021 02:00:46.405 283 [info] : Class TQTF 28:03:2021 02:00:46.405 290 [info] : Class SPEQ 28:03:2021 02:00:46.420 296 [info] : Class TQTD 28:03:2021 02:00:46.420 301 [info] : Class TQOD 28:03:2021 02:00:46.436 308 [info] : Class SPOB 28:03:2021 02:00:46.436 314 [info] : Class TQBE 28:03:2021 02:00:46.436 319 [info] : Class TQTE 28:03:2021 02:00:46.451 325 [info] : Class TQCB 28:03:2021 02:00:46.451 332 [info] : Class AFXCURR1 28:03:2021 02:00:46.467 337 [info] : Class INDX 28:03:2021 02:00:46.467 344 [info] : Class RTSIDX 28:03:2021 02:00:46.467 351 [info] : Class USDRUB 28:03:2021 02:00:46.483 356 [info] : Class CETS 28:03:2021 02:00:46.483 362 [info] : Class INDXC 28:03:2021 02:00:46.483 369 [info] : Class SPBFUT 28:03:2021 02:00:46.498 375 [info] : Class SPBOPT 28:03:2021 02:00:46.498 380 [info] : Class FUTSPREAD 28:03:2021 02:00:46.514 388 [info] : Class INSTR 28:03:2021 02:00:46.514 394 [info] : Class INOS 28:03:2021 02:00:46.514 399 [info] : Class INOSNV 28:03:2021 02:00:46.530 411 [info] : Class SPBXM 28:03:2021 02:00:46.545 416 [info] : Class TQOE 28:03:2021 02:00:46.545 424 [info] : Class TQRD 28:03:2021 02:00:46.545 431 [info] : Class TQUD 28:03:2021 02:00:46.561 436 [info] : Class TQED 28:03:2021 02:00:46.561 442 [info] : Class TQIR 28:03:2021 02:00:46.576 449 [info] : Class TQIU 28:03:2021 02:00:46.576 454 [info] : Class TQIE 28:03:2021 02:00:46.576 461 [info] : Class TQPI 28:03:2021 02:00:46.592 468 [info] : Class INSTR_SYSTEM 28:03:2021 02:00:46.592 475 [info] : Class FQBR 28:03:2021 02:00:46.608 481 [info] : Class FQDE 28:03:2021 02:00:46.608 487 [info] : Class PSBB_EQ 28:03:2021 02:00:46.623 495 [info] : Class TQFD 28:03:2021 02:00:46.623 501 [info] : Class TQFE 28:03:2021 02:00:46.623 507 [info] : Class TQPD 28:03:2021 02:00:46.639 514 [info] : Class TQPE
28:03:2021 02:00:46.358228 [info] : Class PSAU 28:03:2021 02:00:46.358236 [info] : Class PSBB 28:03:2021 02:00:46.358242 [info] : Class PSSU .. 28:03:2021 02:00:46.389260 [info] : Class TQBR 28:03:2021 02:00:46.389265 [info] : Class TQDE 28:03:2021 02:00:46.389272 [info] : Class TQOB ... 389 - sysdate.ms 272 - fractional part of os.clock() -- milliseconds precision