Выполнение скриптов в QUIK

Ранее вы уже научились создавать скрипт и запускать его, так что на этом больше не заостряю внимания, а лишь только вспомним код нашего простого скрипта

Код состоит из трех строк, пока оставим не понятные слова, это дело будущего. А для начала нам необходимо разобраться с тем, как именно выполняется наш скрипт, то есть, какова последовательность выполнения кода. Дело в том что код может начать выполняться не самой первой строчки, а например с середины. Всё зависит от описанных в коде функций. В примере выше описана лишь только одна функция main, но это не значит что весь скрипт должен состоять только лишь из одной функции, их может быть много всяких разнообразных, с чем мы будем постепенно разбираться, но не будем спешить, всё по порядку, иначе у вас будет каша в голове.

Блочное описание

Итак, начинаем разбираться с последовательностью, взгляните на картинку ниже.

На картинке вы видите весь наш скрипт. В нём имеется 4 блока. В синем блоке функция main, будем считать ее основной функцией. Как видите она располагается не в самом верху нашего скрипта. Два зеленых блока, это функции созданные пользователем. И последний фиолетовый блок, это функция обратного вызова. Перед тем как мы перейдем к последовательности выполнения кода, скажу пару слов о функциях обратного вызова.

Функции обратного вызова могут выполняться в любой момент, они запускаются, когда происходит какое-либо событие. Чтобы было понятно, представьте что вы зашли домой, щелкнул выключатель и загорелся свет. У вас в доме имеется функция, которая отвечает за включение света, но свет не включается сам по себе когда сам этого захочет, он включается лишь тогда, когда вы выполняете действие, то есть щёлкаете выключателем. В этом примере событием является щелчок выключателя. Как только вы щёлкаете выключателем, выполняется событие и это событие запускает выполнение функции включения света. Тоже самое происходит в терминале Квик. Происходит какое-либо событие и необходимая функция начинает выполняться. Я думаю понятно, что событий может быть много и к каждому событию привязана своя функция. Вряд ли у вас дома один выключатель включает абсолютно все электроприборы, для каждого предусмотрен свой выключатель.

Для того чтобы узнать какие события существуют в программе Квик и какие к ним привязаны функции, необходимо обратиться к справочнику. Открываем файл QLUA.chm (Руководство пользователя QLua) и находим слева пункт Функции обратного вызова. Видим целый список функций в котором также присутствует функция main. Да действительно, функция Main является функцией обратного вызова, но так как она является основной функцией, я выделил ее на картинке синим цветом. Открываем описание функции main и читаем.

«Функция, реализующая основной поток выполнения в скрипте. Для ее выполнения терминал QUIK создает отдельный поток. Скрипт считается работающим, пока работает функция main(). При завершении работы функции main() скрипт переходит в состояние «остановлен». Если скрипт находится в состоянии «остановлен», то не происходит вызовов функций обработки событий терминала QUIK, содержащихся в этом скрипте.»

Возможно вам пока что не всё понятно что здесь написано, но главное что мы отсюда выделим, это то что функция реализует основной поток, а также то что терминал Квик создаёт для неё отдельный поток, это важно. Отдельный поток означает что наш скрипт выполняется параллельно программе QUIK. Это очень хорошо, иначе были бы зависания программы Квик.

Представьте ситуацию, программа QUIK занята получением исторических данных для графика, в этот момент изменяется стакан, в стакане имеется цена которая нас вполне устраивает по которой мы хотим купить, в нашем скрипте прописан алгоритм, как только появится необходимая цена сразу покупай, скрипт готов купить, но не может, так как он ожидает пока программа QUIK загрузит все исторические данные для графика, проходит несколько секунд, исторические данные полностью загружены И вот только теперь начал выполняться наш скрипт, но необходимой цены в стакане уже нет ее уже забрали. Вот что значит выполнение скрипта в том же потоке в котором выполняется программа QUIK.

Но у нас таких проблем нет, так как четко сказано «терминал QUIK создает отдельный поток», это значит что даже если Квик в данный момент занят загрузкой исторических данных для графика, то наш скрипт всё-равно отправит ордер для покупки по нужной цене.

С отдельным потоком разобрались, теперь переходим к функции обратного вызова под названием OnInit, на картинке она выделена фиолетовым цветом. Переходим в справочник, в разделе функции обратного вызова ищем функцию OnInit и читаем

«Функция вызывается терминалом QUIK перед вызовом функции main(). В качестве параметра принимает значение полного пути к запускаемому скрипту.»

Выделяем самое главное, функция вызывается терминалом QUIK перед вызовом функции main. То есть сначала выполняется функция OnInit, и только когда она завершается, начинает выполняться функция Main. Так же обратите внимание, так как вызов осуществляется перед вызовом main, значит вызов функции OnInit происходит в потоке программы Квик, ведь main еще не вызвана и отдельный поток еще не создан.

Теперь переходим к пользовательским функциям.

Пользователь может создавать в скрипте неограниченное количество своих собственных функций, они не выполняются по событию, так как не являются функциями обратного вызова, их необходимо вызывать. Как видите в функциях main и OnInit написано, вызов функции… это означает что из этих функций вызываются пользовательские функции. Пользовательские функция выполняются в том потоке в котором их вызывают. Функция myFirstFunc выполнится в потоке программы Квик, а функция mySecondFunc выполнится в отдельном потоке, так как вызвана из функции main.

Последовательность выполнения

Для того что бы разобраться с последовательностью выполнения приведу расширенный пример.

Если вы только начинаете изучать язык, то скорее всего многие строки кода пока не понятны, но это очень простой код, не спешите пролистывать, уделите пару минут и все будет ясно.

В самом начале объявляет таблицу t и в поле 0 помещаем время которое работает программа Квик, это будет нулевая точка отсчета, когда начал выполняться наш код. В остальные поля будем записывать разницу между временем в нужный момент и нулевой точкой и будем знать сколько времени прошло в любой точке кода. В следующей строке записываем время запуска скрипта и делаем паузу в 100 мс. Далее во всех точках кода записываем где находится выполнение и время в данный момент, таким образом выясним последовательность. В самом конце, перед завершением функции main, выведем сообщение и отобразим все записанные точки.

Скопируйте себе этот код скрипта и выполните. В итоге Вы получите примерно такое сообщение.

message Lua Скрипт

message Lua Скрипт

Посмотрите на отметки времени. Первая отметка «Запуск» и время 0, ничего удивительного, скрипт только запустился, по этому и прошло 0мс. Следующая отметка «Отметили myFirstFunc» и время 0,101, это значит что Квик узнал о том что имеется функция myFirstFunc через 101мс после запуска скрипта, но только узнал что есть такая функция, тело функции не выполнялось. Но что же делал аж 100мс наш скрипт? — Ничего, просто ждал, он получил команду sleep(100) в строка номер 2. Обратите внимание что функция main так же просто отмечена, в этот момент она не запускается и отдельный поток для нее еще не создается. Так же прошли остальные отметки всех функций. Для более лучшего понимания выполнения кода, привожу наглядный пример.

Последовательность выполнения LUA

Последовательность выполнения LUA

Обратите внимание на цвет курсора. В начале цвет курсора синий, это значит идет выполнения кода в потоке программы Квик, после выполнения функции OnInit() поток программы Квик уходит заниматься своими делами в само платформе, а создается отдельный поток, его я окрасил в желтый цвет. После завершения функции main отдельный поток уничтожается, выполнение скрипта соответственно прекращается.

 

На этом мы разобрались как и в какой последовательности выполняется скрипт в платформе QUIK. Наверное было немного трудно, но я надеюсь что вы справились и теперь ещё один шаг позади.

Если вы еще не добавили сайт в закладки, то рекомендую сделать это прямо сейчас иначе потеряете. А также если вам нравится материал, то отблагодарите автора, то есть меня, разместив ссылку на мой сайт в социальной сети.

Если вы читает все с самого начала, то наверное уже немного устали, думаю стоит сделать перерыв и с новыми силами продолжать изучение. А если полны сил, то вперед, впереди еще много интересного.

Постоянная ссылка на это сообщение: https://k-pavel.ru/vypolnenie-skriptov-v-quik/

avatar
2 Цепочка комментария
6 Ответы по цепочке
2 Последователи
 
Популярнейший комментарий
Цепочка актуального комментария
3 Авторы комментариев
Павел КашинскийOLEGpavelсанн Авторы недавних комментариев

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

  Subscribe  
Новые Старые Популярные
Подписаться на
Oleg
Гость
Oleg

Запустил данный код, но у меня после некоторой паузы выскакивает сразу сообщение 1 и 2, и вижу я сообщение 2 — «Завершение! 1.4000000000015», а из кода, как я понял сообщения должны поступать постепенно: сначала «Запуск! 0», потом
«Отметили myFirstFunc 0.099999999998545» и так далее.
Я ошибаюсь?

OLEG
Гость
OLEG

спасибо, разобрался с вашей помощью. Подскажите, что значит «отметили» в коде? правильно ли я понимаю, что это есть «объявление» функции? и еще, зачем делать паузы в 100мсек, можно эти паузы убрать?

санн
Гость
санн

Вопрос. В выше написанном скрипте прямоугольники зеленый,синий, зеленый ,фиолетовый —
функция обратного вызова OnInit последняя, получается что при исполнении программы
выше стоящие функции не обрабатываются пока процесс не дойдет до функции OnInit.Я правильно понял.

санн
Гость
санн

Я понял что Функция OnInit выполняется самой первой. Программа идет сверху вниз
и первая функция в скрипте у Вас myFirstFunc что программа делает, программа в данном случае пропускает что ли доходя до OnInit .