...
-- Настройки SEC_CODE = "SBER" -- Код инструмента CLASS_CODE = "TQBR" -- Код класса инструмента SHORT_MA_PERIOD = 10 -- Период короткой скользящей средней LONG_MA_PERIOD = 50 -- Период длинной скользящей средней QTY = 1 -- Количество лотов -- Переменные short_ma = {} long_ma = {} prices = {} position = 0 -- Текущая позиция: 0 - нет позиции, 1 - лонг, -1 - шорт -- Функция для расчета скользящей средней function calculate_ma(prices, period) local sum = 0 for i = #prices-period+1, #prices do sum = sum + prices[i] end return sum / period end -- Функция для обработки новых тиков function OnAllTrade(alltrade) if alltrade.sec_code == SEC_CODE and alltrade.class_code == CLASS_CODE then table.insert(prices, alltrade.price) if #prices >= LONG_MA_PERIOD then table.insert(short_ma, calculate_ma(prices, SHORT_MA_PERIOD)) table.
local Titles, Entries, Desk = {}, {}, {} local Wn1_Hndl local Wn1_Field1, Wn1_Field2, Wn1_Field3, Wn1_Field4, Wn1_Field5 = "Код CALL", "Страйк", "Дельта CALL", "Дельта расч", "Теор. расч" function OnInit (scriptPath) qu = require ("QuikUtil(qu)") -- qc, lu, tu blk = require ("BlackScholes(blk)") glb_ScriptDir, glb_ScriptName = lu.SplitPath (scriptPath) message (glb_ScriptName .." started") server = require ("OptionDesk") end -- OnInit() function OnStop (signal) if Wn1_Hndl then DestroyTable (Wn1_Hndl) end StopFlag = true return 1000 -- 1 sec end local function ShowWin (cols) for k = 1, #Desk do local calCode = Desk[k][Entries[Wn1_Field1]] if calCode:sub (3,3) == "0" then calCode = calCode:sub (1,2) .
После того как исполнилась сделка и мы получили соответствующий коллбэк у нас меняются данные по позициям и доступным лимитам. Посмотрим, как можно работать с этими данными через скрипт.
Для анализа состава портфеля, лимитов и их динамики используются таблицы:
Клиентский портфель (получаем данные через getPortfolioInfo и getPortfolioInfoEx).
Позиции по деньгам (getMoney и getMoneyEx, money_limits).
Позиции по инструментам (getDepo, getDepoEx, depo_limits).
Ограничения по клиентским счетам (futures_client_limits).
Позиции по клиентским счетам (futures_client_holding).
Таблица «Клиентский портфель» даёт сводную информацию по лимитам и параметрам риска брокерского счета. Таблицы «Позиции по деньгам» (лимиты) и «Позиции инструментам» (ценные бумаги) показывают данные в разрезе фондового рынка. Таблицы «Ограничения по клиентским счетам» (лимиты) и «Позиции по клиентским счетам» (фьючерсы и опционы) – только про срочному рынку.
Функция OnTrade
Сохранение параметров сделки в файл.
Работа с таблицей сделок.
Сохранение всех сделок дня.
Скрипт автосохранения всех заявок и сделок под завершение торгового дня.
Для отслеживания прошедших сделок мы можем задействовать функцию обратного вызова OnTrade. Она во многом похожа по логике на OnOrder, только возвращает коллбэки уже по исполненным сделкам. В случае, если заявка разбивается на несколько сделок, мы получим информацию по каждой.
В файле QLUA.chm в директории терминала находим через поиск описание самой функции:
здравствуйте, Может кто знает как называется поле «значение» в таблице текущих торгов? Хотелось бы получать значение индексов мосбиржи из та...
Всем привет, только учусь работать с QUIK и LUA, возникла проблема с выводом баланса.
Вот скрипт:
function main()
Firm_ID = «MC0139600000»
client_code = «4105TE2»
moneyRu = getMoneyEx(Firm_ID, client_code, «EQTV», «SUR»,0)
TradeBalance = moneyRu.currentbal/2
message('Баланс RUB = '..moneyRu.currentbal)
if(FakeBalance>0)
then
message('Баланс RUB = '..moneyRu.currentbal)
else
message('Баланс для покупки = '..TradeBalance)
end
end
Выдает ошибку attempt to index a nil value (global 'moneyRu')
Буду очень благодарен если кто-нибудь подскажет в чем проблема.
Сегодня завершаем работу с заявками:
Функция OnTransReply
Функция OnOrder
Получение остатка по заявке, контроль исполнения полного объема
Таблица транзакций
Общая логика выставления лимитной заявки в стакане
В предыдущих примерах мы закладывали на обработку заявки небольшой таймаут (в пределах от 300 мс до 1 секунды), но правильнее отслеживать результат по коллбэкам, т.к. это время может быть и менее 300 мс, а может затянуться (по разным причинам) на секунды. Поможет нам в этом отслеживании функции обратного вызова OnTransReplyиOnOrder.
Если отправляя заявку через sendTransaction мы на старте могли получить ошибку на стороне терминала (неправильно указанный торговый код/инструмент/класс рынка), то через OnTransReply мы получаем результат обработки нашей транзакции на сервере брокера (например ошибка при выставлении заявки из-за отсутствия подключения, либо у клиента нет прав на отправку транзакции конкретного типа, либо заявка не проходит по лимитам и пр.).
Функция OnTransReply возвращает ответ на транзакцию, выставленную средствами qlua.
Сегодня:
Узнаем общее количество заявок
Функции getNumberOf и getItem
Как пройтись циклом по всем заявкам
Вывод активных заявок
Снять скриптом заявку
Снимаем все активные заявки скриптом
Снимаем только заявки, выставленные конкретным скриптом
В прошлый раз мы научились выставлять скриптом заявки в терминале, теперь можем поработать с ними.
Выставим скриптом 5 заявок на покупку и продажу от лучших цен BIDи OFFERстакана заявок с шагом в 0,01.
Напишем функцию, которая будет выдавать нам необходимые цены (лучшую цену спроса и предложения) со стакана:
И возвращать -1, если предложения или покупки в стакане не найдены (стакан закрыт, либо нет торгов).
Тогда основной алгоритм в main будет выглядеть:
Зачем нужен демо терминал?
Где открыть демо квик?
Выставление заявки в торговом терминале через скрипт.
Делаем функцию выставления заявки по требуемым условиям
Карман заявок и tri-файлы
Параметры для заявок с примерами по разным рынкам
Почему важно начинать работу с заявками на qlua с демо терминала?
В отличие от рассматриваемых ранее скриптов, в которых мы обращались к окнам терминала и обрабатывали данные с котировок, графиков, индикаторов и таблиц, делали расчеты, выводили сообщения или собственные таблицы, работа с заявками уже завязана на денежные средства. И т.к. у начинающих всегда есть риски ошибок в коде, различных опечаток, некорректном запуске выставлении заявки в цикле и пр., то начать работу с этой темой я настоятельно рекомендую именно в демо терминале. И речь здесь не только о комиссиях за сделку на которые можно попасть, но и вероятности купить не тот инструмент, не в том объеме, как следствие, например влететь на маржиналку и пр., и пр.
Достаточно, например, прописать в
Сегодня:
Работа с биржевым стаканом через getQuoteLevel2
Особенность нумерации в стакане заявок терминала квик
Работа через функцию обратного вызова OnQuote
Примеры работы со стаканом из скрипта
Сравнение реализации одной алгоритма через разные функции
Из таблицы текущих торгов мы можем получать большой перечень данных, в т.ч. по лучшим ценам спроса и предложения, из которых желающие получат спрэд по выбранному инструменту. Однако иногда нужно заглянуть именно в биржевой стакан. Это, например, пригодится нам далее при выставлении заявок.
Работать с биржевым стаканом можно через getQuoteLevel2 и функцию обратного вызова OnQuote.
Функция getQuoteLevel2 возвращает 2 массива котировок (bid и offer) и 2 значения: количество бидов в стакане (bid_count) и количество офферов (offer_count). Чтобы нам не было скучно разработчики терминала решили последних 2 параметра передавать в виде строки, поэтому при работе их нужно перевести в числа (через tonumber).
Массивы bid и offer содержат цены (price) и количество (quantity) по каждому уровню заявок стакана. Их также нужно будет предварительно перевести в число.
Сегодня:
Добавляем статистику по акциям роста и падения.
Составляем TOP лидеров роста и падения.
Быстрый поиск акций по тикеру в терминале.
Пока не перешли к следующей теме решил показать, как можно улучшить скринер акций, который делали ранее. Кто еще не знаком или уже забыл о чем был скрипт лучше вернуться и хотя бы бегло ознакомиться с логикой и пошаговым построением, чтобы было легче вникнуть в текущие изменения.
Напомню, что скринер выводил по тикерам акции, которые торгуются на Московской Бирже (за минусом бумаг с нулевыми объемами), и по ним через каждые 10 секунд проверял значение LASTCHANGE (% роста/снижения к закрытию прошлого дня) через getParamEx.
В первичной итерации скринер выглядел следующим образом:
Логично продолжить изменения скрипта и сделать расчеты, которые напрашивались, глядя на сам скринер: подсчитаем сколько бумаг торгуется в плюсе, сколько в «красной зоне». Также можно рассчитать средний процент роста/снижения всего по списку, плюс отдельно по растущим бумагам, отдельно по падающим.
Сегодня завершаем работу с лентой всех сделок:
Различия данных ленты всех сделок и биржевого стакана.
Большие покупки и продажи в ленте сделок и динамика цены.
Альтернативные варианты поиск крупных игроков по ленте сделок.
Начало: https://smart-lab.ru/blog/935919.php
Еще раз про отличия ленты всех сделок и биржевого стакана – некоторые заявки могут исполняться очень быстро, их можно просто не заметить в стакане, но они точно отразятся в ленте. Какие-то заявки и движения в стакане могут быть для создания видимости крупных игроков, при этом они могут как отменяться как только цена начинает приближаться, так и очень оперативно переставляться. Лента сделок покажет реальную картину: какие объемы и по каким ценам прошли, какие проходят в текущем моменте.
Обычно при значительных покупках в ленте сделок мы можем наблюдать и рост цены. Например, используя скрипт, который мы рассмотрели в прошлой статье, это можно было наблюдать наглядно на графике Сбербанке (импульс роста в районе 12 часов):
Сегодня рассмотрим:
Что такое таблица обезличенных сделок.
Настройка таблицы в терминале.
Что делать, если таблица открылась, но она пустая.
Вывод данных с таблицы по DDE.
Работа с таблицей обезличенных сделок через скрипт qlua с примерами.
Пишем советника, показывающего на графике крупных игроков.
Лента всех сделок (она же таблица обезличенных сделок, она же таблица всех сделок) — это тиковый массив сделок с одним или несколькими инструментами, в котором отражается информация по каждой сделке, в т.ч.: цена, объём и направление транзакции (покупка/продажа). Обычно для работы выбирается один инструмент, который отслеживается, реже 2 (например базовый актив и ближайший фьючерс на него). Встречал варианты, когда грузят сразу большой список, но в этом случае может сильно подвисать терминал.
Зачем нужна лента сделок: многие, пытаясь торговать внутри дня, проводят часы за медитативным наблюдением за биржевым стаканом. Однако стакан заявок это только намерение, далеко не все выставленные заявки перейдут в сделки. Более того иногда по некоторым акциям (2го и 3го эшелона) заявки в стакане могут активно «двигаться», создавая видимость, что в бумаге идет активная торговля, при этом, если открыть таблицу всех сделок, то будет видно, что реальных сделок практически нет.