SSD Nodes Learn 8GB RAM — $66/рік
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-01

VPS для торгового бота: що справді важливо

Дізнайтеся, як systemd перезапускає бота, навіщо потрібен точний час, як захистити API keys і чому затримка VPS не дорівнює швидкості ордера.

Що потрібно торговому боту від VPS

VPS для торгових ботів оцінюють за чотирма критеріями: чи відновлюється процес після завершення роботи, чи правильно налаштований системний час, чи надійно захищені API (application programming interface) keys від викрадення та чи дізнаєтеся ви про зупинку. Сира швидкодія для роздрібного бота має значно менше значення, оскільки повільною частиною маршруту вашого ордера є брокер і відстань до нього, а не хост, на якому працює ваш Python.

Це інженерний посібник. Наведена інформація не є фінансовою порадою, і жодні стратегії тут не розглядаються.

Безперервна робота — це дисципліна перезапуску, а не число на сторінці продажу

Кожен хост у світі заявляє про 99.9 відсотка безперервної роботи. Це значення описує гіпервізор, а не ваш бот. Бот завершує роботу через необроблений виняток, websocket, який не виконує повторне підключення, або засіб OOM (out of memory), а сервер увесь цей час продовжує працювати. Тому корисне запитання полягає в тому, що відбувається протягом десяти секунд після завершення процесу.

Запустіть бота як службу systemd і передайте init-системі керування перезапуском. Файл unit виконує це у шістьох рядках.

[Unit]
Description=Trading bot
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0

[Service]
Type=simple
User=bot
WorkingDirectory=/opt/tradingbot
EnvironmentFile=/etc/tradingbot/api.env
ExecStart=/opt/tradingbot/venv/bin/python -m tradingbot
Restart=always
RestartSec=10
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/tradingbot

[Install]
WantedBy=multi-user.target

StartLimitIntervalSec=0 — це рядок, який часто пропускають. За замовчуванням systemd припиняє спроби після 5 перезапусків за 10 секунд і назавжди залишає unit у стані failed. Саме цього не повинно відбуватися о 03:00. Значення 0 вимикає обмеження частоти, тому бот, який постійно аварійно завершує роботу, продовжує спроби замість того, щоб замовкнути. RestartSec=10 запобігає перевантаженню біржі повторними підключеннями під час цього циклу.

Перевірте файл, перш ніж покладатися на нього, а потім запустіть службу:

sudo systemd-analyze verify /etc/systemd/system/tradingbot.service
sudo systemctl daemon-reload
sudo systemctl enable --now tradingbot
systemctl status tradingbot

enable — це частина, яка зберігається після перезавантаження, а оновлення ядра означають перезавантаження. Щоб перевірити, чи бот непомітно завершує роботу, запитайте в systemd лічильник перезапусків:

systemctl show tradingbot -p NRestarts
journalctl -u tradingbot --since "24 hours ago" | tail -50

NRestarts=0 через тиждень означає, що бот працює належним чином. NRestarts=812 означає, що ви торгували за допомогою процесу, який усю ніч повторно підключається. Повний опис структури файлу unit, зокрема таймерів для запланованих завдань, таких як щоденний звіт, наведено в матеріалі запуск програми як служби systemd.

Налаштуйте час за UTC і переконайтеся, що його синхронізовано

API бірж підписують запити міткою часу й відхиляють запити, що виходять за межі допустимого інтервалу, часто 5 секунд або менше. Через неточний годинник виникають помилки, схожі на помилки автентифікації, тому користувачі годинами змінюють ключі, перш ніж перевірити час. В API на кшталт Binance повідомлення має буквальний вигляд: Timestamp for this request was 1000ms ahead of the server's time.

Налаштуйте сервер на UTC. Місцеві часові пояси спричиняють перехід на літній час, який може відбутися посеред торгової сесії.

sudo timedatectl set-timezone UTC
timedatectl

В Ubuntu постачається systemd-timesyncd — клієнт SNTP (простого протоколу мережевої синхронізації часу). Він підходить для журналів, але ненадійний для систем, яким потрібно підтримувати точність у межах кількох мілісекунд, оскільки опитує один сервер і не коригує годинник безперервно. Натомість використовуйте chrony:

sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony
chronyc tracking
chronyc sources -v

У chronyc tracking потрібно перевірити рядок System time, наприклад System time : 0.000031415 seconds fast of NTP time. Значення менше кількох мілісекунд є нормальним. Якщо відображається Leap status : Not synchronised, chrony ще не підключився до сервера. Зазвичай це означає, що вихідний UDP 123 заблоковано. Зачекайте хвилину й перевірте ще раз, перш ніж змінювати правила firewall.

Не зберігайте API keys у місцях, звідки ви їх копіюєте

Витік ключа біржі гірший за витік SSH key, оскільки дозвіл на виведення коштів одразу дає доступ до грошей. Більшість ризиків охоплюють дві практики.

По-перше, ніколи не надавайте bot key дозвіл на виведення коштів. Якщо біржа це підтримує, прив’яжіть key до IP-адреси сервера. Це єдиний засіб контролю, який робить викрадений key майже непридатним.

По-друге, не зберігайте secret у каталозі з кодом. Усе, що міститься в /opt/tradingbot, рано чи пізно потрапляє до git repository або backup archive. Збережіть його у файлі, власником якого є root, і який читає лише systemd:

sudo install -d -m 750 -o root -g bot /etc/tradingbot
sudo install -m 640 -o root -g bot /dev/null /etc/tradingbot/api.env
sudo nano /etc/tradingbot/api.env

Файл містить звичайні рядки KEY=value без лапок і без export. Режим 640 із групою bot означає, що service user може читати файл, а всі інші — ні. Перевірте це за допомогою sudo -u bot cat /etc/tradingbot/api.env, а потім від імені іншого user, де команда має завершитися помилкою Permission denied.

Сам bot не повинен працювати від імені root або вашого login user. Створіть system account без shell і без home directory для входу:

sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/tradingbot --create-home bot

Пояснення кожного з цих flags і межі фактичної дії ProtectSystem=strict наведено в матеріалі запуск сервісів від імені непривілейованого користувача. Решта базових налаштувань сервера — SSH keys і firewall — описана в матеріалі перші десять хвилин на новому VPS.

Дізнайтеся про збій раніше за брокера

systemctl status повідомляє, що процес запущено. Це не означає, що бот виконує роботу. Процес, який застряг у циклі повторних спроб підключення до недоступного websocket, проходить усі перевірки, які може виконати systemd.

Натомість використовуйте перевірку стану. Uptime Kuma підтримує push-монітори: він очікує, що бот викликатиме URL за розкладом, і надсилає сповіщення, коли виклики припиняють надходити. Додайте цей виклик у кінець основного циклу, після частини, яка підтверджує працездатність бота, наприклад після успішного отримання ринкових даних.

curl -fsS "http://monitor.example.com:3001/api/push/YOUR_TOKEN?status=up&msg=loop_ok"

Встановіть інтервал монітора приблизно вдвічі більшим за тривалість циклу, щоб звичайні затримки не спричиняли сповіщення. Запускайте монітор на іншому сервері, ніж бот, оскільки монітор, який завершує роботу разом із контрольованим компонентом, нічого не повідомить. Налаштування описано в розділі моніторинг стану на власному сервері за допомогою Uptime Kuma.

Також додайте сповіщення про стан диска. Бот, який записує докладні журнали, за кілька тижнів заповнить кореневу файлову систему, а заповнений диск припиняє запис до бази даних, але не мережеві виклики, тому симптоми будуть незрозумілими. journalctl --vacuum-time=14d і рядок SystemMaxUse= у /etc/systemd/journald.conf обмежують розмір журналу.

Чесно кажучи: затримка здебільшого залежить не від вашого хоста

Саме тут ринок VPS-продуктів для трейдингу перестає бути технічним. На маркетингових сторінках наводять значення менше мілісекунди та створюють враження, що саме хост визначає, чи буде виконано вашу заявку. Для майже всіх роздрібних ботів це не так.

Ваша заявка проходить від бота до кінцевої точки біржі або брокера через загальнодоступний інтернет. На цей шлях найбільше впливають фізична відстань і взаємоз’єднання між вашим провайдером та провайдером біржі або брокера. Сервер у Frankfurt, який обмінюється даними з кінцевою точкою в Tokyo, має затримку приблизно 250 мілісекунд у обидва боки незалежно від швидкодії CPU. Потім власні системи брокера додають затримку на обробку в черзі, перевірки ризиків і обмеження частоти запитів. Для роздрібного рахунку ці затримки зазвичай вимірюються десятками або сотнями мілісекунд.

Замість припущень виконайте вимірювання. curl повідомляє час встановлення з’єднання та час отримання першого байта для реальної кінцевої точки:

curl -s -o /dev/null -w 'dns=%{time_namelookup}s connect=%{time_connect}s ttfb=%{time_starttransfer}s\n' \
  https://api.kraken.com/0/public/Time
mtr -rwzc 100 api.kraken.com

Виконайте цю команду на сервері-кандидаті, перш ніж приймати рішення. Якщо connect дорівнює 0.180 секунди, сервер розташований не на тому континенті, і це варто виправити. Якщо connect дорівнює 0.004 секунди, а ttfb — 0.140 секунди, решта затримки припадає на обробку брокером, і зміна хоста на неї не вплине.

Коли хост справді має значення? Коли ви розміщуєте сервер у тому самому центрі обробки даних, що й торговельний майданчик, або використовуєте пряме мережеве з’єднання з ним і змагаєтеся за позицію в черзі. Це інший вид діяльності з іншим бюджетом. Хост також має значення, коли вузьким місцем є ваш власний код. Бот, який на кожному тиковому оновленні повторно обчислює індикатори за всією історією, може витрачати 200 мілісекунд процесорного часу на один цикл. Це реальна затримка, якою ви можете безкоштовно керувати. Профілюйте цикл, перш ніж шукати швидший сервер.

Під час вибору хоста важливі географічне розташування, стабільна мережа та достатній обсяг пам’яті, щоб OOM killer ніколи не міг втрутитися. Станом на July 2026 бот Python з однією стратегією та кількома сотнями символів у пам’яті без проблем працює з 2 GB RAM і 2 vCPU. Додайте пам’ять, якщо зберігаєте історію тиків у локальній базі даних.

Короткий контрольний список перед запуском у production

  1. systemctl is-enabled tradingbot виводить enabled, а сервіс переживає sudo reboot.
  2. chronyc tracking повідомляє, що зсув системного часу становить менше кількох мілісекунд.
  3. API key має дозвіл на торгівлю, але не має дозволу на виведення коштів. Якщо біржа підтримує список дозволених IP-адрес, він налаштований.
  4. Після завершення процесу за допомогою sudo systemctl kill -s SIGKILL tradingbot він запускається знову протягом RestartSec.
  5. Монітор heartbeat надсилає сповіщення протягом одного інтервалу, якщо навмисно зупинити бота.
  6. Розмір log-файлів обмежений, а у файловій системі root залишається вільний простір у df -h.

Протягом тижня запускайте все в sandbox біржі або в paper mode, перш ніж використовувати реальні кошти. Кожен наведений вище пункт протягом цього тижня щонайменше один раз дасть збій. У цьому і полягає мета тижневого тестування.

FAQ

Чи потрібен торговому боту сервер із низькою затримкою або bare metal?

Лише якщо ви змагаєтеся за швидкість виконання з іншими автоматизованими учасниками на тому самому майданчику. Зазвичай це означає colocation, а не універсальний VPS. Для роздрібного бота час повного циклу здебільшого визначається географічною відстанню та обробкою на стороні брокера. Тому виберіть сервер поблизу кінцевої точки API та виміряйте показники за допомогою curl і mtr, перш ніж платити за щось швидше.

Скільки RAM і CPU потрібно торговому боту?

Більшість ботів з однією стратегією залежать від мережі та простоюють між подіями. Станом на July 2026, 2 vCPU і 2 GB RAM достатньо для Python-бота, який відстежує кілька сотень інструментів. Пам’ять стає обмеженням, якщо ви зберігаєте історію тикових даних у процесі або запускаєте локальну базу даних. Тому перевіряйте free -h і журнал на наявність повідомлень про завершення через OOM, а не робіть припущення.

Чому мій API біржі відхиляє запити з помилкою мітки часу?

Годинник сервера змістився за межі вікна підпису біржі, зазвичай на кілька секунд. Встановіть chrony та переконайтеся, що chronyc tracking показує невелике зміщення System time і синхронізований статус leap. Налаштуйте машину на UTC, щоб перехід на літній час не змінював цей час. Заміна API key не усуває проблему з годинником.

Як запобігти непомітному завершенню роботи бота вночі?

Запустіть його під керуванням systemd із Restart=always і StartLimitIntervalSec=0, щоб у разі циклу збоїв він продовжував повторні спроби, а не припиняв роботу назавжди. Потім додайте heartbeat, який бот надсилає після завершення кожного успішного циклу. Перезапуск обробляє випадок завершення процесу. Heartbeat виявляє випадок, коли процес працює, але завис.

Чи можна запускати бота та систему моніторингу на одному VPS?

Можна, але в день, коли це матиме значення, система моніторингу надасть хибну картину, оскільки збій, який зупинить бота, одночасно зупинить і моніторинг. Розмістіть систему сповіщень на окремій машині, бажано в іншого провайдера або в іншому регіоні. Сервер бота використовуйте лише для бота та його журналів.

#trading#bots#vps#uptime#systemd#monitoring