Трейдинг на MOEX: QUIK + LUA для исполнения, Python для аналитики
На этой странице — краткий “скелет” проекта: как обычно строят связку терминал QUIK → скрипт на LUA → Python-сервис для стратегий, риск-менеджмента, бэктестов и мониторинга.
Московская биржа: что обычно автоматизируют
Технически чаще всего автоматизация сводится к получению данных, расчёту сигналов и управлению заявками.
Данные
Стакан, сделки, свечи, позиции, состояние портфеля, торговые сессии и статусы инструментов.
Сигналы
Спреды, тренд/контртренд, арбитраж, маркет-мейкинг, фильтры по волатильности и ликвидности.
Исполнение
Лимитные/рыночные заявки, стоп-ордера, сопровождение позиций, частичное исполнение, отмены.
Торговля в терминале QUIK
QUIK часто используют как “шлюз”: он получает данные от брокера и позволяет отправлять заявки через LUA.
Настройка брокера/счёта, проверка доступов и торговых ограничений.
Таблицы/стакан/лента — выбираем минимум нужного, чтобы не перегружать терминал.
Обрабатывает события, пишет логи, ставит/снимает заявки, общается с внешним сервисом.
Ручная панель: пауза, аварийная остановка, состояние позиций, отчёты по сделкам.
LUA в QUIK: автоматизация исполнения
Скрипт в QUIK обычно делает самое “критичное”: реагирует на рынок и управляет заявками.
События
Обработка изменений стакана/сделок/свечей и статусов заявок.
Заявки
Создание/снятие/модификация заявок, стопов, контроль частичного исполнения.
Связь с Python
Отправка данных в локальный сервис (HTTP/сокеты/файлы) и получение команд/сигналов.
Python: исследования, стратегии и мониторинг
Python удобен для бэктестов, оптимизации параметров, интеграций (БД/Telegram/Prometheus) и UI.
Бэктест
Симуляция сделок по историческим данным, учёт комиссий/проскальзывания, проверка устойчивости.
Риск-менеджмент
Лимиты на позицию, дневной убыток, максимальный объём, фильтры волатильности.
Мониторинг
Журналы, алерты, метрики: latency, отказоустойчивость, состояние соединений и очередей.
Типовая архитектура
Один из простых вариантов — держать исполнение внутри QUIK, а “мозг” вынести в Python.
Мини-примеры: LUA ↔ Python (шаблоны)
Ниже — безопасные “рыбки” кода без привязки к конкретным функциям брокера. Подставьте свои поля/методы.
-- Псевдокод: отправка котировки/сигнала в локальный Python-сервис
-- В QUIK используются доступные вам способы связи (в т.ч. сокеты/файлы/HTTP через dll).
-- Здесь логика показана схематично.
local function to_json(tbl)
-- замените на вашу JSON-сериализацию
return string.format('{"ticker":"%s","price":%s,"ts":%s}', tbl.ticker, tbl.price, tbl.ts)
end
local function send_event(event)
local payload = to_json(event)
-- send_http("http://127.0.0.1:8000/event", payload) -- пример
-- или write_to_file("events.log", payload .. "\n")
end
function onQuote(ticker, price)
send_event({
ticker = ticker,
price = price,
ts = os.time()
})
end
# Псевдокод: простой HTTP сервер (Flask) и логика "сигнал -> команда"
# pip install flask
from flask import Flask, request, jsonify
import time
app = Flask(__name__)
STATE = {
"last_price": {},
"cooldown_until": 0
}
def decide(ticker: str, price: float):
# Пример: очень условный "сигнал"
# Замените на вашу стратегию + риск-лимиты
prev = STATE["last_price"].get(ticker)
STATE["last_price"][ticker] = price
if prev is None:
return None
if price > prev * 1.002:
return {"action": "BUY_LIMIT", "ticker": ticker, "qty": 1, "price": round(price * 0.999, 2)}
if price < prev * 0.998:
return {"action": "SELL_LIMIT", "ticker": ticker, "qty": 1, "price": round(price * 1.001, 2)}
return None
@app.post("/event")
def event():
data = request.get_json(force=True)
ticker = data.get("ticker", "UNKNOWN")
price = float(data.get("price", 0))
# Пример простого "тормоза", чтобы не флудить командами
now = time.time()
if now < STATE["cooldown_until"]:
return jsonify({"command": None, "reason": "cooldown"})
cmd = decide(ticker, price)
if cmd:
STATE["cooldown_until"] = now + 0.2 # 200мс пауза
return jsonify({"command": cmd})
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8000)
FAQ
Короткие ответы на типичные вопросы при старте автоматизации.
Можно ли всё делать только в LUA, без Python?
Можно, особенно для простых правил исполнения и управления заявками. Python обычно добавляют ради исследований, бэктестов и интеграций.
Как безопасно “прикрутить” автоматизацию к реальным деньгам?
Начинают с симуляции/песочницы, затем минимальные объёмы. Обязательно: лимиты, аварийная остановка, логи, мониторинг, контроль рассинхронизаций.
Что критично для надёжности?
Идемпотентность команд (повтор не ломает), подтверждения статусов заявок, восстановление после падений, журнал событий, и “безопасный режим” при ошибках связи.