Почему торговый бот падает и остаётся лежать
Торговый бот редко останавливается красиво — он падает по одному из четырёх сценариев, и каждый выглядит по-разному. Сбой соединения с биржей обрывает поток котировок, но цикл стратегии продолжает крутиться на последней известной цене: расчёт идёт по устаревшим данным, а заявки уходят по цене, которой на рынке уже нет.
Зависание процесса опаснее явного падения. Процесс числится живым, отвечает на проверку, но торговый цикл встал на заблокированном вызове — остановка торгового бота не фиксируется ни мониторингом, ни логами. Исключение в стратегии или расчёт, съевший память, роняют бота совсем: соединение закрыто, а состояние на бирже осталось прежним.
Пока бот молчит, незакрытая позиция живёт своей жизнью. Стоп-заявки, которые держались виртуально внутри стратегии, никто не переставляет, экспозиция растёт вместе с движением рынка, а расхождение между локальным состоянием и реальными ордерами накапливается. После ручного подъёма бот получает чужой портфель и работает с ним как с чистого листа.
Ночью и в выходные такой отказ стоит часов простоя: дежурный узнаёт о нём из просадки, а не из сигнала, и до вмешательства рынок успевает уйти далеко. Поэтому разбираем, как автоматический перезапуск торгового бота закрывает каждый из этих сценариев по отдельности — от контроля живости процесса до сверки состояния с биржей перед возвратом в торговлю.
Что даёт автоматический перезапуск торгового бота
Торговый бот останавливается не из-за стратегии, а из-за среды: обрыв потока котировок, исключение в обработчике ордера, исчерпание памяти или зависший цикл. Пока процесс лежит, открытая позиция остаётся без присмотра, а ручной перезапуск ночью — это десятки минут простоя, которые никто не измеряет. Именно поэтому время простоя становится такой же рабочей метрикой, как доходность.
Автоматический перезапуск торгового бота закрывает это на уровне окружения. Супервизор — например, systemd — держит процесс под наблюдением, поднимает его при падении и возвращает в строй за секунды вместо минут. В контейнерной схеме ту же роль играют политики перезапуска, а проверка живости цикла отличает реально работающий процесс от формально запущенного.
Время восстановления перестаёт зависеть от того, кто дежурит. При старте бот подтягивает актуальные позиции, сверяет их с журналом сделок и продолжает с той же точки, а не с нуля. Восстановление становится предсказуемым: одинаковым днём и ночью, при обрыве связи и при сбое самого процесса.
Мониторинг состояния и уведомления об инциденте замыкают контур. Метрики живости, задержки обработки и числа перезапусков уходят в систему наблюдения, а сигнал приходит только тогда, когда цикл не поднялся сам. Тем самым уходит целый класс отказов — «бот упал, и об этом узнали утром по убытку», а ручные вмешательства в ночные часы сводятся к нулю.
Варианты организации перезапуска и их ограничения
Выбор варианта определяется не удобством, а тем, какой отказ нужно закрыть: падение процесса, зависание логики при живом процессе или разрыв соединения с биржей. Это разные классы сбоев — и не каждая схема их различает.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Менеджер служб | Одиночный бот на выделенном сервере, без контейнеров | Видит только выход процесса: зависший, но живой бот продолжает висеть. Нет учёта причины падения и нарастающей паузы между попытками |
| Контейнер и оркестрация | Несколько ботов, изоляция зависимостей, воспроизводимый запуск | Перезапуск обнуляет состояние в памяти — незакрытые позиции, локальные счётчики. Проверку живости пишут вручную, бизнес-логику она не видит |
| Сторожевой процесс | Нужно ловить не «умер ли», а «работает ли»: свежесть сделок и котировок, наличие соединения | Требует сопровождения: при неверных условиях плодит копии бота, а сами условия приходится пересматривать при смене стратегии |
| Внешний мониторинг | Нужны метрики, история сбоев и оповещения ответственного | Сам не лечит: об простое вы узнаёте быстрее, но простой длится, пока дежурный не вмешается |
| Ручной контроль | Отладка, стратегии с подтверждением входов вручную | Время реакции — минуты и часы; ночь, выходные и отпуск остаются незакрытыми |
Рабочие схемы почти всегда комбинированные: менеджер служб или контейнер даёт базовый перезапуск, сторожевой процесс добавляет проверку логики, внешний мониторинг — оповещения и историю. Дальше разбираем, как эти слои собрать в один контур с предсказуемым поведением.
Политики перезапуска, зависимости и состояние бота
Политика перезапуска описывается в конфигурации явно, а не «на всякий случай». Мы задаём задержку между попытками, лимит повторов и поведение после его исчерпания: супервизор systemd возвращает процесс при сбое, но при зацикливании останавливает его и отправляет событие в систему оповещений вместо бесконечного круга.
Порядок запуска зависимостей важнее самой политики. Бот поднимается после хранилища позиций, очереди задач и подтверждённого доступа к бирже, и каждый шаг подтверждается проверкой готовности, а не фактом «процесс запущен». Иначе рестарт начинается на пустом кэше — часть заявок остаётся без контроля.
Состояние позиций живёт вне процесса: журнал сделок, открытые заявки, размер позиции и время последней синхронизации. При старте бот восстанавливает картину из хранилища и сверяет её с биржей, а расхождения попадают в отчёт дежурному, а не в рыночные действия.
Идемпотентность операций закрывает главный риск — дубли сделок. Каждой заявке присваивается собственный идентификатор, поэтому повтор после перезапуска распознаётся как уже исполненный и не превращается во вторую сделку.
Этапы внедрения автоперезапуска и алертов
Автоперезапуск без аудита причин опасен: бот поднимается и падает по кругу, а настоящая проблема — утечка памяти, обрыв связи с биржей, отклонённый ордер — остаётся незамеченной. Поэтому идём последовательно: сначала разбираем, почему процесс падает, затем проектируем восстановление и только потом включаем автоматику.
-
Аудит отказов. Разбираем журналы и коды выхода, отделяем внешние сбои от ошибок логики: сколько падений за период, какие повторяются, что происходит с открытыми позициями в момент остановки — закрыты они, висят ли заявки на бирже.
-
Схема восстановления. Решаем, что делать сразу после подъёма: сверять фактические позиции с состоянием хранилища, снимать незакрытые заявки, повторять только безопасные операции. Задаём лимит попыток и растущую паузу между ними, чтобы бот не заваливал биржу запросами.
-
Настройка перезапуска. Сервис описываем как управляемый юнит systemd с политикой запуска и ограничением частоты рестартов; порядок подъёма зависимостей — хранилище состояния, очереди — задан явно. Для контейнера те же правила живут в политике перезапуска.
-
Настройка алертов. Сигналы делим по важности: падение процесса, пропавший сигнал живости, серия отклонённых ордеров, расхождение баланса. Каждому — свой порог и канал, с дедупликацией, чтобы дежурный получал одно уведомление на инцидент, а не поток.
-
Проверка на сбоях. На тестовом контуре намеренно роняем процесс, обрываем соединение, задерживаем ответы биржи и смотрим, восстанавливается ли бот без потери позиций. Отдельно чистим ложные срабатывания: алерт, который кричит зря, перестают читать.
-
Передача в эксплуатацию. Отдаём регламент дежурства: типовые отказы, что смотреть в журналах, как поднять вручную, как действовать при расхождении позиций. Прогоняем сценарии вместе с вашей командой — дежурство не должно зависеть от нас.
Что остаётся у заказчика после внедрения
После внедрения у заказчика остаётся не набор разрозненных скриптов, а работающий контур с понятными точками вмешательства. Все решения передаются комплектом: конфигурациями, схемами и регламентами, по которым команда может сопровождать бота самостоятельно — или отдать нам только дежурство.
- Конфигурации служб. Файлы systemd с политиками автоматического перезапуска, задержкой между попытками и лимитом на количество падений — поведение бота при сбое одинаково независимо от того, кто на смене.
- Контейнерные манифесты и политики. Для Docker-развёртывания настраиваются перезапуск контейнера и проверка живости: бот поднимается заново не только после падения процесса, но и когда он завис, а соединение с биржей не работает.
- Схема зависимостей. Что должно быть доступно до старта — торговый шлюз, хранилище ключей, база, канал уведомлений — с порядком запуска и таймаутами ожидания.
- Правила алертов. Разделение событий: что уходит дежурному немедленно, что накапливается в отчёте, а что пишется только в журнал. Пороги задаются так, чтобы ночные перезапуски не превращались в поток ложных вызовов.
- Регламент реакции. По каждому типу алерта описано: что проверяет дежурный, когда перезапускает вручную, когда откатывает конфигурацию, когда останавливает торги и эскалирует.
- Документация. Инструкция «как поднять контур с нуля», размещение секретов, порядок проверки, что бот действительно торгует, а не просто числится запущенным.
- Журналы и логи. Настроенная ротация и срок хранения, фиксация состояния позиций и последних запросов перед перезапуском — по ним причина сбоя разбирается без предположений.
Приёмка идёт сценариями: гасим процесс, обрываем сеть, отзываем доступ к шлюзу и смотрим, восстанавливается ли бот по регламенту. Опишите задачу — вернёмся с оценкой и планом работ.
Кейс: бот перестал требовать ночного дежурства
Стратегия работала круглосуточно на нескольких биржах, и открытые позиции нельзя было оставлять без присмотра. До внедрения бот падал 5–6 раз в неделю: обрыв связи с биржей, неожиданный формат ответа API, исчерпание пула потоков после серии переподключений. Каждый сбой — ночной подъём, ручной перезапуск, сверка позиций: 40–50 минут простоя и три-четыре сорванных ночи в неделю.
Что изменили
Процесс перевели под сервисный менеджер с перезапуском по коду выхода, а проверка живости смотрит не на «процесс запущен», а на последний успешный обмен с биржей. Перед рестартом позиции и ордера сбрасываются на диск, поэтому повторный запуск не открывает дубли сделок. Ограничение частоты — не больше трёх перезапусков за десять минут — не даёт уйти в штормовой цикл.
Алерты вывели в Prometheus с разделением по критичности: одиночный сбой гасится молча и остаётся в журнале, дежурного поднимают, только если три попытки подряд не дали живого состояния.
После внедрения 5–6 падений в неделю превратились в 1–2 в месяц, время восстановления сократилось с 40–50 минут до 10–20 секунд, около 90% сбоев закрываются без человека. Ночные подъёмы — 1–2 раза в квартал вместо трёх-четырёх в неделю, дежурство перестало быть круглосуточным.
Журнал перезапусков заодно показал корневую причину — частые таймауты при переподключении; их закрыли настройкой повторов в модуле доступа к API. Автоматика осталась страховкой на случай реального отказа, а не ежедневным инструментом.
Чем перезапуск процесса отличается от восстановления состояния
Перезапуск процесса — техническая операция, которую умеют systemd или Docker: упавший процесс поднимается за секунды и снова отвечает на сигналы. Но это отвечает лишь на вопрос «жив ли процесс», а не на вопрос «продолжает ли бот ту же торговлю». Между этими состояниями лежит вся разница в цене ошибки.
Восстановление состояния — отдельная задача. Открытые позиции, выставленные заявки, незавершённые циклы и точка, на которой прервался расчёт, живут в оперативной памяти; после падения её содержимое теряется. Процесс стартует с чистого листа и по умолчанию не знает, что половина работы уже сделана.
Отсюда первое обязательное действие при старте — сверка позиций. Бот опрашивает биржевой интерфейс и сопоставляет фактические позиции и активные заявки с собственной моделью. Расхождение означает, что предыдущий цикл завершился не полностью, и торговлю нельзя возобновлять, пока состояние не приведено к общему знаменателю.
Второй контур — журнал операций, куда намерение пишется до отправки заявки, а результат после. Он даёт основу для обработки дублей: заявка, ушедшая перед падением, могла уже исполниться, поэтому повтор отправляется с уникальным идентификатором, который биржа отклонит как повторный. Без журнала восстановление превращается в догадки и удвоенные позиции.
Практический порядок такой: поднять процесс, прочитать журнал, сверить позиции с биржей, погасить дубли и только затем вернуть торговый цикл. Так перезапуск остаётся дешёвой операцией, а восстановление состояния — контролируемым.
Технические сомнения перед стартом работ
Перед стартом автоматического перезапуска бота заказчики задают одни и те же инженерные вопросы: не начнёт ли бот дублировать заявки, что будет при недоступности биржи, где лежат ключи доступа. Ниже — короткие ответы, как это устроено в нашей схеме.
Как отличить ложное срабатывание от реального падения?
Супервизор смотрит не только на процесс, но и на признаки живости: время последнего запроса к бирже, рост ошибок в логе. Рестарт идёт после серии неудачных проверок подряд, единичный таймаут его не вызывает.
Не появятся ли дубли ордеров после перезапуска?
Перед открытием позиций бот сверяет состояние с биржей: активные заявки и позиции запрашиваются заново, свои записи помечаются клиентским идентификатором. Незавершённые операции подтверждаются или отменяются до старта торговой логики — вторая заявка не создаётся.
Что происходит при отказе биржи?
Недоступность биржи не считается падением бота: рестарт здесь не помогает, поэтому включается пауза с нарастающей задержкой между попытками. Когда связь вернулась, бот заново сверяет позиции и продолжает с подтверждённого состояния.
Где хранятся ключи доступа к бирже?
Ключи лежат не в коде и не в репозитории, а в защищённом хранилище секретов, доступном только сервисной учётной записи. В логи и уведомления они не попадают, права ключа ограничиваем торговлей без вывода средств.
Обсудим вашу задачу и вернёмся с планом
Чтобы оценка была точной, а не «примерно», нам нужно понять текущую схему запуска и характер падений. Опишите, как бот стартует сегодня: вручную в терминале, systemd-юнитом, в контейнере или по расписанию на арендованном сервере. Отдельно важно, как часто он падает и что в этот момент происходит с открытыми позициями — остаются без присмотра, закрываются по стоп-лоссу или зависают в полусостоянии.
Из ответов вырастает план внедрения: где именно ставить автоматический перезапуск торгового бота, какие проверки здоровья писать и куда направлять алерты, чтобы вы узнавали о сбое раньше, чем увидите просадку. В ответ вы получите:
- разбор текущей точки отказа — падение процесса, зависание потока, разрыв связи с биржей или отказ API-ключа;
- схему перезапуска: политика Restart в systemd, restart-политики контейнера или собственный сторожевой процесс;
- проверки живости, которые отличают «процесс работает» от «бот торгует» — свежесть последнего ответа биржи, наличие активных подписок, отсутствие залипших ордеров;
- маршрутизацию алертов: мгновенное уведомление при падении, ежедневная сводка по перезапускам, эскалация при повторных сбоях;
- безопасную остановку и восстановление состояния — что делать с незакрытыми позициями и как не задвоить ордера после подъёма;
- журналирование и хранение логов, чтобы разбирать причины, а не только факт перезапуска;
- защиту доступов к серверу и биржевым ключам при автоматическом управлении.
Опишите задачу — вернёмся с оценкой работ и планом внедрения, с этапами и порядком действий.







