Инвестиции с нуля

От первого шага до первой прибыли

Робот Scatter&Gather: Время разбрасывать камни и время собирать камни

Scatter&Gather v10.6_medium: Работа над ошибками

Знаете это чувство, когда вроде бы всё работает, робот шуршит заявками, портфель растёт, а внутри зудит: что-то не так? Вот и я успокаивал себя статистикой. Весь январь — ни одной ошибки. Но февраль расставил всё по местам. Ошибка, дремавшая в недрах Scatter&Gather v10.5_medium, решила напомнить о себе громким хлопком. И знаете, что самое коварное? Она не роняла терминал, не сыпала красными сообщениями в лог. Она просто делала вид, что всё под контролем, а в это время данные робота расходились с реальностью. Брокер считал одно количество акций в портфеле, робот — другое. Знакомая история: эта беда в разных комбинациях преследует меня с самого начала.

И всего-то делов — за полтора месяца на пяти роботах ошибка выскочила всего два раза. Но зачем она нам нужна? Пришлось отвлечься от разработки робота TrendPlus и браться за исправление Scatter&Gather.

Почему робот начал жить в параллельной реальности

Давайте честно: в момент проектирования мне казалось, что подтверждение от брокера придёт мгновенно. Ну что там тянуть? Отправил заявку — исполнил — получил отчёт. Тик-так, тик-так. Но в реальном мире, особенно на фондовом рынке, бывает всякое. Каналы связи шалят, брокерская система задумывается, а в особо пикантные моменты даже сам QUIK может взять паузу.

И вот здесь начиналось то, чего я никак не мог ожидать. Робот выставлял заявку на продажу и, не дожидаясь подтверждения, генерировал новую пару предзаявок. Ведь код все равно отследит сделку, только немного позже. У меня есть защита даже на случай остановки робота — отслеживание выставленной заявки продолжится после старта. Но одну ситуацию я не предусмотрел — если сработает новая предзаявка на продажу, выставится вторая заявка. Робот возьмет ее под контроль, бросив предыдущую. А старая заявка тем временем спокойно себе исполнится на стороне брокера. Только её подтверждение робот уже не отслеживал.

Дальше — хуже. Вторая заявка (уже новая) тоже исполнится. Робот послушно зафиксирует сделку и запишет её в Profit.txt. А первую сделку, как я уже написал выше, он просто проигнорирует, потому что «не может» её отслеживать. В его системе координат одновременное существование двух заявок невозможно. Но брокер этого, разумеется, не знает.

Что мы имеем в сухом остатке

Картина маслом: брокер честно провёл две продажи. Бумаги списаны, деньги зачислены. А робот живёт в убеждении, что он сделал только одну продажу. Портфель по версии брокера худеет, а робот упорно считает, что всё в рамках плана. Если все так и оставить, расхождение будет нарастать, как снежный ком.

Самое неприятное здесь даже не финансовая погрешность, а потеря управления. Если робот перестаёт адекватно оценивать собственные позиции, любые дальнейшие действия становятся гаданием. Можно, конечно, довериться интуиции, но когда речь идёт о механической торговле, интуиция — плохой советчик. Мне нужна детерминированность, предсказуемость и железобетонная уверенность в том, что заявка либо исполнилась, либо нет. Третьего не дано.

Я всегда говорю: торговый робот — это не чёрный ящик. Это, скорее, диспетчерская вышка. И если диспетчер видит не все самолёты на радаре, катастрофа — лишь вопрос времени.

Как я лечил «разрыв шаблона»

Решение лежало на поверхности, но, как это часто бывает, требовало не просто «добавить флажок», а переосмыслить логику ожидания. Я убрал из кода двусмысленность. Теперь алгоритм работает жёстко и однозначно: пока текущая сделка не получила окончательного подтверждения исполнения, никакие новые предзаявки не генерируются.

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

Вы спросите: а если подтверждение идёт неприлично долго? Что ж, в новой версии я заложил разумные таймауты и механизмы перепроверки, но без самодеятельности. Робот не додумывает за брокера. Если ответа нет, он ждёт. Да, это снижает частоту выставления заявок в пиковых ситуациях. Но я предпочту потерять копейку на недозаработанном спреде, чем потерять контроль над портфелем.

Весь робот — в пяти файлах

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

Вот они, герои обновления:

  • DataManager_v10.6.lua
  • HistoricalTester_v10.6.lua
  • ML_Enhancer_v10.6.lua
  • S&G_v10.6_medium.lua
  • StepOptimizer_v10.6.lua

В запускающем файле S&G_v10.6_medium.lua нужно будет заново прописать свои учётные данные для фондового рынка: депозит, класс инструмента и код клиента. Все остальные файлы, создаваемые роботом не требуют замены, они подхватятся автоматом.

После замены файлов не забудьте перезапустить скрипт в QUIK старым добрым способом: «Сервисы» → «Lua скрипты», удалить устаревшего робота и указать путь к свежему S&G_v10.6_medium.lua.

Вместо заключения

Ну что же, продолжим тестирование обновленного робота. Версия v10.6_medium не претендует на звание идеала. Будут новые ошибки, новые нюансы, новые феврали, которые заставят краснеть. Но эта конкретная проблема — с двойными заявками — надеюсь, закрыта окончательно.

Скачать робота:

Scatter&Gather v10.6_medium (download)
Downloaded: 8. Size: 294.8 KB. Date: 11 Фев. 2026