alfacentavra
alfacentavra личный блог
14 августа 2023, 17:25

Qlua: получение данных с графиков терминала.

Продолжаем погружение в основы qlua. 

Идентификатор инструмента
Получаем количество свечей через getNumCandles
Получаем свечные данных через getCandlesByIndex
Читаем данные с индикатора SMA
Данные с верхней и нижней линии Price Channel
Графики с таблицы текущих торгов
Сравнение получение данных через CreateDataSource и через getCandlesByIndex

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

Получение данных котировок с графика цены.

Для начала на самом графике цены необходимо установить идентификатор.

Создаем график в торговом терминале, нажимаем правую клавишу мышки, выбираем «Редактировать», выбираем график цен:

Qlua: получение данных с графиков терминала.

Проваливаемся во вкладку «Дополнительно», и присваиваем id, например: SBER_ID:

Qlua: получение данных с графиков терминала.

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

Qlua: получение данных с графиков терминала.

Если в дальнейшем окно с графиком закроется, то для корректной работы скрипта идентификатор потребуется прописать заново. Также если мы скопирум график (Действия / Создать копию), то новый график не будет содержать идентификатора.

Теперь привязываемся к данному id в скрипте и можем запросить, например, через getNumCandles количество свечей с графика:

function main()
  tiker_id = "SBER_ID"
  number_of_candles = getNumCandles(tiker_id)
  message("Количество свечей в источнике данных: "..number_of_candles)
end


Получить данные по идентификатору с графика поможет функция
getCandlesByIndex, запрос будет выглядеть следующим образом:

mprice, a, b = getCandlesByIndex(tiker_id, line, first, number_of_candles)

где:
tiker_id – наш идентификатор.
line – номер линии графика. Если индикатор имеет несколько линий, то они нумеруются от 0 и далее. Если работаем с ценами, то указываем 0.
first – индекс первой свечи: особенность нумерации при получения данных через графики: первая свечка имеет индекс не 1, а 0. first не может быть больше общего количества свечей на графике.
number_of_candles – количество запрашиваемых свечей. В наших примерах мы будем запрашивать все, но бывают случаи, когда нужны только несколько последних свечек.

При этом, кроме таблицы свечей (mprice) мы получаем с функции еще и:
a – количество свечей в таблице mprice и
b – легенда инструмента (подпись в терминале под графиком).

Получим последнюю свечку с графика Сбербанка:

function hhmmss(date_time)
  local Hour = date_time.hour
  if Hour<10 then Hour = "0"..Hour end
  local Min = date_time.min
  if Min<10 then Min = "0"..Min end
  local Sec=date_time.sec
  if Sec<10 then Sec="0"..Sec end
  return Hour..Min..Sec
end

function DDMMYYYY(date_time)
  local DD = date_time.day
  if DD<10 then DD = "0"..DD end
  local MM = date_time.month
  if MM<10 then MM = "0"..MM end
  local YYYY = date_time.year
  return DD..MM..YYYY
end

function main()
  tiker_id = "SBER_ID"
  number_of_candles = getNumCandles(tiker_id)
  
  mprice, a, b = getCandlesByIndex(tiker_id, 0, 0, number_of_candles)
  i = number_of_candles - 1
  openprice           = mprice[i].open
  highprice             = mprice[i].high
  lowprice              = mprice[i].low
  closeprice           = mprice[i].close
  volume                = mprice[i].volume
  localtime             = hhmmss(mprice[i].datetime)
  localdata             = DDMMYYYY(mprice[i].datetime)
  
  message(number_of_candles.." "..localdata.." "..localtime.." OPEN="..openprice.." HIGH="..highprice.." LOW="..lowprice.." CLOSE="..closeprice.." VOLUME="..volume)

  message(a.." "..b)

end


Результат:
Qlua: получение данных с графиков терминала.


Видим, что текущая, последняя свечка имеет номер number_of_candles — 1.

 

Чуть скорректируем код, чтобы получить последнюю и первую свечку:

for i = 0, number_of_candles, (number_of_candles - 1) do

Qlua: получение данных с графиков терминала.

И можем сравнить с результатом по скрипту выгрузки котировок, который писали ранее:

Qlua: получение данных с графиков терминала.

Файл.

 

Получаем данные с индикатора

Чтобы получить данные с индикатора, в нашем случае простая средняя, достаточно просто поменять идентификатор:

tiker_sma_id = "SBER_SMA_ID"


Получим последних 10 значений обычной средней:

function main()
  tiker_sma_id = "SBER_SMA_ID"
  number_of_candles_sma = getNumCandles(tiker_sma_id)
  SMA_from_graph, a, b = getCandlesByIndex(tiker_sma_id, 0, 0, number_of_candles_sma)
  for i = number_of_candles_sma-10, number_of_candles_sma-1 do
    message("Свеча : "..number_of_candles_sma .." SMA с графика: "..SMA_from_graph[i].close)
  end
  message(a.." "..b)
end

Результат:
Qlua: получение данных с графиков терминала.

Можно проверить значения по графику, но можно сделать проверку самостоятельным расчетом средней:

Qlua: получение данных с графиков терминала.

Здесь в формуле средней использую свойство, когда новое значение получается через удаление последнего и добавления нового числа последовательности, деленных на период средней (в нашем случае 10). Особенно удобно, если период средней большой, ускоряет расчет. Получаем:

Qlua: получение данных с графиков терминала.
Как видим, всё сходится.

Файл.

Данные с Price Channel 

Получим данные с индикатора Price Channel (максимум и минимум цен за выбранный период).
Аналогично предыдущим вариантам указываем id:
Qlua: получение данных с графиков терминала.


Запрашиваем данные с верхней (0) и нижней (2) линии индикатора:

function main()

  tiker_price_channel_id = "SBER_PRICECHANNEL_ID"
  number_of_candles = getNumCandles(tiker_price_channel_id )
  message(""..number_of_candles)
  
  rsi_upper, m, n = getCandlesByIndex(tiker_price_channel_id, 0, 0, number_of_candles)

  rsi_lower, k, s = getCandlesByIndex(tiker_price_channel_id, 2, 0, number_of_candles)
  
  summ = 0

  for i = number_of_candles-10, number_of_candles-1 do

    message(i.." "..DDMMYYYY(rsi_upper[i].datetime).." "..hhmmss(rsi_upper[i].datetime).." upper="..rsi_upper[i].close.." lower="..rsi_lower[i].close)

    sleep(10)

  end

  message(m.." "..n)
  message(k.." "..s)

end

Получаем:

Qlua: получение данных с графиков терминала.
Проверяем, всё сходится:

Qlua: получение данных с графиков терминала.
Файл.

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


Графики с таблицы текущих торгов.

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

Для этого на графике Сбербанка нажимаем Insert (либо правая клавиша мыши/ Добавить график (индикатор)), далее выбираем Новый.

Qlua: получение данных с графиков терминала.

Не меняя бумагу (Сбербанк) нажимаем Изменить:

Qlua: получение данных с графиков терминала.

История значений параметра:

Qlua: получение данных с графиков терминала.

Выбираем суммарный спрос:

Qlua: получение данных с графиков терминала.

Нажимаем последовательно кнопки Выбрать, Выбрать, Добавить.

Получаем график:

Qlua: получение данных с графиков терминала.

Мне удобнее смотреть его не в барах или свечках, а в форме простой линии по закрытию минуты, поэтому я еще меняю представление графика:

 Qlua: получение данных с графиков терминала.

Qlua: получение данных с графиков терминала.

В дополнительных параметрах графика прописываем id: SBER_BID

Аналогично проделываем для параметра «Суммарное предложение», id: SBER_OFFER.

Выводим оба графика на одну область:

Qlua: получение данных с графиков терминала.

Если графики после этих манипуляций не появились, необходимо зайти в меню терминала Система / Настройки / Основные настройки / Сохранение данных, выбрать «Данные, отражающие текущее состояние и всю историю изменений» и «Получать пропущенные данные»:

Qlua: получение данных с графиков терминала.

Вернуться на сам график и нажать F5. После чего график должен уже нормально отразиться.

Сам терминал при этом сообщит о том, что был перезаказ пропущенных данных:

Qlua: получение данных с графиков терминала.

Если графики не отразились, то делаем стандартный перезаказ данных: Система / Заказ данных / Перезаказать данные:

Qlua: получение данных с графиков терминала.
 

После этого всё должно работать нормально.

Теперь по id можно будет запрашивать данные по выбранным графикам:

Qlua: получение данных с графиков терминала.

Здесь я обращаюсь к цене закрытия свечи по каждой минутке, но можно по аналогии со свечными данными работать с ценой открытия, high/low и в каких-то случаях с volume.

Файл примера.

Все сегодняшние примеры требуют соответствующих графиков и корректного прописания идентификаторов на них. Иначе терминал выдаст ошибку.

Теперь у нас есть 2 варианта обращения к свечным данным. Можно сравнить их.

 

Сравнение получение данных через CreateDataSource и через getCandlesByIndex

Плюсы:

Работа со свечными данными через CreateDataSource:

1) Не требуется никаких графических настроек.

2) Можно запускать скрипт с разных терминалов/рабочих мест сразу, без дополнительных настроек.

3) Нельзя случайно выбрать не тот инструмент, таймфрейм, индикатор, т.к. всё прописывается в самом коде скрипта.  

4) Можно реализовывать алгоритмы, которые торгуют не одну бумагу, а отфильтровывают по критериям инструменты, например с высоким потенциалом движения, и далее ведут торговлю по ним.

Минус:

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

 

Работа со свечными данными через getCandlesByIndex (по идентификатору графика):

Плюсы:

1) Работа с графиками, очень легкий вариант написания советников и торговых роботов, особенно завязанных на индикаторы.

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

3) Можно использовать графики по данным из таблицы текущих торгов.

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

Минусы:

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

2) Если машинально случайно на графике сменили таймфрейм – летит вся стратегия.

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

4) Если по стратегии используются разные таймфреймы, то должны быть открыты сразу несколько соответствующих графиков.

5) При небольших неточностях скрипт становится на два порядка более ресурсозатраным. Так, например, если мы сделаем скрипт с ожиданием минутных данных, по аналогии с тем, что мы рассматривали ранее по CreateDataSource и запустим два скрипта одновременно, то мы увидим:

Qlua: получение данных с графиков терминала.

Здесь мы обращаемся в цикле while ко всему диапазону свечек графика. Но стоит скорректировать и загружать только последнюю закрытую свечку, как скрипт становится вполне соразмерным по нагрузке:

 Qlua: получение данных с графиков терминала.
 

Упражнения:

1. Сделайте вывод цены закрытия по выбранному инструменту и двум любым индикаторам в файл. Последние 10 значений выведите в таблицу.

2*. Попробуйте написать торгового советника на индикаторах с графика.

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


Ранее:

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

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

Основы qlua, часть 1:
message, конкатенация
фильтрация по сообщениям в терминале
PrintDbgStr, комментарии
типы данных, type
операции с числами
операции со строками
операции с таблицами
условные операторы

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

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

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

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

Qlua: дополняем скрипт советника таймингом:
Устанавливаем время старта работы скрипта,
Ставим тайминг на получение сигналов на вход,
Устанавливаем таймер на приостановку скрипта.

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

Qlua: пишем скринер акций Московской биржи

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

3 Комментария

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

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