Робот на сервере, QUIK у клиента: как устроена распределённая торговая система
Один сервер обслуживает много терминалов: котировки берутся с ISS МосБиржи напрямую, заявки уходят в QUIK клиента через службу-шлюз, а счёт, ключи и деньги остаются у клиента. Разбор схемы и её слабых мест.
Самый частый способ запустить торгового робота — поставить его на тот же компьютер, где работает QUIK. Так проще всего: терминал рядом, данные под рукой, заявки отправляются в соседний процесс.
И так же просто всё ломается. Windows уходит в перезагрузку ради обновления, провайдер теряет связь на десять минут, кто-то выключает машину — а позиция в это время живёт сама по себе. Для стратегии, которая держит сделки часами, это не мелочь.
Ниже — схема, по которой мы работаем вместо этого: робот живёт на сервере, терминал остаётся у клиента, и один сервер обслуживает много терминалов сразу.

Два потока, которые нужно развести
Робот делает две принципиально разные вещи: читает рынок и отправляет заявки. В простой схеме и то и другое идёт через терминал. В распределённой эти потоки разделены, и это главное решение, из которого вытекает всё остальное.
Рыночные данные приходят с ISS МосБиржи — открытого интерфейса самой биржи. Сервер забирает обезличенные сделки, свечи и стаканы напрямую, терминал в этом не участвует.
Торговые команды идут через терминал клиента. На сервере работает служба-шлюз, в QUIK у клиента установлен скрипт на QLua — встроенном языке терминала. Шлюз передаёт скрипту команду поставить заявку, скрипт отдаёт её терминалу, терминал отправляет брокеру. Обратно тем же путём возвращаются подтверждения: заявка зарегистрирована, исполнена частично, снята.
Больше на машине клиента не стоит ничего. Ни службы, ни агента, ни «нашего клиента» — только текстовый скрипт внутри QUIK, который можно открыть и прочитать.
Почему данные берутся мимо терминала
Терминал получает рыночные данные и сам — казалось бы, зачем отдельный источник.
Задержка на активном рынке. Поток обезличенных сделок, идущий через терминал, начинает отставать именно тогда, когда идёт всплеск активности. Биржевой интерфейс отдаёт те же данные без посредника.
Умножение работы. Если клиентов десять и данные собираются через их терминалы, одни и те же котировки приедут на сервер десять раз, и каждый терминал будет этим занят. С биржи данные приходят один раз и используются всеми стратегиями сразу.
Воспроизводимость. Данные одинаковы для всех: не нужно разбираться, почему у одного клиента стакан выглядит иначе, чем у другого, и как у кого настроены таблицы. Для отладки стратегии это важнее, чем кажется.
Что именно стоит у клиента
Скрипт QLua внутри терминала делает три вещи:
- Принимает команды от службы-шлюза и передаёт их терминалу через его собственные функции отправки транзакций.
- Возвращает события: заявка принята, отклонена, исполнена частично или полностью, снята.
- Отвечает на запросы о состоянии — сколько денег на счёте, какая позиция открыта, какие заявки живы, какой шаг цены и размер лота у инструмента. Эти параметры знает только терминал конкретного клиента, и без них нельзя ни рассчитать объём, ни выставить корректную цену.
Третий пункт часто упускают при проектировании, а он критичен: сервер не имеет права считать, что знает состояние чужого счёта. Он обязан спрашивать.
Почему деньги остаются у клиента
Это первый вопрос, который задаёт любой человек в здравом уме, и ответ должен быть не обещанием, а свойством конструкции.
Робот не подключается к брокеру. У него нет ни логина, ни пароля, ни ключа API, ни доступа в личный кабинет. Он разговаривает только с терминалом, который клиент запустил сам и авторизовал под своей учётной записью.
По каналу ходят только торговые команды. Вывод средств — операция личного кабинета брокера, а не торгового терминала. Даже получив канал целиком, снять через него деньги нельзя: такой операции в нём просто нет.
Выключение — одной кнопкой. Клиент останавливает скрипт в QUIK, и сервер мгновенно теряет всякую возможность что-либо сделать на счёте.
Из этого следует и обратное, о чём честно предупреждаем: ответственность за торговлю остаётся на владельце счёта. Робот исполняет алгоритм, а не управляет деньгами.
Что даёт схема «один сервер — много терминалов»
Логика живёт в одном месте: стратегии, расчёт объёма, лимиты, журнал сделок, мониторинг. Исполнение — у каждого своё, на его счёте, у его брокера, по его тарифам.
- Обновление в одной точке. Поправленная стратегия начинает работать у всех сразу, без рассылки файлов и просьб обновиться.
- Клиенту нечего настраивать. Установка сводится к добавлению скрипта в терминал.
- Общая картина. Позиции и заявки по всем счетам видны в одной панели, журналы лежат в одном месте. Когда что-то пошло не так, не приходится собирать картину по телефону.
- Разные стратегии и объёмы — это разные настройки на сервере, а не разные программы у каждого клиента.
- Ресурсы считаются один раз. Расчёт индикаторов по инструменту не зависит от числа клиентов, торгующих этот инструмент.
Где схема ломается и что с этим делать
Честная часть, без которой всё вышесказанное — реклама.
Терминал клиента должен быть запущен
Это главное ограничение. QUIK работает на машине клиента: выключена машина — робот бессилен. Обычное решение — недорогая виртуальная машина, на которой терминал живёт круглосуточно. Это отдельная статья расходов, и говорить о ней нужно до начала работы.
Связь рвётся
Канал между сервером и терминалом не вечен. Поэтому шлюзу нужен контроль живости: если терминал не отвечает дольше заданного времени, связь считается потерянной, и система не делает вид, что команда ушла.
Молчание нельзя трактовать как успех. Это самая дорогая ошибка в подобных системах: стратегия думает, что заявка стоит, а её нет — или наоборот.
Скрипт в терминале падает тихо
Одна ошибка в QLua останавливает скрипт, при этом сам терминал продолжает работать как ни в чём не бывало. Снаружи всё выглядит нормально: QUIK запущен, соединение с брокером есть. Поэтому нужен отдельный признак «скрипт жив» — периодический сигнал от самого скрипта, а не проверка того, что терминал в сети.
После обрыва нельзя доверять своей картине
Сколько заявок стоит в рынке и какая позиция открыта, знает терминал, а не сервер. Первое действие после восстановления связи — запросить у терминала фактическое состояние и только потом принимать решения.
Пренебрежение этим правилом стоит дорого: закрытие позиции по устаревшим данным способно не закрыть её, а открыть обратную. Это не теория — так бывает.
Версии расходятся
Терминалы у клиентов обновляются когда угодно. Протокол обмена между сервером и скриптом должен переживать ситуацию, когда на одном счёте стоит свежая версия, а на другом — полугодовой давности. Практически это означает версионирование команд и игнорирование неизвестных полей вместо падения.
Кому такая схема подходит
Подходит, если стратегия держит позиции минуты и часы, инструментов несколько, а клиентов больше одного. Выигрыш растёт с числом счетов: логика одна, исполнение разное.
Не подходит для сверхбыстрой торговли, где важны миллисекунды: лишнее звено в виде терминала и канала до него добавляет задержку. Там нужны прямые подключения и совсем другая архитектура.
Спорно для одного счёта и простой стратегии: если клиент один, проще поставить робота рядом с терминалом на ту же виртуальную машину и не городить распределённую систему.
Коротко
Котировки — с биржи напрямую, команды — через терминал клиента, логика и журналы — на сервере, счёт и деньги — у клиента и больше нигде.
Сложность такой системы не в идее, а в дисциплине: она обязана честно сообщать «я не знаю», когда связь оборвалась, вместо того чтобы докладывать об успехе. Всё остальное — следствие.
Как выглядит готовая система — панель, стратегии, журналы — показано на странице платформы управления торговыми ботами. Если нужна такая схема под ваши счета и вашу стратегию, посмотрите, что входит в разработку торгового робота, или просто напишите мне.
Текст не является инвестиционной рекомендацией и не содержит обещаний доходности. Ответственность за торговые решения остаётся на владельце счёта.