<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[QUIK -> DDE &mdash; Основы программирования LUA в QUIK (QLUA)]]></title>
	<link rel="self" href="https://quik2dde.ru/extern.php?action=feed&amp;tid=16&amp;type=atom" />
	<updated>2012-12-17T21:55:30Z</updated>
	<generator>PunBB</generator>
	<id>https://quik2dde.ru/viewtopic.php?id=16</id>
		<entry>
			<title type="html"><![CDATA[Re: Основы программирования LUA в QUIK (QLUA)]]></title>
			<link rel="alternate" href="https://quik2dde.ru/viewtopic.php?pid=21#p21" />
			<content type="html"><![CDATA[<p>Типичный скрипт QLUA, в случае использования подхода обработки событий, должен содержать обязательно примерно следующий код:</p><div class="codebox"><pre><code>is_run = true

function main()
    while is_run do
        sleep(50)
    end;
end

function OnStop()
    is_run = false
end</code></pre></div><p>Здесь мы объявляем глобальную переменную <strong>is_run</strong>, которая будет содержать значение <strong>true</strong> до тех пор, пока не будет нажата кнопка «Остановить скрипт». В функции main() крутится пустой бесконечный цикл, который через каждые 50 мс. проверяет состояние этой глобальной переменной.&nbsp; При нажатии кнопки “Остановить” эта переменная сбрасывается в false внутри обработчика OnStop(), благодаря чему функция main() завершается и скрипт переходит в состояние “остановлен”. После этого обработчики событий в нем не вызываются.</p><p>(<strong>Замечание</strong>: QUIK версии 6.4.0.169 [url=http://forum-archive.quik.ru/forum/lua/96866/]есть ошибка[/url], из-за которой обработчики вызываются и после остановки скрипта, не забывайте об этом.)</p><p>Для примера напишем небольшой скрипт, подсчитывающий общий оборот по нашим сделкам. Для этого приведенный выше текст дополним обработчиком <strong>OnTrade()</strong>.</p><div class="codebox"><pre><code>is_run = true

function main()
    while is_run do
        sleep(50)
    end;
end

function OnStop()
    is_run = false
end

function OnTrade(trade_data)
    qty = trade_data.qty
    sum = trade_data.value
    n = getNumberOf(&quot;trades&quot;)
    for i=0, n-1 do
        t = getItem(&quot;trades&quot;, i)
        sum = sum + t.value
        qty = qty + t.qty
    end
    message(&quot;Total: qty=&quot; .. tostring(qty) .. &quot; sum=&quot; .. tostring(sum), 1)
end</code></pre></div><p>Сохраним этот текст в запустим на выполнение. Если во время работы скрипта мы будем совершать сделки, то после каждой сделки в окне информации будет выводиться общее количество проданных и купленных лотов по всем инструментам и общая сумма всех сделок. </p><p><span class="postimg"><img src="https://quik2dde.ru/static-img/summ-trade-qlua.png" alt="https://quik2dde.ru/static-img/summ-trade-qlua.png" /></span></p><p>Разумеется, при необходимости скрипт можно усложнить, обрабатывая только нужные сделки.</p>]]></content>
			<author>
				<name><![CDATA[admin]]></name>
				<uri>https://quik2dde.ru/profile.php?id=2</uri>
			</author>
			<updated>2012-12-17T21:55:30Z</updated>
			<id>https://quik2dde.ru/viewtopic.php?pid=21#p21</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Основы программирования LUA в QUIK (QLUA)]]></title>
			<link rel="alternate" href="https://quik2dde.ru/viewtopic.php?pid=20#p20" />
			<content type="html"><![CDATA[<p><span style="color: #3F9439"><strong>Обновлено: 01.10.2020</strong></span><br />([url=https://quik2dde.ru/viewtopic.php?id=17]Обсуждение этого материала здесь[/url])</p><h5>Введение</h5><p>Начиная с версии 6.5 в терминале QUIK была добавлена возможность запуска пользовательских скриптов, написанных на языке Lua. В сравнении в ранее имевшимся внутренним языком QUPILE, добавление скриптов на Lua дало пользователям не только более мощный и удобный язык программирования, но и предоставило принципиально новые возможности для создания торговых роботов, в частности возможность мгновенной реакции на изменение рыночных данных за счет реализованной возможности событийного программирования. Событиями могут выступать: изменение стакана котировок, изменение параметров инструментов, совершение сделок на бирже, совершение сделок по поручениям (заявкам), поданным из терминала пользователя (вручную или из скриптов) и т.д.</p><p>Документация по Lua в QUIK и базовые примеры от ARQA: [url=https://arqatech.com/upload/iblock/536/quik_lua.zip]quik_lua.zip[/url]</p><p>Список изменений и нововведений в QUIK по части функциональности Lua-скриптов [url=https://quik2dde.ru/viewtopic.php?id=30]можно посмотреть здесь[/url].</p><h5>Виды скриптов на Lua для QUIK</h5><p>Для выполнения разного рода задач терминал QUIK поддерживает следующие виды скриптов:<br /><strong>Lua-скрипты</strong>: в них доступна вся функциональность для написания роботов, включая возможность получения рыночных данных, параметров инструментов, задание реакции на изменение рыночных данные, выставление заявок, создание таблиц внутри интерфейса терминала QUIK с выводом в них нужной пользователю информации. Эти скрипты могут располагаться в любом месте, доступном терминалу (локальный диск, сетевой ресурс и т.д.).<br /><strong>Пользовательские индикаторы</strong>: это отдельный вид программ на Lua, предназначенный в первую очередь для вывода на графиках терминала индикаторов технического анализа, алгоритм которых реализуется в скриптах данного вида. Помимо этого, индикаторам доступны функции вывода меток на графиках. В большинстве случаев индикаторы для своего расчёта в качестве исходных берут данные с определённого графика, хотя имеется и возможность получения других данных (правда, на данный момент очень сложно обеспечить синхронизацию ганных на графике и внешних данных, с графиком не связаннх). В скриптах индикаторов доступен ограниченный набор внешних функций, по сравнению с <strong>Lua-скриптами</strong>.</p><p>Далее будут рассматриваться только <strong>Lua-скрипты</strong> и особенности их написания в QUIK. Создание индикаторов будет рассмотрено в отдельной теме.</p><h5>Что включает в себя Lua в QUIK</h5><p>В качестве интерпретатора используется <strong>Lua</strong>:<br /></p><ul><li><p>версии <strong>5.1.5</strong> в QUIK версий 6.x, 7.x и 8.0..8.4</p></li><li><p>версии <strong>5.3</strong> в QUIK версий 8.5 и более новых</p></li></ul><p>Включены библиотеки: <strong>io</strong>, <strong>string</strong>, <strong>math</strong>, <strong>package</strong>, <strong>os</strong>, <strong>table</strong>. ( [url=http://forum-archive.quik.ru/forum/lua/96651/96692/#m96692]пруф[/url] )</p><p>Помимо этого скриптам на Lua, запущенным в терминале QUIK, доступны дополнительные функции, предназначенные для получения рыночных данных, взаимодействия с терминалом. Кроме того, пользователь может размещать в своём скрипте функции с заранее предопределёнными наименованиями (так называется callback-функции), которые позволяют реализовывать в торговых роботах реакцию на рыночные события. Ввиду такого расширения Lua в рамках терминала QUIK обычно называют QLua, подчеркивая наличие указанных дополнений. Хотелось бы отметить, что эти дополнения никак не изменяют собственно синтаксис самого языка Lua, а лишь добавляют в него некоторые функции по аналогии с функциями разных библиотек. Поэтому для изучения программирования на самом языке Lua в QUIK годится абсолютно любая книга по Lua.</p><p>Здесь не будет рассматриваться собственно программирование на самом языке Lua, считается, что читатель найдёт эту информацию самостоятельно. Ниже будет подробно рассказано о том, какие возможности для написания программ имеются именно в рамках терминала QUIK.</p><h5>Как программировать на LUA в QUIK</h5><p>Есть 3 подхода:</p><p>а) Можно сделать файл с расширением .lua и написать всю необходимую логику прямо в основной части файла. Такой код после запуска выполнится один раз. Запускать (вручную, нажатием кнопки «Запустить») можно сколько угодно. Такой вариант вполне подойдет для эпизодического подсчета каких-то параметров своих сделок, например.</p><p>б) Можно написать в Lua-скрипте одну единственную функцию с предопределенным именем <strong>main()</strong> и всю логику работы робота (или вычислительного скрипта) поместить в эту функцию. Функция main выполняется в отдельном потоке, т.е. она не мешает работе основного функционала терминала QUIK, наличие функции <strong>sleep()</strong> позволяет выполнять периодически приостанавливать скрипт и возобновлять его работу через какой-то промежуток времени.<br />Фактически, если зациклить main() и вставить sleep(), то получаем полную эмуляцию подхода, использующегося при программировании на встроенном QPILE: периодический расчет чего-либо через заданный интервал времени.</p><p>в) В QLUA доступна событийная модель программирования. Т.е. теперь нет необходимости в одной &quot;главной&quot; функции &quot;выявлять&quot; происходящие изменения и на основании анализа этих изменений выполнять какие-то действия.</p><p>С первым и вторым подходом все достаточно понятно, да и используемый для этого интерфейс весьма напоминает тот, который использовался в QPILE, так что на нем подробно останавливаться не буду.</p><h5>Программирование на QLUA с использованием событий</h5><p>При выборе такого подхода получаем весьма гибкую среду выполнения пользовательских скриптов внутри QUIK, позволяющую мгновенно получать интересующие события от терминала, производя нужную нам обработку этих событий.</p><p>Для того, чтобы обработать то или иное событие, необходимо просто прописать в своем скрипте функцию с предопределенным названием. Все доступные функции обработки событий есть в документации по <strong>QLUA</strong>. Поддерживаются самые различные события совершение на бирже очередной сделки, выставление новой заявки пользователем (или скриптом), изменение стакана котировок и т.д.</p><p>Схематически принцип выполнения скриптов <strong>LUA</strong> внутри терминала <strong>QUIK</strong> можно изобразить следующим образом:<br /><span class="postimg"><img src="https://quik2dde.ru/static-img/qlua-overview.png" alt="QLUA общий обзор" /></span></p><p>Скрипт LUA в QUIK может содержать несколько функций с предопределенными названиями, являющимися обработчиками событий (таких как новая сделка, изменение лимитов, изменение котировок и т.д.).<br />Выполнение скрипта происходит после пожатия на кнопку &quot;Запустить&quot; в диалоге &quot;Таблицы -&gt; Lua -&gt; Доступные скрипты&quot;, и всегда начинается с обработки тела скрипта вне каких-либо функций (на схеме обозначено [BODY]) и вызова обработчика с именем <strong>Init()</strong> (если он есть). После того, как функция <strong>Init()</strong> завершится, происходит создание отдельного потока приложения QUIK, и в этом потоке начинает выполняться функция <strong>main()</strong>, которая обязательно должна быть. Скрипт считается работающим до тех пор, пока выполняется функция main. Как только она завершится - прекращается и выполнение скрипта, т.е. вызов из него обработчиков событий.</p><p>Обратите внимание, что <strong>все</strong> функции обработки событий, в отличие от функции <strong>main()</strong>, выполняются в рамках основного потока терминала QUIK, а значит время их работы должно быть сравнительно небольшим, иначе будут заметны &quot;подвисания&quot; в работе терминала.</p>]]></content>
			<author>
				<name><![CDATA[admin]]></name>
				<uri>https://quik2dde.ru/profile.php?id=2</uri>
			</author>
			<updated>2012-12-17T20:43:41Z</updated>
			<id>https://quik2dde.ru/viewtopic.php?pid=20#p20</id>
		</entry>
</feed>
