SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Выбор VPS для торгового бота: технические требования

Узнайте, почему для торговых ботов важны не рекламные цифры аптайма, а настройка systemd, синхронизация времени через NTP и защита API ключей. Разбор реальных критериев выбора.

Требования к VPS для торгового бота

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

Это инженерное руководство. Данный текст не является финансовой консультацией, стратегии здесь не обсуждаются.

Uptime — это дисциплина перезапуска, а не цифра в рекламном буклете

Обязательства по uptime различаются. AWS гарантирует не менее 99.5 процентов для одного экземпляра EC2 и 99.99 процентов для соответствующих требованиям развертываний в нескольких зонах доступности. Эти обязательства покрывают доступность инфраструктуры, а не работоспособность вашего бота. Бот может завершиться из-за необработанного исключения, websocket, который не переподключается, или OOM (out of memory) killer, при этом сервер останется доступным. Поэтому полезный вопрос заключается в том, что происходит в течение десяти секунд после завершения вашего процесса.

Запускайте бота как systemd service и позвольте системе инициализации управлять перезапуском. Это делает 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 секунд, включая начальный и ручные запуски; конфигурация менеджера может переопределить эти значения. Достижение лимита останавливает попытки автоматического перезапуска, но юнит можно запустить вручную, по таймеру или через сокет после истечения интервала. Установка значения 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 не учитывает автоматические задачи перезапуска с момента последнего сброса счетчика; это не доказывает, что неделя прошла без сбоев или аварий. Ручные перезапуски и systemctl reset-failed сбрасывают счетчик, и зависший бот все равно может показывать ноль. NRestarts=812 насчитывает 812 задач перезапуска, а не успешных переподключений к бирже или сделок, и ничего не говорит о том, когда они произошли. Проверяйте журнал для уточнения времени и причины, включая сбои до того, как бот установит соединение. Полная структура unit-файла, включая таймеры для запланированных задач, таких как ежедневный отчет, описана в запуск программы как systemd service.

Установка системного времени в UTC и проверка синхронизации

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

Установите на сервере часовой пояс UTC. Локальные часовые пояса приводят к скачкам времени при переходе на летнее/зимнее время; Unix-метки, используемые API, не меняются при смене часового пояса отображения.

sudo timedatectl set-timezone UTC
timedatectl

В Ubuntu начиная с версии 25.10 по умолчанию используется chrony; в более старых дистрибутивах можно использовать systemd-timesyncd — клиент SNTP (Simple Network Time Protocol). systemd-timesyncd корректирует часы, но не умеет опрашивать несколько серверов одновременно для выявления некорректного источника времени. Вместо него используйте 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. Малое значение указывает на небольшую остаточную коррекцию часов NTP в chrony; перед оценкой точности проверьте синхронизацию с помощью Root delay и Root dispersion. Если отображается Leap status : Not synchronised, значит, chrony не синхронизирован, даже если серверы ответили; измерения могут быть отклонены как недостаточно точные. Подождите минуту и проверьте снова, прежде чем изменять правила межсетевого экрана.

Храните 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 предоставляет владельцу root права на чтение и запись, а участникам группы bot — права на чтение, при этом у остальных пользователей прав нет. Проверьте это с помощью sudo -u bot cat /etc/tradingbot/api.env, а затем выполните проверку от имени непривилегированного пользователя, не входящего в группу bot: доступ должен быть запрещен с ошибкой Permission denied.

Сам бот не должен работать от имени root или вашего личного пользователя. Создайте системную учетную запись с оболочкой nologin и /var/lib/tradingbot в качестве домашней директории перед запуском службы или созданием файлов, принадлежащих группе bot:

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

Обоснование каждого из этих флагов и подробности о том, насколько далеко заходит ProtectSystem=strict, описаны в запуске служб от имени непривилегированного пользователя. Остальные базовые настройки сервера, SSH-ключи и межсетевой экран описаны в первые десять минут на новом VPS.

Обнаружение сбоя до того, как его заметит брокер

systemctl status сообщает, что процесс запущен. Это не означает, что бот выполняет какие-либо действия. Процесс, застрявший в цикле повторных попыток подключения к неработающему websocket, проходит проверку состояния процесса, описанную выше.

Используйте 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 для трейдинга перестает быть чисто техническим. Маркетинговые страницы обещают задержки менее миллисекунды, намекая, что именно хост отделяет вас от успешной сделки. Для почти любого розничного торгового бота это не так.

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

Измеряйте задержки, а не гадайте. 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 секунды, это время включает DNS-разрешение и установку TCP-соединения; это не определяет, на каком континенте вы находитесь. Если connect составляет 0.004 секунды, а ttfb — 0.140 секунды, то разница включает установку TLS, передачу запроса, сетевые задержки и обработку на стороне сервера. Смена хоста может повлиять на некоторые из этих компонентов, поэтому сравнивайте измерения из разных потенциальных локаций.

Так когда же хост имеет значение? Когда вы размещаетесь в том же дата-центре (colocation) или имеете прямое соединение с площадкой и конкурируете за позицию в очереди — это другой бизнес с другим бюджетом. И когда узким местом является ваш собственный код: бот, который пересчитывает индикаторы по всей истории на каждом тике, может тратить 200 миллисекунд CPU на цикл. Это реальная задержка, которую вы можете устранить бесплатно. Профилируйте цикл перед тем, как искать более быстрый сервер.

Что действительно важно в выбранном хосте, так это география, стабильность сети и достаточный объем оперативной памяти, чтобы OOM killer никогда не вмешивался в работу. Добавьте памяти, если вы храните историю тиков в локальной базе данных.

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

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

Запустите всю систему в песочнице биржи или в режиме paper trading на одну неделю перед использованием реальных средств. Каждый из пунктов выше обязательно даст сбой хотя бы раз за эту неделю — в этом и заключается смысл тестового периода.

FAQ

Нужен ли торговому боту сервер с низкой задержкой или bare metal?

Только если вы конкурируете по скорости исполнения с другими автоматизированными участниками на той же площадке. Обычно это означает размещение в одном дата-центре (colocation), а не использование обычного VPS. Для розничного бота время кругового обращения (RTT) определяется географией и скоростью обработки запросов самим брокером. Выбирайте сервер, расположенный ближе к API-эндпоинту, и проводите замеры с помощью curl и mtr, прежде чем платить за более дорогое оборудование.

Сколько оперативной памяти и ресурсов процессора нужно торговому боту?

Большинство ботов, реализующих одну стратегию, ограничены скоростью сети и простаивают между событиями. Память становится критическим ресурсом, если вы храните историю тиков в процессе или используете локальную базу данных. Вместо догадок следите за free -h и системным журналом на предмет сообщений об OOM kill.

Почему API биржи отклоняет запросы с ошибкой временной метки?

Временная метка запроса выходит за пределы допустимого биржей окна. Значение имеют как рассинхронизация часов, так и задержки при передаче запроса. Установите chrony, убедитесь, что chronyc tracking показывает небольшое смещение System time и статус синхронизации leap, а также проверьте параметры root delay и dispersion. Установка системного времени в UTC обеспечивает единообразие отображения, но не исправляет дрейф часов. Смена API-ключа не решает проблему рассинхронизации времени.

Как предотвратить незаметную остановку бота в ночное время?

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

Можно ли запускать бота и систему мониторинга на одном VPS?

Можно, но мониторинг подведет вас в самый ответственный момент, так как сбой, который остановит бота, выведет из строя и монитор. Держите систему оповещений на отдельной машине, желательно у другого провайдера или в другом регионе, а сервер бота используйте только для самого бота и его логов.

Была ли эта статья полезной?