Никогда не пользовался колбеком OnInit. Обычно я инициализирую переменные до начала main как то так:
Код
stop_loss_pc=3
MAsteps=1
is_run = true
send_order=false
for sec in string.gmatch(ticker_list,"%a+") do
lot[sec]=getParamEx(class,sec,"lotsize").param_value
step[sec]=getParamEx(class,sec,"SEC_PRICE_STEP").param_value
--задаём первоначальные бид, аск и ласт
last_price[sec]=tonumber(getParamEx(class,sec,"last").param_value)
if last_price[sec]==0 or last_price[sec]==nil then
last_price[sec]=tonumber(getParamEx(class,sec,"prevprice").param_value)
toLog (log, sec.." при запуске нет цены последней сделки "..type(last_price[sec]))
end
tablebid = getParamEx(class, sec, "bid") --получаем таблицу "bid"
bid_best[sec]=tonumber(toPrice(sec, tablebid.param_value)) --из таблицы берЄм значение
tableoffer = getParamEx(class, sec, "offer") --получаем таблицу "offer"
offer_best[sec]=tonumber(toPrice(sec, tableoffer.param_value)) --из таблицы берЄм значение
end
Зачем нужен OnInit? В него помещается такой же кусок кода? В чём преимущество? Спасибо.
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
09.10.2016 15:27:59
По-моему были какие-то функцииQLua, которые корректно работают только в Init(), просто в теле скрипта не работают (что-то про источники данных, да?). Если речь про инициализацию переменных/открытие файлов и т.п. - то разницы нет никакой.
Пользователь
Сообщений: Регистрация: 05.02.2015
30.01.2017 20:19:52
Зачем у Oninit в скобках параметр (script_path)? У меня работает и без него: OnInit ()
имеется в виду, что нужно делать так?
Код
script_path=getScriptPath()
function OnInit (script_path)
--задаём переменные
end
Пользователь
Сообщений: Регистрация: 02.02.2015
миру мир!
31.01.2017 07:26:26
Потому как параметры в Луа указывать не обязательно, и если даже функция вызвана с параметрами - всем пофик
Пользователь
Сообщений: Регистрация: 30.01.2015
31.01.2017 20:53:30
Цитата
Космонавт написал: Зачем у Oninit в скобках параметр (script_path)? У меня работает и без него: OnInit ()
имеется в виду, что нужно делать так?
Код
script_path = getScriptPath ()
function OnInit (script_path)
--задаём переменные
end
Если память мне не врет, то вроде бы раньше вызов getScriptPath () в начале подвешивал скрипт и еще были глюки вызова функций QLUA вне колбеков или main.
Пользователь
Сообщений: Регистрация: 16.01.2017
03.02.2017 17:42:24
Цитата
Космонавт написал: Зачем у Oninit в скобках параметр (script_path)? У меня работает и без него: OnInit ()
имеется в виду, что нужно делать так?Кодscript_path=getScriptPath() function OnInit (script_path) --задаём переменные end
Имеется ввиду, что quik уже за Вас вызвал getScriptPath() и результат Вам подсовывает в качестве параметра при вызове OnInit(script_path). А уж будете Вы использовать этот "подарок" внутри OnInit или нет, дело Ваше
Пользователь
Сообщений: Регистрация: 16.01.2017
03.02.2017 23:35:53
Небольшая поправка: В script_path Вы получаете не просто полной путь к папке запускаемого скрипта (как при вызове getScriptPath()), а полный путь, включая имя файла самого скрипта.
Пользователь
Сообщений: Регистрация: 22.02.2023
30.06.2023 12:38:55
Всё же, хотелось бы получить комментарий разработчика, в чем сакральный смысл функции OnInit?
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 30.01.2015
30.06.2023 13:13:12
Цитата
Ziveleos написал: Всё же, хотелось бы получить комментарий разработчика, в чем сакральный смысл функции OnInit?
В том, что это этот колбек вызывается раньше всех других колбеков и раньше функции main. Без него у Вас колбеки будут вызываться раньше, чем будет вызвана функция main.
Пользователь
Сообщений: Регистрация: 30.01.2015
30.06.2023 13:14:53
в итоге если вы параметры торговли определяете в main, то колбеки начнут работу без параметров и могут такого вам наторговать, что будет мучительно стыдно за такой скрипт.
Пользователь
Сообщений: Регистрация: 30.01.2015
30.06.2023 13:16:25
вообще-то ответ есть в документации: ------------- OnInit Функция вызывается терминалом QUIK перед вызовом функции main(). В качестве параметра принимает значение полного пути к запускаемому скрипту.
Формат вызова:
OnInit(STRING script_path)
В данной функции пользователь имеет возможность инициализировать все необходимые переменные и библиотеки перед запуском основного потока main().
Пользователь
Сообщений: Регистрация: 22.02.2023
30.06.2023 21:14:19
Необходимые переменные и библиотеки перед запуском основного потока main() возможно инициализировать и в BODY. Если скрипт не HFT, или вообще без коллбэков, получается OnInit не сильно нужен.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 22.02.2023
30.06.2023 21:30:52
И не нужно на меня кегль повышать.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 25.09.2020
01.07.2023 22:37:42
Ziveleos, OnInit нафиг не нужен. Как и весь этот маразм с двумя потоками. Лично я выбросил OnInit если не в первой, то во второй версии своего скрипта. Думаю, это наследие С++ - там тоже какие-то идиотские трепыхания идут ещё до main.
Пользователь
Сообщений: Регистрация: 22.02.2023
02.07.2023 21:18:58
Владимир, Второй поток все-таки нужен, иначе QUIK замрёт, пока работает скрипт. А вот, что касается:
Цитата
nikolz написал: В том, что это этот колбек вызывается раньше всех других колбеков и раньше функции main.Без него у Вас колбеки будут вызываться раньше, чем будет вызвана функция main.
коллбэки начинают работать только вместе с main.
Код
qtes = {}
function OnQuote(class, sec )
ql2 = getQuoteLevel2(class, sec)
table.insert(qtes, ql2)
end
sleep(10000)
function main()
--sleep(10000)
message(tostring(#qtes))
end
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 25.09.2020
03.07.2023 00:42:38
Ziveleos, Второй поток нафиг не нужен, работа скрипта - это работа интерпретатора. По крайней мере, в нормальной реализации. Я в своё время потратил довольно много времени, чтобы переместить всё, что можно, в поток main, и с тех пор практически забыл про все глюки. Для эмуляции прерываний по таймеру использую sleep, а единственное "настоящее" прерывание - OnTrade.
Объясняю, тем кто не понял. -------------- Если у Вас скрипт запускается одновременно с запуском QUIK, то нет особой разницы, где Вы устанавливаете и загружаете начальные параметры скрипта. ------------------------- Но если Вы запускаете скрипт при работающем QUIK, т е в реальном времени торговли, то возможны следующие последствия в зависимости от места , где вы устанавливаете переменные. Рассмотрим эти варианты: ------------------ 1) В начале скрипта присваиваем значения. В этом случае присвоение происходит до полной загрузки скрипта и запуска функции main. присвоение произойдет лишь при загрузке скрипта. При этом могут быть еще не определены Ваши функции, которые Вы используете для назначения параметров. ------------------- 2) В начале функции main В этом случае весь скрипт уже загружен и все функции определены. Но так как main - это отдельный поток, то при длительной процедуре инициализации переменных могут поступить данные по колбекам и эти данные могут оказать влияние на установку переменных. Вот пример теста main c установкой параметров:
Код
local beg=os.clock();
local x={}
local function sig(i) return i end
function main()
Log:write("main начинаем устанавливать начальные значения"..os.clock()-beg.."\n"); --Log:flush();
for i=1,10000 do x[i]=math.sin(i); Log2:write("X="..x[i].."\n"); Log2:flush();
end;
Log:write("закончили установку нач значений\n"); Log:flush();
while true do
-- nkevent.wait(event); --ждем события
Log:write("main основной цикл="..os.clock()-beg.."\n"); Log:flush();
sleep(10);
end
end
а вот результат работы этого скрипта с колбеками
Код
OnI nit=0.0
main начинаем устанавливать начальные значения0.0010000000002037
On All=0.0020000000004075
On All=0.0020000000004075
On All=0.0020000000004075
...
On All=0.0060000000003129
On All=0.0060000000003129
On All=0.0060000000003129
...
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
закончили установку нач значений
main основной цикл=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
On All=0.029999999999745
Внутри цикла установки параметров в функции main вызывается колбек OnAllTrade в основном потоке . ---------------------- 3) Установка параметров в колбеке OnInit() это самый безопасный и предсказуемый способ установки. OnInit вызывается ,когда весь скрипт загружен и определены все наши функции. OnInit вызывается в основном потоке, когда поток main еще не запущен. Так как все колбеки вызываются в основном потоке, то они не могут быть вызваны пока OnInit не завершит работу. =================== Т е все переменные будут определены и загружены без каких-либо неожиданностей. ==================== Приведу для наглядности аналогию. На перекрестке есть светофор. Особо буйные могут ходить через перекресток не взирая на сигналы светофора. Особо продвинутые могут даже ходить с закрытыми глазами. Особо осторожные будут ходить лишь на зеленый. --------------------- Выбор за Вами.
Пользователь
Сообщений: Регистрация: 25.09.2020
03.07.2023 12:52:48
nikolz, В ЛЮБОМ случае "нет особой разницы, где Вы устанавливаете и загружаете начальные параметры скрипта". Я миллион раз запускал скрипт и во время торговли, и когда её нет, и НИ МАЛЕЙШИХ "последствий в зависимости от места , где вы устанавливаете переменные" не наблюдалось.
Ладно уж, "рассмотрим эти варианты": 1) Да, именно "в начале скрипта присваиваем значения". Я лично полагаю, что в этом случае присвоение происходит ПОСЛЕ полной загрузки скрипта, но ДО запуска функции main. Впрочем, допускаю, что и ДО полной загрузки, но это при условии, что системную математику писали клинические дебилы. В любом случае, это примерно одна секунда.
2) Да, "в начале функции main" ТОЖЕ производятся кое-какие присвоения. И в середине тоже. Более того, они могут присваиваться даже из внешних файлов - например, номер счёта, код клиента, состояние портфеля и кошелька. Но мне и в страшном сне не может присниться ни "длительная процедура инициализации переменных, ни, тем более, чтобы в это время могли поступить данные по колбекам, и уж совсем невозможно, чтобы эти данные хоть как-то могли "оказать влияние на установку переменных". Это нужен ТАЛАНТИЩЕ, чтобы такого добиться. Просто программировать нужно уметь, хоть немножко.
3) Установка параметров в колбеке OnInit нафиг не нужна, как и сам OnInit. Лично у меня этого дерьма нет, не было и не будет. Точнее, было в самом начале моего знакомства с Луа в тренировочном скрипте, где я пытался понять, за каким хреном эта бредятина может быть кому-то понадобиться.
Пользователь
Сообщений: Регистрация: 22.02.2023
03.07.2023 15:31:31
Владимир, что Вы называете вторым потоком? Под вторым потоком я подразумевал именно поток main, а коллбэки, BODY - это основной основной поток QUIK.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 25.09.2020
03.07.2023 16:42:33
Ziveleos, Я разве называл вторым потоком? Впрочем, неважно: поток main - он обязательный, так что первый и единственный, а всё остальное - это второй: прорисовка таблиц, коллбеки, и прочая лабуда. Прорисовка у меня вообще отключаемая - так называемый "спящий режим", всех коллбеков один OnTrade, так что в этом "основном потоке QUIK" мой скрипт находится дай бог сотую долю процента.
Пользователь
Сообщений: Регистрация: 30.01.2015
04.07.2023 06:33:35
QUIK создает 7 потоков. Скрипты -запускают main в следующих по очереди потоки.
Пользователь
Сообщений: Регистрация: 15.06.2023
04.07.2023 13:20:46
Владимир,
зря ругаете, функция необходима и ключевое здесь OnInit(STRING script_path) В данной функции пользователь имеет возможность инициализировать все необходимые переменные и библиотеки перед запуском основного потока main().
К примеру если обрабатываете колбек OnAllTrade() без нее и не обойтись.
Пользователь
Сообщений: Регистрация: 15.06.2023
04.07.2023 13:31:33
написал: инициализирую переменные до начала main как то так:
это нормально если ваши переменные не лезут в терминал или к серверу до запуска mail()
Пользователь
Сообщений: Регистрация: 15.06.2023
04.07.2023 15:08:50
В чём преимущество? Так его и нет.
Вопрос в организации переменных Вашего скрипта их локализации и видимости.
Пользователь
Сообщений: Регистрация: 25.09.2020
04.07.2023 17:58:39
VPM, НА КОЙ "функция необходима"? Я прекрасно могу инициализировать все необходимые переменные и без этого дерьма, как и без каких-либо библиотек - и перед запуском основного потока main, и после него, и во время него. OnAllTrade также нафиг не нужен.
Пользователь
Сообщений: Регистрация: 15.06.2023
04.07.2023 18:30:04
, так я с Вами не спорю, где угодно!
Вопрос в организации переменных Вашего скрипта их локализации и видимости.
К примеру, "перед запуском основного потока main" всего 200 локальных переменных я постоянно выхожу за это число. Если как у Космонавта то сам lua ругается порой.
Сервис!
Пользователь
Сообщений: Регистрация: 25.09.2020
04.07.2023 18:47:59
VPM, А тут не о чем спорить, задача организации торговли настолько проста, что её можно реализовать даже на чистом Луа, даже при полной ущербности системной математики Квика.
Какие могут быть ЛОКАЛЬНЫЕ переменные "перед запуском основного потока main" - то мне неведомо. У меня их... ну, пара десятков, наверное, наберётся. Впрочем, сейчас посчитаю... ого, аж 34 штуки.
Пользователь
Сообщений: Регистрация: 15.06.2023
04.07.2023 19:00:30
Я смотрел Ваши посты Как понимаю у Вас свой подход вы не пользуетесь историей данных. А локализация в луа нужна чтоб не засорять для видимости и быстродействия.
Нет, я как раз прекрасно знаю, что никакая локализация в луа не нужна, и ничего не засоряется для видимости и быстродействия, если специально этим не заниматься.
Пользователь
Сообщений: Регистрация: 15.06.2023
04.07.2023 19:38:44
Я не обсуждаю язык, бессмысленно другого нет. Я лишь прислушиваюсь к рекомендациям авторов. Проверить видимость легко, быстродействие скрипта легко с локальными и глобальными. SciTe одно нажатие.
А вот со сбором мусора сложней. Оказывается nil запускает сборщик.
На Ваш вопрос - В чём преимущество? Хотел сделать поправку на пост. Если скрипт небольшой, не требует особого быстродействия, не затратен по памяти. Вас все устраивает - То ни каких.
Если хотите оптимизировать Вас скрипт посмотрите "Програмирование на Lua" сэкономит много времени. Проверено!
С уважением VPM
Пользователь
Сообщений: Регистрация: 25.09.2020
04.07.2023 20:15:56
VPM, Да плюньте Вы на быстродействие скрипта с локальными и глобальными. И на сборщик мусора тоже. Пусть работают как работают - это ИХ проблемы.
Пользователь
Сообщений: Регистрация: 15.06.2023
04.07.2023 20:50:12
Это да.
В трейдинге нет единого алгоритма по которому Все работают.
И ведь вопрос очень примитивен, даже для меня - это азы. Если можем помочь почему бы нет.
Я уже Вам писал в другом п. никто здесь является мне или Вам соперником в торговле.
Вы прекрасно знаете что ММ и Банки торгуют абсолютно др. алгоритмы. Ну к примеру ММ видит обе стороны сделок и одновременно с обоих торгует.
Пользователь
Сообщений: Регистрация: 22.02.2023
04.07.2023 21:51:27
Видимо, единственное преимущество OnInit в том, что в отличии от body, из неё можно вызывать функции не объявленные ранее. Ну, и " В качестве параметра принимает значение полного пути к запускаемому скрипту."
Скрытый текст
Код
file = io.open(getScriptPath() .. "\\Environment.txt", "w+")
local len = 0
for k, v in pairs(_ENV) do
file:write(string.format("%s\t %s \n",k,(tostring (v))))
len = len + 1
end
file:write("\n Окружение BODY: ", len, "\n\n" )
function OnInit()
local len = 0
for k, v in pairs(_ENV) do
file:write(string.format("%s\t %s \n",k,(tostring (v))))
len = len + 1
end
file:write("\n Окружение OnInit: ", len, "\n\n" )
end
function main()
file:seek("set")
local log = file:read("a")
local b_log = string.match(log, "(.-)\n\n")
local i_log = string.match(log, "Окруж.-\n\n(.-)\n\n")
file:write(" Нет в BODY: ")
for s in string.gmatch(i_log, "(.-)\t.-\n") do
if not string.match(b_log, s) then
file:write("\n", s)
end
end
file:write("\n\n Разница: ")
for s in string.gmatch(i_log, "(.-)\n") do
if not string.match(b_log, s) then
file:write("\n", s)
end
end
file:flush()
file:close()
end
--file:write("Чудо-юдо рыба-кит \n")
function tableLog(t)
for k, v in pairs(t) do
file:write(string.format("%s %s \n",k,(tostring (v))))
end
end
Ziveleos, Ну на кой кому всё это надо? Кого интересуют эти несчастные переменные окружения? Заняться больше нечем?
Пользователь
Сообщений: Регистрация: 22.02.2023
05.07.2023 11:39:18
Владимир, переменные окружения показывают разницу между body и OnInit. Получается, если до зарезу необходимо сделать что-то до начала работы коллбэков, и в этом "что-то" используются функции объявляемые позже, то без OnInit не обойтись. В остальном он на фиг не нужен.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 27.01.2017
05.07.2023 11:56:10
Цитата
Ziveleos написал: , переменные окружения показывают разницу между body и OnInit. Получается, если до зарезу необходимо сделать что-то до начала работы коллбэков, и в этом "что-то" используются функции объявляемые позже, то без OnInit не обойтись. В остальном он на фиг не нужен.
Body скрипта выполняется в потоке терминала. Так что служебные переменные вполне себе инициализируются там.
Читаем документацию:
Цитата
Как и в предыдущей структуре скрипта Lua, после его запуска первоначально выполняются сценарии, описанные в <BODY>, если они присутствуют. Далее происходит вызов обработчика с именем OnInit(), если он присутствует. В обработчике OnInit() пользователь имеет возможность инициализировать все необходимые переменные и библиотеки перед запуском отдельного потока. После завершения функции OnInit() происходит создание отдельного потока РМ QUIK, и в этом потоке начинает выполнение функция main(), которая обязательно должна присутствовать в скрипте.
Так что тело скрипта вполне себе достаточно. OnInit вполне можно использовать для каких-то действий после выполнения служебных процедур, например проверить, что запуск возможен. А если нет - отказ. Но все это можно делать так или иначе.
Речь же про колбеки звучит странно, т.к. я слабо себе представляю использование колбеков в алгоритме, если они не обработаны все. Например, запуск в середине торгового дня. Половина колбеков уже прошла, надо читать прошедшие события из таблиц, и здесь уже не важно как инициализировать. Поэтому колбеки - это вспомогательный инструмент, не более. "Прибивать гвоздями" их к логике - не самая лучшая затея. Он может и не прийти, в конечном итоге. Гарантированной доставки в документации не декларируется.
Пользователь
Сообщений: Регистрация: 25.09.2020
05.07.2023 12:17:23
Ziveleos, Я же спросил: ДЛЯ ТОРГОВЛИ на кой эта хрень нужна? ЗА КАКИМ ХРЕНОМ кому-то "до зарезу необходимо сделать что-то до начала работы коллбэков"? И кому нужно такое говно как Луа, КРОМЕ организации торговле на бирже?
Nikolay написал: Речь же про колбеки звучит странно, т.к. я слабо себе представляю использование колбеков в алгоритме, если они не обработаны все. Например, запуск в середине торгового дня. Половина колбеков уже прошла, надо читать прошедшие события из таблиц, и здесь уже не важно как инициализировать. Поэтому колбеки - это вспомогательный инструмент, не более. "Прибивать гвоздями" их к логике - не самая лучшая затея. Он может и не прийти, в конечном итоге. Гарантированной доставки в документации не декларируется.
Просто из собственного опыта при запуске от колбека пришло а основной цикл еще не запущен. Прошедшие события читаю и из таблиц перед за основного цикла, после запуска беру из колбека. А какие еще варианты обработать т. всех сделок?
Пользователь
Сообщений: Регистрация: 22.02.2023
05.07.2023 13:18:19
Цитата
Nikolay написал: Body скрипта выполняется в потоке терминала. Так что служебные переменные вполне себе инициализируются там.
А я что сказал?
Цитата
if до зарезу необходимо сделать что-то до начала работы коллбэков, and в этом "что-то" используются функции объявляемые позже, then без OnInit не обойтись. end В остальном он на фиг не нужен.
Цитата
Nikolay написал: Речь же про колбеки звучит странно, т.к. я слабо себе представляю использование колбеков в алгоритме, если они не обработаны все.
Если в самой функции коллбэка используется нечто не объявленное ранее, и он сработает, возникнет ошибка. Поэтому это "нечто" нужно объявить до запуска main.
Всё пройдет. Но это не точно.
Пользователь
Сообщений: Регистрация: 22.02.2023
05.07.2023 13:23:37
Владимир, просто давно интересовал этот вопрос: какая разница между body и OnInit, и зачем он вообще нужен?