Материал статьи взят здесь: http://www.bot4sale.ru/blog-menu/qlua/spisok-statej/368-lua-time.html
Дата/время в QLua(Lua) может быть представлено либо в виде секунд, прошедших с полуночи 1 января 1970 года, либо в виде таблицы, имеющей следующие поля:
year - год (четыре цифры)
month - месяц (1 – 12)
day - день (1 – 31)
hour - час (0 – 23)
min - минуты (0 – 59)
sec - секунды (0 – 59)
wday - день недели (1 - 7), воскресенью соответствует 1
yday - день года
isdst - флаг дневного времени суток, тип boolean
Встроенные функции:
os.clock() - возвращает время в секундах с точностью до миллисекунд с момента запуска приложения, в нашем случае QUIK. Пример: 1544.801
os.time() - возвращает время в секундах, прошедших с полуночи 1 января 1970 года, может принимать вышеописанную таблицу, в качестве аргумента, без аргументов возвращает текущее время
os.date() - возвращает форматированные дату/время, первым аргументом принимает формат, вторым аргументом принимает время в секундах. Аргументы не обязательны. Если не передать 2-й аргумент, функция вернет текущие дату/время компьютера. Если функцию вызвать вообще без аргументов, то она вернет текущие дату/время компьютера в виде 03/22/15 22:28:11
В строке формата можно использовать следующие опции:
%a - день недели, сокр. (англ.) (пример, Wed) %A - день недели, полностью (англ.) (пример, Wednesday) %b - месяц, сокр. (англ.) (пример, Sep) %B - месяц, полностью (англ.) (пример, September) %c - дата и время (по-умолчанию) (пример, 03/22/15 22:28:11) %d - день месяца (пример, 22) [диапазон, 01-31] %H - час, в 24-х часовом формате (пример, 23) [диапазон, 00-23] %I - час, в 12-и часовом формате (пример, 11) [диапазон, 01-12] %M - минута (пример, 48) [диапазон, 00-59] %m - месяц (пример, 09) [диапазон, 01-12] %p - время суток "am", или "pm" %S - секунда (пример, 10) [диапазон, 00-59] %w - день недели (пример, 3) [диапазон, 0-6, соответствует Sunday-Saturday] %x - дата (пример, 09/16/98) %X - время (пример, 23:48:10) %Y - год, 4 цифры (пример, 2015) %y - год, 2 цифры (пример, 15) [00-99] %% - символ "%" *t - вернет таблицу !*t - вернет таблицу (по Гринвичу)
Примеры:
-- Представить произвольное время в секундах datetime = { year = 2015, month = 03, day = 22, hour = 22, min = 28, sec = 11 }; seconds = os.time(datetime); -- в seconds будет значение 1427052491 -- Представить время в секундах в виде таблицы datetime datetime = os.date("*t",seconds); -- Преобразование строки даты/времени в таблицу datetime dt = {}; dt.day,dt.month,dt.year,dt.hour,dt.min,dt.sec = string.match("22/03/2015 22:28:11","(%d*)/(%d*)/(%d*) (%d*):(%d*):(%d*)"); for key,value in pairs(dt) do dt[key] = tonumber(value) end -- А так можно получить текущие дату/время сервера в виде таблицы datetime dt = {}; dt.day,dt.month,dt.year,dt.hour,dt.min,dt.sec = string.match(getInfoParam('TRADEDATE')..' '..getInfoParam('SERVERTIME'),"(%d*).(%d*).(%d*) (%d*):(%d*):(%d*)") for key,value in pairs(dt) do dt[key] = tonumber(value) end |
Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!
Привет.
так получили день недели компьютера, а как получить день недели серверного времени?
Привет.
Спасибо - Супер
Подскажите, пожалуйста, как решить проблему: при разрыве связи и повторного подключения квика скрипт выдает ошибку: field 'day' missing in date table.
Квик указывает на строку: seconds_opt_Si = os.time(datetime_opt_Si)
Привет!
А к чему такой огород?
getParamEx (class_code, sec_code, "MAT_DATE").param_value и так вернет дату в формате "dd.mm.YY"
и MAT_DATE в опционах периодически отсутствует, попробуйте EXPDATE
getParamEx (class_code, sec_code, "MAT_DATE").param_value
Возвращает 20200709, а мне нужно 09.07.2020
да-да в поле param_image нужный вам формат:
getParamEx(class_code, sec_code, "mat_date").param_image
Да, так остается скрипт запущен, после установки соединения.
Спасибо большое!
Пожалуйста, рад, что помог.
как время с компа отобразить в коде? мне нужно чтоб в углу экрана выводилось время с компа или сервера без разницы. помогите
Добрый день! Подскажите, как можно ускорить работу индикатора (например, чтобы при запуске источника данных действие индикатора было ограничено сегодняшним днём или каким-либо периодом). А то при запуске индикатор считает всю историю (пробегает по всем свечам) и КВИК просто зависает.
Здравствуйте, Роман.
Не знаю что у Вас за алгоритм, возможно действительно очень сложные вычисления выполняются, но может пересмотреть код, оптимизировать его как то.
Вообще заставить Квик не пробегать по всем свечкам не получится, можно заставить пропускать. Можете при вызове OnCalculate запросить Дату Время бара, произвести сравнение с текущим днем и если бар относится к текущему дню, тогда производить вычисления, иначе вернуть nil
Так же учтите, что Квик "пробегает" по свечкам не 1 раз, а 2 или даже 3 раза, зачем, трудно сказать, но факт есть факт.
Приведу пример вычисления над барами за текущий день
Спасибо, Павел! А то я уж тоже начал задумываться об ограничении времени. Иначе запросишь какой-нибудь текущий параметр на график, и, хорошо, если часовики или дневки, а на минутках всё намертво стоит секунд по 15))!
в qlua в таблице Стоп-заявок stop_orders параметр время выставления стоп-заявки ordertime в чем измеряется? в каком формате? и как его перевести в формат часы: минуты: секунды или в секунды
Здравствуйте, там число, я думаю, ЧЧММСС, типа, 121510, хотя не уверен на 100%, ни разу его не использовал, если число, то можно его перевести в строку и получить из нее составляющие по принципу как сделано в функции StrToTime, которая находится в разделе "Нужные функции"
А в таблице сделок, сделки всегда идут в правильном хронологическом порядке? Допустим я хочу получить определенные "свежие сделки", совершенные после 19:00, могу ли я сделать "пробежку" по таблице с конца, и проверять ,условно если getItem("trades",i).datetime > 19:00 то обрабатываю сделку. Как только getItem("trades",i).datetime <= 19:00 прекратить цикл. Т.е. не окажется ли в таблице сделок "затерявшаяся" , из-за нарушения хронологического порядка? И соответственно может лучше пробегаться по всей таблице, а не прерывать цикл?
Ну и заодно, такой же вопрос по номерам сделок. Вроде бы они в таблице всегда идут по порядку, чем более свежая сделка, тем номер у нее больше. Но тут я совсем не уверен, что порядок всегда будет соблюден.
Привет!
Если у вас в квике 1 рынок подключен, например срочный, то хронология будет соблюдена, если подключен еще и фондовый, то хронология не будет соблюдена и последовательности номеров сделок (и таймштампов) не будет, вплоть до 18-50. (после 19-00 нормально).
Решение: фильтр по интересующему рынку.
А так все правильно, нашли первую строку с таймштампом < 19:00, запомнили № стр + 1, и больше обратный цикл не нужно вызывать.
Посчитали что есть от № стр + 1 , до последней сделки и запомнили № строки последней сделки и следующий раз уже от неё плясать.
Спасибо, все понятно объяснили. Хотелось бы еще уточнить, что значит запомнили № строки? Я планировал запоминать DateTime и номер сделки для оценки, что уже было посчитано. Так как только DateTime, наверное, может совпасть у разных сделок до секунды. А вот № строки будет зависеть от того сколько сделок всего в таблице, но оно же не постоянно? Я пока не разобрался, отчего вообще это зависит.
То только сегодняшние сделки в таблице, то вчерашние за весь день, то с какого-то часа.
Нашел в хелпе. "Если количество строк таблицы превышает пороговое значение, заданное в файле info.ini (без учёта глобальных фильтров), то при вызове пункта меню «Создать окно / Заявки» открывается окно редактирования таблицы. Иначе – открывается сформированная Таблица заявок. По умолчанию пороговое значение равно «100000».
Получается в базе данных, я так понимаю, в файле trades.dat, по умолчанию хранится до 10000 строк. А сколько отражается в таблице терминала Quik, это уже другой вопрос. Но все равно, количество сделок может быть и больше 10000, это надо учитывать или файл trades.dat удалили, где - то вообще рекомендовали их *.dat периодически удалять, т.к. современный Квик начинает подвисать , когда они разрастаются. Больше это, наверное, к alltrade.dat относится, если в него все сделки пишутся. Сейчас провел эксперимент, удалил trades.dat запустил квик и сделки в таблице появились и файл "восстановился"
local row = 0 -- № строки в таблице всех сделок
for i=getNumberOf("all_trades") -1, 0, -1 do
local item = getItem("all_trades", i)
if item then
local posix = os.time(item.datetime)
if posix and tonumber(os.date("%H%M",posix) < 1900 then row = i + 1; break end
end
end
вот когда из цикла, который ищет time < 19-00 , то row будет равно порядковому номеру строки с первым таймштампом == 1900,
а потом row меняете на getNumberOf("all_trades") -1 (т.е. строка с последней сделкой)
Дмитрий, вразумите - если необходимо сравнить совпадает ли дата, записанная в два разных массива, как проще всего их сравнить?
Например:
В trade1/2 дата записана в виде таблицы день, месяц, год...
Сравнение через unpack сравнит массивы поэлементно или необходимо явно прописывать условие на каждое поле и делать and?
Дмитрий, здравствуйте! Спасибо за хороший ресурс и отличную обратную связь! Обычно решение нахожу сам, но возник вопрос на который ответ не нашел.
Вот так мы получаем секунды, из которых потом вытаскиваем дату и время:
local Size = getNumCandles(tag)
local t,n,_ = getCandlesByIndex(tag,0,0,Size)
local seconds = os.time(t[i].datetime)
Мне нужно наоборот. У вас в примерах есть инфо как из секунд получить таблицу
local datetime = os.date("*t",seconds).
А как при наличии секунд получить индекс свечи? Я пока что пришел только к тому чтобы перебирать секунды из свеч и сравнивать со своими, но это долго. Мне кажется есть решение элегантней.
Всегда пожалуйста! 🙂 Никак не получить индекс, только перебор, т.к. ночью, в выходные и праздничные дни свечей нет и не получиться зная время первой свечи просто разделить секунды на таймфрейм.
%x - дата (пример, 09/16/98)
если по нормальному по нашему представить то это такой нет функции надо просто разбить как нам надо по %Y - год, 4 цифры (пример, 2015) и т.д.
Здравствуйте.
Разбираюсь с датой временем. Пример с циклом как раз то что мне нужно
Но он у меня не работает, выдает ошибку. "lua:26: attempt to call global 'dt' (a table value)"
Перешел разбираться с циклом и там в примере указано pairs(Array)
Исправил код из примера
И ошибка пропала.
Я так понял что обязательно писать pairs. или в каких то случаях допускается просто указать таблицу? Если допускается, то в каких? Или это ошибка в примере?
Код писал в индикаторе.
Да, в примере была ошибка, прошу прощения, исправил.
А к чему это: for key,value in pairs(dt) do dt[key] = tonumber(value) end ?
С моей точки зрения - это бред. Луа без разницы строковые значения в dt или нет.
Рекомендую вот тут ознакомится как действительно работать со временем в луа, Дмитрий, без обид))
http://bot4sale.ru/blog-menu/qlua/spisok-statej/368-lua-time.html
Да какие обиды, Вы что? 🙂 Хороший ресурс советуете же)
Добрый день!
Помогите с поиском ошибки, не могу разобраться
на строке local Torgtime = TimeTrade() выдает ошибку attempt to call global 'TimeTrade' (a nil value)
Может кто подскажет где косяк?
после if код не вставился
все равно не загрузилась часть кода, запишу без шорткодов
if epoch_time > os.time(tradetime1) and epoch_time os.time(tradetime4) and epoch_time os.time(tradetime2) and epoch_time os.time(tradetime5) and epoch_time < os.time(tradetime6) then
local Torgtime = 3
else
local Torgtime = 2
return Torgtime
Вы функцию TimeTrade написали внутри функции main
Дмитрий, спасибо огромное, просто запутался с endами, код правильный, а я ищу ошибку в функции TimeTrade и искал бы всю ночь.
Спасибо за помощь!
Всегда пожалуйста!