Чому торговий бот падає і залишається лежати
Торговий бот рідко зупиняється гарно — він падає за одним із чотирьох сценаріїв, і кожен виглядає по-різному.
Збій з'єднання з біржею обриває потік котирувань, але цикл стратегії продовжує крутитися на останній відомій ціні: розрахунок іде за застарілими даними, а заявки вирушають за ціною, якої на ринку вже немає.
Зависання процесу небезпечніше за явне падіння. Процес значиться живим, відповідає на перевірку, але торговий цикл зупинився на заблокованому виклику — зупинка торгового бота не фіксується ні моніторингом, ні логами.
Виняток у стратегії або розрахунок, що з'їв пам'ять, валять бота зовсім: з'єднання закрито, а стан на біржі залишився незмінним.
Поки бот мовчить, незакрита позиція живе своїм життям. Стоп-заявки, які утримувалися віртуально всередині стратегії, ніхто не переставляє, експозиція зростає разом із рухом ринку, а розбіжність між локальним станом і реальними ордерами накопичується. Після ручного підйому бот отримує чужий портфель і працює з ним як із чистого аркуша.
Уночі та на вихідних така відмова коштує годин простою: черговий дізнається про неї з просадки, а не із сигналу, і до втручання ринок встигає піти далеко.
Тому розбираємо, як автоматичний перезапуск торгового бота закриває кожен із цих сценаріїв окремо — від контролю живості процесу до звірки стану з біржею перед поверненням у торгівлю.
Що дає автоматичний перезапуск торгового бота
Торговий бот зупиняється не через стратегію, а через середовище: обрив потоку котирувань, виняток в обробнику ордера, вичерпання пам'яті або завислий цикл.
Поки процес лежить, відкрита позиція залишається без нагляду, а ручний перезапуск уночі — це десятки хвилин простою, які ніхто не вимірює. Саме тому час простою стає такою ж робочою метрикою, як дохідність.
Автоматичний перезапуск торгового бота закриває це на рівні оточення. Супервізор — наприклад, 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-політики контейнера або власний сторожовий процес;
- перевірки живості, які відрізняють «процес працює» від «бот торгує» — свіжість останньої відповіді біржі, наявність активних підписок, відсутність залиплих ордерів;
- маршрутизацію алертів: миттєве сповіщення при падінні, щоденний зведений звіт щодо перезапусків, ескалація при повторних збоях;
- безпечну зупинку і відновлення стану — що робити з незакритими позиціями і як не задвоїти ордери після підйому;
- журналювання та зберігання логів, щоб розбирати причини, а не лише факт перезапуску;
- захист доступів до сервера і біржових ключів при автоматичному керуванні.
Опишіть задачу — повернемося з оцінкою робіт і планом впровадження, з етапами та порядком дій.







