Мы сталкиваемся с ситуацией: трейдеры пишут простые стратегии на QLUA, но для ML-моделей (LSTM, градиентный бустинг) нужны Python-библиотеки и GPU. QUIK — доминирующий терминал на российских рынках (ММВБ, СПБ Биржа), а QLUA — встроенный Lua-скриптовый движок. Проблема: QLUA не тянет тяжелые вычисления, а Python не умеет напрямую выставлять ордера. Решение — асинхронный TCP-мост между QLUA и Python AI-сервером. Ошибка в QLUA-скрипте может стоить миллионы, а latency в 50 мс — превратить прибыльную стратегию в убыточную. Наша команда устраняет эти риски, имея за плечами более 50 интеграций и 5+ лет опыта. Средний объём данных на один тик — 100 байт, что при 10 тиках в секунду даёт нагрузку 1 Кб/с — некритично.
Как работает интеграция AI-бота с QUIK?
Основной подход — QLUA-скрипт выступает посредником: получает данные от терминала, отправляет их в Python по TCP, получает сигнал и отправляет ордер. Это даёт минимальную задержку (p99 <10 мс) и полный контроль над ML-логикой. Рассмотрим типовую реализацию.
QLUA + Python TCP Bridge
-- QLUA скрипт: получает данные, отправляет Python, получает сигнал
local socket = require("socket")
local json = require("json")
local client = socket.tcp()
client:connect("127.0.0.1", 5555)
function OnBar(class_code, sec_code, interval, candle)
if class_code == "TQBR" and sec_code == "SBER" then
local features = {
open = candle.open,
high = candle.high,
low = candle.low,
close = candle.close,
volume = candle.volume,
symbol = sec_code
}
client:send(json.encode(features) .. "\n")
local signal_str = client:receive("*l")
local signal = json.decode(signal_str)
if signal.action == "buy" then
SendOrder(sec_code, signal.price, signal.quantity, true)
elseif signal.action == "sell" then
SendOrder(sec_code, signal.price, signal.quantity, false)
end
end
end
function SendOrder(sec_code, price, qty, is_buy)
local trans = {
CLASSCODE = "TQBR",
SECCODE = sec_code,
OPERATION = is_buy and "B" or "S",
PRICE = tostring(price),
QUANTITY = tostring(qty),
ACCOUNT = "L01-00000F00",
TYPE = "L",
TRANS_ID = tostring(os.time())
}
sendTransaction(trans)
end
# Python AI-сервер
import socket
import json
import numpy as np
from your_ml_model import predict
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 5555))
server.listen(1)
conn, addr = server.accept()
buffer = ""
while True:
data = conn.recv(4096).decode()
buffer += data
if '\n' in buffer:
line, buffer = buffer.split('\n', 1)
features = json.loads(line)
signal = predict(features)
conn.send((json.dumps(signal) + '\n').encode())
Сравнение подходов к интеграции
| Подход | Получение данных | Отправка ордеров | Задержка (p99) | Сложность |
|---|---|---|---|---|
| QLUA+TCP | Да | Да | <10 мс | Средняя |
| Trans2Quik | Нет | Да | <2 мс | Низкая |
| QuikSharp | Да | Да | <5 мс | Высокая |
Выбор между ними зависит от приоритетов: если нужен полный цикл — QLUA+TCP, если только быстрая отправка — Trans2Quik. Для .NET-проектов удобен QuikSharp, но он требует установки соответствующей среды.
Как избежать потери соединения?
При разрыве TCP-соединения QLUA-скрипт может зависнуть. Решение — watchdog в Python-сервере, который перезапускает скрипт при потере связи. Также в QLUA используем таймауты и повторные подключения. В таблице ниже — типовые задержки при разных способах получения данных.
| Источник данных | Частота обновления | Задержка (мс) |
|---|---|---|
| OnBar (1 мин) | Каждую минуту | 100-200 |
| OnTrade | Реалтайм | 10-50 |
| Level II (стакан) | Каждое изменение | 5-20 |
Получение биржевых данных
Финам Data Feed — для ML обучения: исторические данные через Финам API или экспорт из QUIK. QLUA Data Tables — для потоковых данных.
-- Получение всех сделок из таблицы
local trades_table = getTable("trades")
local num_rows = #trades_table
-- Подписка на стакан
Subscribe_Level_II_Quotes("TQBR", "SBER")
local order_book = getParamEx2("TQBR", "SBER", "BID")
Специфика российского рынка
Режим T+2 на ММВБ: учёт в AI-стратегиях. Short позиции требуют РЕПО или наличия ценных бумаг. Брокерские комиссии: типичные 0.035–0.1% от оборота. Для дейтрейдинга это значимо. Брокерский сбор + биржевой сбор + НКД для облигаций.
Фьючерсы и опционы через FORTS: отдельный класс SPBFUT. Кодировка тикеров (SiM5, RIM5). Часовое гарантийное обеспечение.
Что делать, если модель даёт ложные сигналы?
Ложные сигналы — частая проблема ML-стратегий. Мы внедряем фильтрацию: дополнительная статистическая проверка (z-score, Z-test) перед отправкой ордера. Также используем стоп-лоссы и ограничение на количество сделок в минуту.
Процесс работы
- Аналитика: обсуждаем стратегию, выбираем стек (QLUA+Python или другой).
- Проектирование: архитектура TCP-моста, типы ордеров, частоты данных.
- Разработка: пишем QLUA-скрипт, Python AI-сервер, интегрируем модель.
- Тестирование: paper trading в QUIK, симуляция рыночных условий с разными режимами T+2 и FORTS.
- Деплой: настройка мониторинга, автостарт скриптов, документация.
Сроки и стоимость
Интеграция под ключ занимает от 2 до 4 недель в зависимости от сложности ML-модели и количества инструментов. Стоимость рассчитывается индивидуально. Для ориентира: базовая интеграция QLUA+Python — от 2 недель, с обучением модели — до 2 месяцев.
Чек-лист для запуска AI-бота
- Настроить watchdog для TCP-соединения
- Включить логирование всех транзакций QLUA
- Проверить latency в пиковые нагрузки (более 100 сделок в секунду)
- Протестировать работу с разными классами инструментов (TQBR, SPBFUT)
- Установить лимиты на частоту ордеров
Что входит в работу
- QLUA-скрипт с обработкой ошибок и переподключением
- Python AI-сервер с интеграцией вашей модели
- Мониторинг через логи и метрики (latency, throughput)
- Документация по запуску и обслуживанию
- Обучение команды (2 часа)
- Поддержка 1 месяц после деплоя
Документация QLUA описывает все события и функции. Для старта достаточно socket-модуля Lua и socket-модуля Python.
Оцените ваш проект — напишите нам, мы поможем подобрать оптимальную архитектуру. Закажите консультацию, чтобы мы проанализировали вашу стратегию. Свяжитесь с нами для обсуждения деталей.







