VPS для торгового бота: что действительно важно
Узнайте, что нужно торговому боту от VPS: перезапуск через systemd, точные часы, защита API-ключей, heartbeat и реальные ограничения задержки.
Что требуется торговому боту от VPS
VPS для торговых ботов оценивают по четырем критериям: запускается ли процесс снова после сбоя, правильно ли установлены часы, надежно ли защищены ключи API (интерфейс прикладного программирования) от кражи и узнаете ли вы об остановке бота. Сырая производительность для розничного бота имеет гораздо меньшее значение. Медленная часть пути ордера обычно связана с брокером и расстоянием до него, а не с хостом, на котором работает Python.
Это руководство посвящено инженерным вопросам. Здесь нет финансовых рекомендаций и не рассматриваются торговые стратегии.
Доступность — это дисциплина перезапуска, а не число на странице продаж
Каждый хост в мире заявляет доступность 99.9 процента. Это значение описывает гипервизор, а не вашего бота. Бот завершается из-за необработанного исключения, websocket, который не выполняет повторное подключение, или средства OOM (out of memory), а сервер всё это время продолжает работать. Поэтому полезно выяснить, что происходит в течение десяти секунд после завершения процесса.
Запустите бота как службу systemd и передайте init-системе управление перезапуском. Файл модуля делает это в шести строках.
[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.targetStartLimitIntervalSec=0 — это строка, которую часто пропускают. По умолчанию systemd прекращает попытки после 5 перезапусков за 10 секунд и навсегда оставляет модуль в состоянии 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 tradingbotenable — это часть настройки, которая сохраняется после перезагрузки, а обновления ядра требуют перезагрузки. Чтобы проверить, не завершался ли бот без уведомлений, запросите у systemd счётчик перезапусков:
systemctl show tradingbot -p NRestarts
journalctl -u tradingbot --since "24 hours ago" | tail -50NRestarts=0 через неделю означает, что бот работает нормально. NRestarts=812 означает, что вы торговали с использованием процесса, который всю ночь выполнял повторные подключения. Полная структура файла модуля, включая таймеры для запланированных задач, например ежедневного отчёта, описана в разделе запуск программы как службы 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 (simple network time protocol). Он подходит для журналов, но недостаточно точен для задач, где необходимо удерживать расхождение в пределах нескольких миллисекунд, поскольку опрашивает один сервер и не выполняет непрерывную коррекцию часов. Вместо него используйте 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-ключи в каталогах, которые копируются
Утечка ключа биржи опаснее утечки ключа SSH, поскольку разрешение на вывод средств сразу позволяет превратить его в деньги. Большую часть риска снижают два правила.
Во-первых, никогда не выдавайте ключу бота разрешение на вывод средств. Если биржа поддерживает такую возможность, привяжите ключ к IP-адресу сервера. Это единственная мера, которая делает украденный ключ практически бесполезным.
Во-вторых, храните секрет не в каталоге с кодом. Всё, что находится в /opt/tradingbot, рано или поздно попадёт в git-репозиторий или архив резервной копии. Поместите секрет в файл, владельцем которого является 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 позволяют читать файл пользователю службы, но запрещают доступ всем остальным. Проверьте это с помощью sudo -u bot cat /etc/tradingbot/api.env, а затем от имени любого другого пользователя. Во втором случае команда должна завершиться ошибкой Permission denied.
Сам бот не должен работать от имени root или вашей учётной записи. Создайте системную учётную запись без оболочки и домашнего каталога, в который можно войти:
sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/tradingbot --create-home botОбоснование каждого из этих флагов и описание того, насколько далеко действительно распространяется действие ProtectSystem=strict, приведены в разделе запуск служб от непривилегированного пользователя. Остальные базовые настройки сервера — ключи SSH и firewall — описаны в разделе первые десять минут на новом VPS.
Узнайте о сбое раньше брокера
systemctl status сообщает, что процесс запущен. Это не означает, что бот выполняет работу. Процесс, застрявший в цикле повторных попыток подключения к недоступному websocket, проходит все проверки, которые может выполнить systemd.
Используйте heartbeat. В 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 миллисекунд CPU на один цикл. Это реальная задержка, которую можно бесплатно устранить. Сначала профилируйте цикл, а затем ищите более быстрый сервер.
При выборе хоста важны географическое расположение, стабильная сеть и достаточный объем памяти, чтобы OOM killer никогда не мог остановить процессы. По состоянию на July 2026 один Python-бот с одной стратегией и несколькими сотнями символов в памяти стабильно работает с 2 GB RAM и 2 vCPU. Увеличьте объем памяти, если храните историю тиков в локальной базе данных.
Краткий контрольный список перед запуском в рабочем режиме
systemctl is-enabled tradingbotвыводитenabled, а служба продолжает работать послеsudo reboot.chronyc trackingсообщает, что расхождение системного времени составляет менее нескольких миллисекунд.- API-ключ имеет разрешение на торговлю, но не имеет разрешения на вывод средств. Если биржа поддерживает список разрешённых IP-адресов, он настроен.
- После завершения процесса с помощью
sudo systemctl kill -s SIGKILL tradingbotон снова запускается в течениеRestartSec. - Монитор heartbeat отправляет оповещение не позднее одного интервала после преднамеренной остановки бота.
- Размер журналов ограничен, а в корневой файловой системе достаточно свободного места в
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, а не полагайтесь на предположения.
Почему мой exchange API отклоняет запросы с ошибкой временной метки?
Системные часы сервера ушли за пределы временного окна, в котором exchange принимает подпись запроса. Обычно отклонение составляет несколько секунд. Установите chrony и убедитесь, что chronyc tracking показывает небольшое смещение System time и синхронизированный статус leap. Настройте машину на UTC, чтобы переход на летнее время не изменил системное время. Замена API key не устраняет проблему с часами.
Как сделать так, чтобы бот не завершался ночью незаметно для меня?
Запустите его под управлением systemd с параметрами Restart=always и StartLimitIntervalSec=0. Тогда systemd будет повторять попытки после сбоя, вместо того чтобы окончательно остановить бот при цикле сбоев. Затем добавьте heartbeat, который бот отправляет после завершения каждого успешного цикла. Перезапуск обрабатывает завершение процесса. heartbeat выявляет ситуацию, когда процесс работает, но завис.
Можно ли запускать бот и систему мониторинга на одном VPS?
Можно, но в тот день, когда это будет важно, система мониторинга введет вас в заблуждение. Причина в том, что сбой, из-за которого остановится бот, одновременно остановит и мониторинг. Разместите систему оповещений на отдельной машине, желательно у другого провайдера или в другом регионе. Сервер бота используйте только для бота и его журналов.