alfacentavra
alfacentavra личный блог
26 сентября 2023, 11:44

Qlua: работа с заявками (часть 2).

Сегодня:

Узнаем общее количество заявок
Функции getNumberOf и getItem
Как пройтись циклом по всем заявкам
Вывод активных заявок
Снять скриптом заявку
Снимаем все активные заявки скриптом
Снимаем только заявки, выставленные конкретным скриптом


В прошлый раз мы научились
выставлять скриптом заявки в терминале, теперь можем поработать с ними.
Выставим скриптом 5 заявок на покупку и продажу от лучших цен
BIDи OFFERстакана заявок с шагом в 0,01.

 

Напишем функцию, которая будет выдавать нам необходимые цены (лучшую цену спроса и предложения) со стакана:

Qlua: работа с заявками (часть 2).

И возвращать -1, если предложения или покупки в стакане не найдены (стакан закрыт, либо нет торгов).

Тогда основной алгоритм в main будет выглядеть:

Qlua: работа с заявками (часть 2).

Функцию выставления заявки 
newtransaction() мы прописывали ранее, она не изменится.

 

Запустим скрипт, увидим в нем свои заявки:

Qlua: работа с заявками (часть 2).

Теперь поработаем с ними.

 

Узнаем общее количество заявок

Количество строк в таблице заявок (т.е. сумму как активных заявок, так и снятых и исполненных) можно получить через функцию getNumberOf:

number = getNumberOf("orders")

message("Количество заявок: "..number)


Данная функция позволяет получать количество строк из различных таблиц терминала. Используется чаще всего вместе с функцией
getItem с помощью которой мы можем получать уже сами значения таблиц и смотреть в т.ч. лимиты по деньгам, лимиты по бумагам, информацию по сделкам и пр.  Подробное описание можно найти в файле QLUA.chm  (находится в папке с терминалом) при поисковом запросе getNumberOf:

Qlua: работа с заявками (часть 2).

Сейчас нас будут интересовать заявки.

Каждая строка таблицы заявок представляет собой массив данных с набором параметров. Нумерация строк идет с 0. Параметры таблицы каждой строки можно посмотреть в мануале QLUA раздел getNumberOf, далее Заявки (orders):

Qlua: работа с заявками (часть 2).

Следующий скрипт пройдется по таблице заявок и выведет по каждой номер, цену, объем и комментарий.

Qlua: работа с заявками (часть 2).
Результат

Qlua: работа с заявками (часть 2).

Внимательно изучая таблицу параметров можно заметить, что нигде не прописаны направление (покупка/продажа), а также статус по заявке (активная, снята, исполнено). Это разработчики решили спрятать во флаги (
flags), с которыми нам нужно будет работать побитово. Чтобы не было скучно, видимо.

Qlua: работа с заявками (часть 2).

Примеры
:

bit.band(tonumber(myorder["flags"]), 1) >  0 -- активная заявка

bit.band(tonumber(myorder["flags"]), 4) >  0 -- заявка на продажу

Вывод всех активных заявок:

Qlua: работа с заявками (часть 2).

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

Выведем активные заявки на покупку:

Qlua: работа с заявками (часть 2).


Результат:

Qlua: работа с заявками (часть 2).

Номер заявки в торговой системе (order_num) нам нужен, чтобы работать далее с ней. Например, снять заявку.

 

Снять скриптом заявку

Чтобы снять активную заявку нужно знать её номер (order_num не путать с idтранзакции!). Если мы его знаем и хотим запустить транзакцию на удаление нам достаточно передать в sendTransactionследующую таблицу:

Qlua: работа с заявками (часть 2).

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

Если мы уверены, что нужная нам заявка находится последней в таблице, то мы можем, получив по getNumberOfколичество строк таблицы заявок просто взять последнюю строку (с нумерацией getNumberOf() – 1) и по её номеру выставить транзакцию на снятие заявки.

Однако мы рассмотрим вариант, когда мы не знаем активна последняя заявка или нет и будет циклом перебирать в обратном порядке список заявок построчно, пока не дойдем до первой активной заявки. Её и снимем (она может попасться сразу, а может быть и в середине таблицы или даже в самом начале, если мы вручную или скриптом ранее снимали остальные заявки, либо какие-то заявки исполнились).

Сделаем функцию, которая будет снимать заявку по её номеру в терминале (order_num):

Qlua: работа с заявками (часть 2).

Проходим циклом по всем строкам таблицы заявок в обратном порядке и как только находим первую активную заявку снимаем её:

 Qlua: работа с заявками (часть 2).

Файл: https://github.com/morefinances/qlua/blob/main/delete_one_order.lua 

Снимаем все заявки скриптом

Чтобы снять разом все активные заявки нам достаточно в предыдущем примере убрать (или закомментить --) break в цикле, который обрывал работу после снятия первой найденной активной заявки. В этом случае цикл пройдется по всем строкам таблицы заявок и через новые транзакции снимет каждую активную заявку.

Qlua: работа с заявками (часть 2).
Снимая заявки в обратном порядке мы чуть ускоряем работу скрипта, т.к. преимущественно активные заявки находятся в конце списка таблицы заявок.

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

Qlua: работа с заявками (часть 2).

Видим по комментариям, что снимались сперва те заявки, которые выставились последними. Всё автоматизировано.

 

Снимаем только заявки, выставленные конкретным скриптом.

Чтобы скрипт снял не все заявки, а только собственные, ранее выставленные, нам нужно обращаться к комментарию заявки (CLIENT_CODE) и сверять по нему (при условии, что другие скрипты делают собственные комментарии, отличные от варианта текущего алгоритма).

Qlua: работа с заявками (часть 2).

Здесь в string.sub(myorder["brokerref"], 8, 15) – первые 7 символов это торговый код и двойной слэш, поэтому делая срез с 8 по 15 получаем именно тот общий комментарий (code_order), который делал скрипт при выставлении заявки, но без слэша и номера id заявки.

Для проверки работы скрипта выставим вручную в терминале заявку, например, на продажу объемом в 10 лот.

Qlua: работа с заявками (часть 2).

Qlua: работа с заявками (часть 2).

После этого опять запустим скрипт выставления заявок по стакану.

Qlua: работа с заявками (часть 2).

В таблице заявок видим, что 10 лот, выставленные вручную имеют короткий комментарий (только код клиента и двойной слэш), а скриптом с указанием скрипта, который выставлял и номером
id заявки (прописывали это в алгоритме выставления заявки).

Qlua: работа с заявками (часть 2).

Теперь снимем скриптом заявки, выставленные алгоритмом.

Qlua: работа с заявками (часть 2).

Видим, что заявка, выставленная вручную осталась активной, остальные снялись:

Qlua: работа с заявками (часть 2).

Одна заявка успела исполнится. После работы на учебном счете не забывайте закрывать позиции, чтобы суммы демосчета хватило для всех экспериментов.

В следующей статье завершим работу с заявками.


Самостоятельная работа:

1) Напишите скрипт, закрывающий все активные заявки по таймеру, например в 18:30.
2) Измените предыдущий скрипт так, чтобы заявки по таймеру не закрывались, а перевыставлялись на исполнение по рынку.
3) Напишите скрипт, который делает покупку по рынку 1 лотом GAZP в 11:01 и продает в 11:55.
4*). Напишите скрипт, который выставляет тейк и стоп после исполнения заявки, при этом если по таймеру (например 2 часа) ни один уровень не достигнут, то позиция принудительно закрывается по рынку.

Теги: qlua для начинающих, кружок авиамоделизма.

Ранее:

Qlua: введение
Доля клиентов, использующих алгоритмическую торговлю
«Кружок авиамоделизма»
Разные торговые терминалы, почему Quik
Основной функционал qlua
smart-lab.ru/blog/917696.php

Настраиваем торговый терминал и редактор кода
Установка торгового терминала
Подготовка терминала
Вкладки в терминале
Сохранение и загрузка настроек
Таблица системных сообщений
Отключение окна сообщений
Редактор Notepad++
Настройка русского языка в редакторе
Выбор синтаксиса языка и кодировки
Цветовые настройки
Дублирующий просмотр
Запуск первого скрипта
smart-lab.ru/blog/918869.php

Основы qlua, часть 1:
message, конкатенация
фильтрация по сообщениям в терминале
PrintDbgStr, комментарии
типы данных, type
операции с числами
операции со строками
операции с таблицами
условные операторы
smart-lab.ru/blog/920031.php

Основы qlua, часть 2:
Циклы for … do … end, while do … end, repeat … until.
sleep, break, goto.
как пройти весь массив циклом, как пройти таблицу по ключам
локальные и глобальные переменные, функции
получение даты и времени
получение данных через getInfoParam
smart-lab.ru/blog/921366.php

Qlua: структура скрипта.
Структура типового скрипта qlua с примерами.
Обработка скриптом «обрыва связи» с сервером и возобновления работы.
Работа с файлами: запись, перезапись и чтение файла.
getScriptPath, getWorkingFolder
smart-lab.ru/blog/922044.php

Qlua: получение данных из таблицы текущих торгов, создание таблиц в торговом терминале.
Получение биржевых данных через функцию getParamEx
Выгрузка списка параметров функции getParamEx через DDE из торгового терминала
Создание пользовательских таблиц в торговом терминале
smart-lab.ru/blog/923365.php

Qlua: работа с таблицами (продолжение). Пишем своего советника (начало).
Интегрируем таблицы в структуру скрипта qlua.
Удаляем таблицы через DestroyTable.
Останавливаем скрипт через IsWindowClosed.
Обработка события закрытия таблицы через коллбэк.
Работа с цветом SetColor, Highlight, SetSelectedRow.
Пишем простого советника.
smart-lab.ru/blog/924710.php

Qlua: дополняем скрипт советника таймингом:
Устанавливаем время старта работы скрипта,
Ставим тайминг на получение сигналов на вход,
Устанавливаем таймер на приостановку скрипта.
smart-lab.ru/blog/925421.php

Qlua советник: дополняем сигналами на закрытие позиции, таблицей для вывода данных и расчетом финансового результата по позициям.
Дополняем сигналами на закрытие позиции.
Создаем дополнительную таблицу для вывода данных.
Делаем расчет финансового результата.
smart-lab.ru/blog/926972.php

Qlua: завершаем апгрейд советника:
Пропуск «поздних» сигналов на старте.
Обработка советником обрыва связи.
Сохранение сигналов и логов в файл.
smart-lab.ru/blog/927748.php

Qlua: пишем скринер акций Московской биржи
smart-lab.ru/blog/928152.php

Qlua: получение данных биржевых свечей с сервера брокера, обработка данных, пишем скрипт выгрузки котировок
Функция CreateDataSource
Получение количества свечек данных
Пауза для подгрузки данных
Получение по инструменту OPEN, HIGH, LOW, CLOSE, VOLUME
Обработка времени и даты
Закрытие источника данных
Примеры: получение данных последних 10 свечей, выгрузка новой минутной свечки после её закрытия, текущее значение простой средней SMA10 по минуткам
Простой скрипт выгрузки котировок
smart-lab.ru/blog/929905.php

Qlua: получение данных с графиков терминала.
Идентификатор инструмента
Получаем количество свечей через getNumCandles
Получаем свечные данных через getCandlesByIndex
Читаем данные с индикатора SMA
Данные с верхней и нижней линии Price Channel
Графики с таблицы текущих торгов.
Сравнение получение данных через CreateDataSource и через getCandlesByIndex
smart-lab.ru/blog/931408.php

Qlua: работа с метками, пишем торгового советника на индикаторах.
Вывод текста на график
Вывод графических сигналов
Удаление меток с графика
Торговый советник на индикаторах
Удаление данных вечерней/утренней сессии с графика.
smart-lab.ru/blog/933582.php

Qlua: работа с лентой всех сделок.
Что такое таблица обезличенных сделок.
Настройка таблицы в терминале.
Что делать, если таблица открылась, но она пустая.
Вывод данных с таблицы по DDE.
Работа с таблицей обезличенных сделок через скрипт qlua с примерами.
Пишем советника, показывающего на графике крупных игроков.
smart-lab.ru/blog/935919.php

Qlua: работа с лентой всех сделок (часть 2).
Различия данных ленты всех сделок и биржевого стакана.
Большие покупки и продажи в ленте сделок и динамика цены.
Альтернативные варианты поиск крупных игроков по ленте сделок.
smart-lab.ru/blog/938053.php

Qlua: дополняем скринер акций статистикой, лидерами роста и падения.
Добавляем статистику по акциям роста и падения.
Составляем TOP лидеров роста и падения.
Быстрый поиск акций по тикеру в терминале.
smart-lab.ru/blog/938450.php

Qlua: работа с биржевым стаканом.
Работа с биржевым стаканом через getQuoteLevel2
Особенность нумерации в стакане заявок терминала квик
Работа через функцию обратного вызова OnQuote
Примеры работы со стаканом из скрипта
Сравнение реализации одного алгоритма через разные функции
smart-lab.ru/blog/940742.php

Qlua: работа с заявками (часть 1).
Зачем нужен демо терминал
Где открыть учебный счет
Выставление заявки в торговом терминале через скрипт
Делаем функцию выставления заявки по требуемым условиям
Карман заявок и tri-файлы
Параметры для заявок с примерами по разным рынкам
smart-lab.ru/blog/942481.php

27 Комментариев
  • Jame Bonds
    26 сентября 2023, 11:54
    Учитывая потенциальную возможность встретить отрицательные цены, лучше не использовать -1 для обозначения отсутствия цен.
    Например: в календарных спредах легко найти отрицательную цену.
  • Surmounter
    26 сентября 2023, 12:13
    Что посоветуете использовать вместо комментария, для идентификации заявок, если брокер не дает туда писать, вернее перезатирает его?
    Номер транзакции тоже ненадежен в этом плане.
  • nicknh
    26 сентября 2023, 12:14

    Еще добавлю, что для получения лучшего спроса и предложения по инструменту не надо подписываться на очень «тяжелый» поток данных Level_II_Quotes. Эти данные есть в таблице текущих торгов, получаемые очень быстро и просто. И если уж рассматривается метод getQuoteLevel2, то важно уточнять, что без подписки он будет работать если стакан уже открыт самим пользователем. Что вероятно и будет сделано, но, например, вероятна ситуация, когда нет открытых окон в терминале. Все заказывается скриптами.

    Также стоит уточнить, что для снятия всех активных заявок есть отдельный метод, и не надо циклом бегать по ордерам. Что тоже необязательно делать постоянно, т.к. при первом сканировании достаточно запомнить индекс записи в таблице ордеров. Он будет неизменным в течении торговой сессии.

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

  • Сергей Иванов
    26 сентября 2023, 13:35
    alfacentavra, спасибо за урок…
    Вопрос немного не по теме, а есть ли у Вас опыт работа с различными типами заявок типа Стоп-лимит (Stop limit), Тейк профит… рекомендации по ним?
    В частности интересует механизм реализации Тейк профит: у моего брокера нет алгоритмических заявок, а я бы хотел каждый день автоматом выставлять заявку на продажу по цене к примеру 101. Выхода два: 1) ставить скриптом, 2) использовать Take profit. Вопрос такой — если была заявка на покупку по рыночной цене которая с 99 пробьет цену до 105, то в какой очередности обработаются — прямая заявка по 101, прямая заявка по 102, заявка Take profit по 101…

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн