Избранное трейдера sl0nic
Функция CreateDataSource
Получение количества свечек данных
Пауза для подгрузки данных
Получение по инструменту OPEN, HIGH, LOW, CLOSE, VOLUME
Обработка времени и даты
Закрытие источника данных
Примеры: получение данных последних 10 свечей, выгрузка новой минутной свечки после её закрытия, текущее значение простой средней SMA10 по минуткам
Простой скрипт выгрузки котировок
Сегодня рассмотрим функцию, с помощью которой можно получать данные биржевых свечек. Это можно делать и с графиков (чуть позже рассмотрим), но в этом случае нужно, чтобы сам график как источник данных был открытым, что не очень удобно, особенно если скрипт использует несколько таймфреймов – необходимо аналогичным образом держать открытыми и соответствующее количество графиков.
Более практичным вариантом является получение данных через функцию CreateDataSource, запрос осуществляется следующим образом:
ds, err = CreateDataSource(код класса, тикер инструмента, интервал)
Код класса: для акций «TQBR», для срочного рынка «SPBFUT».
Пока не ушли далеко от темы получения данных из таблицы текущих торгов решил сделать в качестве примера еще и простой скринер акций. Это вполне доступно по тем материалам, которые мы уже прошли. Будем отслеживать динамику изменения цены относительно цены закрытия предыдущего дня.
Нам понадобятся:
1. Таблица для вывода данных (строить уже умеем).
2. Получение данных из таблицы текущих торгов через getParamEx (проходили там же).
3. Тикеры бумаг. Можно взять конкретный список бумаг и работать с ним, но приятнее и правильнее, чтобы скрипт мог автоматом выгружать все торгуемые тикеры из терминала и далее уже отслеживать их динамику. Попробуем это реализовать.
Через sec_list = getClassSecurities(«TQBR») можно получить строку с тикерами акций на Московской бирже, которые будут разделены запятыми. Чтобы пройтись по всем элементам и записать их в массив используем цикл:
for TIKER in string.gmatch(sec_list, "[^,]+") do tikers[#tikers + 1]=TIKER end
Отслеживать будем параметр LASTCHANGE – процент изменения цены от цены закрытия:
Сегодня дополним наш алгоритм советника следующими пунктами:
1. Пропуск «поздних» сигналов на старте.
2. Обработка советником обрыва связи.
3. Сохранение сигналов и логов в файл.
Еще один пункт, связанный со временем, который был выбран для апгрейда советника – это пропуск сигналов на старте, если запуск скрипта состоялся не в начале торговой сессии (например любой старт после 10:30). Это может быть полезным, если выбрана активная внутридневная стратегия и сигналы полученные на старте скрипта, например в середине дня, могут быть уже не актуальными (с низким потенциалом прибыли) и лучше дождаться новых. Т.е. необходимо разделить сигналы на те, которые сгенерировались на старте и остальные сигналы, которые будем далее брать в работу. Сигнал на старте может закрыться (по обратному/сигналу выхода) и если переоткроется снова, то его уже можно брать в работу как новый.
В нашем скрипте сигналы по каждому инструменту (массив signal) ранее могли принимать значение:
0 – вне позиции по инструменту
Продолжаем изучать основы qlua. Улучшаем советника, которого писали ранее и уже дополняли в разных вариантах работой со временем.
Сегодня рассмотрим:
Дополним сигналами на закрытие позиции.
Создадим дополнительную таблицу для вывода данных.
Научим скрипт делать расчет финансового результата.
Сигналы на закрытие позиции.
Логика выходов не менее важная часть любой торговой стратегии и должна тестироваться также скрупулезно как и логика сигналов на вход и разные варианты фильтров для лонга и шорта. Также может быть отдельная логика управлением позицией, например часть позы может частично докупаться если движение идет в сторону прибыли, частично резаться если в сторону убытков, могут по-разному управляться стопы: вся позиция или часть закрываться по уровням, вся или часть двигаться трейлингом в разной логике, например, какая-то часть или вся позиция закрываться по времени (перед закрытием основной сессии или через определенное количество часов после входа, если нет сильного движения и цена ни стоп, ни тейк не достигла).
В прошлый раз был создан советник, который по минимальной торговой логике давал нам некие сигналы на лонг/шорт. Но было что улучшать и, может, далеко не все пункты кто-то захочет включить в алгоритм собственного советника, но в учебных целях мы поэтапно рассмотрим каждый, чтобы было понимание как это можно реализовать.
Сегодня дополним скрипт теми пунктами, которые были связанные с обработкой времени:
Прежде всего начала сделаем правильное отображение цифровых данных.
В прошлых примерах все данные в скрипте выводились в формате строки.
При внимательном рассмотрении можно было заметить, что число выравнивалось по левому (как текст), а не правому краю (как число) ячейки.
Типы всегда можно посмотреть по функции AddColumn в файле QLUA (говорили об этом ранее) по запросу «Функции для работы с таблицами Рабочего места QUIK»:
Тип данных в колонке:
QTABLE_INT_TYPE – целое число,
Продолжаем изучение qlua, cегодня:
Интегрируем таблицы в структуру скрипта qlua.
Удаляем таблицы через DestroyTable.
Останавливаем скрипт через IsWindowClosed.
Обработка события закрытия таблицы через коллбэк.
Работа с цветом SetColor, Highlight, SetSelectedRow.
Пишем простого советника.
В прошлый раз мы рассмотрели как с помощью qlua создать таблицу в торговом терминале и заполнить её информацией из таблицы текущих торгов. Но это была статичная табличка, чтобы её «оживить» нужно разместить операции с нашей таблицей внутри структуры скрипта в функции main.
Саму таблицу мы можем создать до цикла while и внести неизменяемые данные (в нашем случае тикер и наименование бумаги), а уже заполнить цифрами и обновлять внутри цикла. Пока будет работать скрипт таблица будет обновляться.
function OnInit() tikers = {"GAZP", "SBER", "VKCO"} progname = "mytable :" timeout = 5000 end function OnStop() do_it = false message(progname.." Финиш.") end function main() message(progname.
Сегодня рассмотрим:
1. Получение биржевых данных через функцию getParamEx
2. Выгрузка списка параметров функции getParamEx через DDE из торгового терминала
3. Создание пользовательских таблиц в торговом терминале
Одна из особенностей работы через квик это то, что можно получать достаточно большой объем биржевой информации по интересуемым инструментам. Большинство других платформ для алгоритмической торговли и терминалов в РФ будут выдавать только цену открытия, максимум/минимум дня, последнюю цену, цену закрытия, объемы по инструментам и максимум еще 3-5 каких-то дополнительных пунктов. В распоряжении тех, кто использует qlua огромная матрица параметров таблицы текущих торгов.
Получить их можно через функцию getParamEx:
getParamEx(код класса актива, инструмент, параметр), где:
код класса: например в случае акций это «TQBR», а в случае срочного рынка «SPBFUT».
инструмент: тикер.
параметр – один из параметров для соответствующей группы инструментом (об этом подробнее ниже).
Функция возвращает таблицу со следующими полями:
Сегодня начинаем уже писать полноценные скрипты для терминала, а не отдельные блоки кода на lua.
Пройдем:
Структура скрипта
В торговом терминале можно запускать небольшие примеры на lua, как мы это делали ранее, но если говорить о постоянно работающем алгоритме, а не о компактной программе, которая должна выполнить только несколько коротких действий, то минимальная структура скрипта для квика будет содержать следующие функции:
function OnInit – инициализирует глобальные переменные и константы (например, торгуемые бумаги, размеры тейка и стопа, торговый счет и пр.), имена таблиц, необходимых файлов.
function OnStop – функция остановки скрипта, активируется при нажатии клавиши «Остановить» в панели скриптов терминала.
function main – основная функция, создает отдельный поток для выполнения скрипта. Обычно внутри main создается цикл для непрерывной работы, т.к. без него функция выполнит один раз весь код, который в ней прописан и скрипт остановится.
Продолжаем погружаться в основы языка. Сегодня рассмотрим:
Циклы for … do… end
while do … end
repeat … until
sleep
Как пройти весь массив циклом
Как пройти таблицу по ключам и значением
break
goto
Локальные и глобальные переменные
Функции
Получение даты и времени
Получение данных через getInfoParam
Цикл for … end
for index = start, end, step do -- start – начало отсчета, -- end – конец отсчета, step - шаг -- тело цикла end
Пример:
for i = 1, 10 do -- пройтись от 1 до 10 c шагом 1 (по умолчанию)<br /> message("i="..i) -- вывод i<br /> end
Можно задать шаг:
for i = 1, 10, 2 do -- пройтись с 1 до 10 с шагом 2 message("i="..i) end
Цикл while do...end
while (условие) do -- тело цикла end
Выполняет тело цикла, пока соблюдается условие. Если условие на старте не соблюдается, то цикл не запустится.
Пример:
a = 1 while a < 9 do a = a + 1 message(tostring(a)) end
Цикл repeat … until
Весь материал, который здесь и далее будет рассматриваться по qlua, работает на 10й версии квика. Вполне допускаю, что со временем какие-то функции разработчики перепишут и в новых версиях что-то нужно будет сверять c мануалами, уточнять хелпом и на форумах, но предполагаю, что а) эти изменения будут вводиться очень не быстро и б) синтаксис и основа при этом останутся без существенных изменений.
Сегодня рассмотрим:
message
Выводит сообщение в торговом терминале в формате окна (в прошлой статье говорил, что удобнее отключить, чтобы не отвлекаться постоянно) и в таблице системных сообщений.
Особенности message: функция после вывода делает перенос строки, поэтому если необходимо вывести несколько значений в одной строке нужно делать их слияние (об этом ниже).
Для корректного отображения русских букв необходимо выбирать котировку файла Windows-1251 (об этом также в прошлый раз мы уже говорили). Иногда по этой причине некоторые разработчики пишут только на английском весь вывод текста в терминал, чтобы не заморачиваться с кодировкой, в т.ч. при размещении на github и совместной работе с кодом.