Сейчас, 12 февраля в 02 часа ночи, однако результат исполнения кода дает время - 9 февраля, 12 часов дня. При этом в строке сообщений Quik время выводится верное (оно берется из компа?) Выглядит строка сообщений приблизительно так: 2:17:29 09-12:17:29
Почему время сервера сильно отстает от реального? У меня из-за этого проблемы с исполнением кода...
Время в сообщениях, это время Вашего компьютера. SERVERTIME это время сервера. И эти времена совершенно не обязаны совпадать. Никто кроме Вас не может гарантировать что время на Вашем компьютере синхронизировано с компьютером брокера.
TRADEDATE показывает дату торговой сессии. Это не тоже самое что астрономическая дата. Дата торговой сессии это дата когда проводились торги. Последний раз они проводились в пятницу, 9-го числа.
Время в сообщениях, это время Вашего компьютера. SERVERTIME это время сервера. И эти времена совершенно не обязаны совпадать. Никто кроме Вас не может гарантировать что время на Вашем компьютере синхронизировано с компьютером брокера.
TRADEDATE показывает дату торговой сессии. Это не тоже самое что астрономическая дата. Дата торговой сессии это дата когда проводились торги. Последний раз они проводились в пятницу, 9-го числа.
1. Все нормально синхронизировано. На компьютере время точное - проблема не в этом, а как Вы верно заметили, в том что сервер выдает время последних торгов, которое не всегда актуально. 2. Это значит, что считывание актуального времени (в виде таблицы) с помощью квик и луа -- простейшая, казалось бы, задача, -- становится очень нетривиальным действом. Просто так считать с помощью date | time его нельзя. Необходимо рассчитывать разницу между поясным временем и временем Гринвича, конвертировать время в формат POSIX, добавлять нужную величину, а затем конвертировать время POSIX в таблицу. Т.е. получение ключевого простейшего показателя требует выполнения четырех ресурсоемких функций!! Или может я что-то недопонимаю и есть более простой путь?
А что Вы хотите получить? Если Дату/Время Вашего компьютера, то есть штатная Lua функция os.date()
Нееет... эта функция возвращает время по Гринвичу, которое не совпадает с локальным временем компьютера и с временем сервера. Я уже реализовал получение точного локального времени, но выглядит эта конструкция очень громоздко - потребовалось 8 операций, включая 5 вызовов функции даты и времени!
-- ТЕКУЩЕЕ ЛОКАЛЬНОЕ (ПОЯСНОЕ) ВРЕМЯ (POSIX + ТАБЛИЦА) function fTimeLocal(offset) -- offset - смещение поясного времени в секундах (целое положительное или отрицательное цифровое значение) if offset == nil then offset = os.offset() ; end -- если не получили временной сдвиг, рассчитываем его по стандартной функции local posix = os.time()-- считываем текущее время ПК в формате POSIX posix = posix + offset-- добавляем поясной сдвиг local datetime = os.date("!*t", posix)-- переводим в формат таблицы return posix, datetime-- возвращаем полученные значения end
-- СМЕЩЕНИЕ ВРЕМЕНИ ОТНОСИТЕЛЬНО ГРИНВИЧА ЛОКАЛЬНОЕ / ПОЯСНОЕ ВРЕМЯ К ГРИНВИЧУ - (СЕКУНДЫ) function os.offset() local currenttime = os.time() local datetime = os.date("!*t",currenttime) datetime.isdst = true -- Флаг дневного времени суток return currenttime - os.time(datetime) end
Иван Ру написал: Нееет... эта функция возвращает время по Гринвичу, которое не совпадает с локальным временем компьютера и с временем сервера.
Это не так.
Код
message ( 'time=' .. os.date ())
Попробуйте получить время posix с помощью os.time, а затем конвертировать его во время в табличном формате. Получится рассинхронизация Посмотрите на пример кода и полученный результат
КОД: local posix = os.time() message ('os.time()'.."-"..tostring(posix)) local ttime = os.date() message ('os.date()'.."-"..tostring(ttime)) local posixToDate = os.date("!*t", posix) local posixToDateStr = posixToDate.hour..":"..posixToDate.min message ('Convert os.date() result to posix'.."-"..tostring(posixToDateStr))
РЕЗУЛЬТАТ ИСПОЛНЕНИЯ:
Мои скрипты первоначально считывали время и дату сервера и уже ее конвертировали в формат posix, но я столкнулся с проблемой -- периодически выскакивала ошибка типа "в таблице отсутствует поле day/hour и т.п.). Каких либо закономерностей не обнаружил, я так понял, что это связано с потерей пакетов при загрузке интернет-канала или какими-то другими проблемами связанными с соединением локальной машины и сервера -- поэтому от этого способа пришлось отказаться.
надо только добавить, что так можно делать только если часовой пояс вашего компьютера совпадает с часовым поясом биржи или Квик настроен на трансляцию времени в локальном поясном времени. В остальных случаях будет по прежнему несостыковка
Sergey Gorokhov написал: Иван Ру , Уберите знак "!"
Код
local posixToDate = os.date ( "*t" , posix)
надо только добавить, что так можно делать только если часовой пояс вашего компьютера совпадает с часовым поясом биржи или Квик настроен на трансляцию времени в локальном поясном времени. В остальных случаях будет по прежнему несостыковка
Совпадают. В принципе для обхода проблемы я применял вот такие функции, пользуйтесь кому нужно и критикуйте кто может
-- ТЕКУЩЕЕ ВРЕМЯ ПО ГРИНВИЧУ (ТАБЛИЦА) function fTimeGrinvichTable() dtServ = {}; dtServ = os.date("!*t",os.time()) for key,value in pairs(dtServ) do dtServ[key] = tonumber(value) end return dtServ end
-- ТЕКУЩЕЕ ЛОКАЛЬНОЕ (ПОЯСНОЕ) ВРЕМЯ (POSIX) function fTimeLocalPosix(offset) -- offset - смещение поясного времени в секундах (целое положительное или отрицательное цифровое значение) if offset == nil then offset = os.offset() ; end -- если не удалось считать временной сдвиг, рассчитываем его по стандартной функции local posix = os.time()-- считываем текущее время ПК в формате POSIX posix = posix + offset-- добавляем поясной сдвиг return posix -- возвращаем полученные значения end
-- ТЕКУЩЕЕ ЛОКАЛЬНОЕ (ПОЯСНОЕ) ВРЕМЯ (POSIX + ТАБЛИЦА) function fTimeLocal(offset) -- offset - смещение поясного времени в секундах (целое положительное или отрицательное цифровое значение) if offset == nil then offset = os.offset() ; end -- если не удалось считать временной сдвиг, рассчитываем его по стандартной функции local posix = os.time()-- считываем текущее время ПК в формате POSIX posix = posix + offset-- добавляем поясной сдвиг local datetime = os.date("!*t", posix)-- переводим в формат таблицы return posix, datetime-- возвращаем полученные значения end
-- СМЕЩЕНИЕ ВРЕМЕНИ ОТНОСИТЕЛЬНО ГРИНВИЧА ЛОКАЛЬНОЕ / ПОЯСНОЕ ВРЕМЯ К ГРИНВИЧУ - (СЕКУНДЫ) function os.offset() local currenttime = os.time() local datetime = os.date("!*t",currenttime) datetime.isdst = true -- Флаг дневного времени суток return currenttime - os.time(datetime) end
-- ДОПОЛНЕНИЕ ТАБЛИЦЫ ВРЕМЕНИ (Добавляет к поляем времени поля текущей даты, а также поле 'posix' с данными в соотв. формате) function curDayToPosix (timeTab, dateTab, offset) -- timeTab -- таблица со временем, но без полей дат, dateTab - таблица с полями дат if offset == nil then offset = os.offset() ; end -- если не удалось считать временной сдвиг, рассчитываем его по стандартной функции -- устанавливаем в поля даты значения текущего дня timeTab.year = dateTab.year timeTab.month = dateTab.month timeTab.day = dateTab.day timeTab.posix = os.time (timeTab) + offset end
Смещение локального часового пояса относительно Гринвича в виде таблицы: os.date("*t", 0) (по часам компьютера с учетом региональных настроек операционки, корректно работает для всех случаев, в т.ч. особые часовые пояса, в которых нет перевода на летнее/зимнее время и в тех, где смещение не в целых часах; может Вы из Тегерана торгуете )
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
Данное поведение обусловлено, дополнительным вызовом функции конвертации, в которой происходит округление миллисекунд, в os.sysdate(). Это корректное поведение в сравнении этих двух функций.
Функция возвращает системные дату и время с точностью до микросекунд.
Цитата
Roman Azarov написал: Данное поведение обусловлено, дополнительным вызовом функции конвертации, в которой происходит округление миллисекунд, в os.sysdate().
Это как? Что во что конвертируется и по каким правилам округляется?
Надо делать так, как надо. А как не надо - делать не надо.
В примере пользователя Иван речь идет именно о миллисекундах. os.sysdate в отличие от os.clock вызывает в довесок к winapi'шной GetSystemTimeAsFileTime ещё и конвертацию через FileTimeToSystemTime. В последней и происходит округление миллисекунд.
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. В последней и происходит округление миллисекунд.
т.е. пока получается, что реализация в полной мере не соответствует заявленному поведению в документациии в документации нет примечания, что есть определенная погрешность в результате, выдаваемом функцией