VPS para bot de trading: o que realmente importa
Veja o que um bot de trading exige de um VPS: reinicio com systemd, relogio correto, chaves API protegidas, heartbeats e limites reais de latencia.
O que um bot de trading precisa de um VPS
Um VPS para bots de trading é avaliado por quatro aspetos: o processo volta a arrancar depois de terminar, o relógio está certo, as chaves da API (application programming interface) estão protegidas contra roubo e é detetada uma paragem. Para um bot de retalho, a velocidade bruta fica muito abaixo desses fatores, porque a parte mais lenta do percurso da ordem é o seu broker e a distância até ele, não o host que executa o seu Python.
Este é um guia de engenharia. Nada do que está aqui constitui aconselhamento financeiro e nenhuma estratégia é discutida.
Disciplina de reinício é disponibilidade, não um número numa página de vendas
Os compromissos de disponibilidade anunciados variam. A AWS especifica pelo menos 99.5 por cento para uma única instância EC2 e 99.99 por cento para implementações elegíveis em várias zonas de disponibilidade. Esses compromissos abrangem a disponibilidade da infraestrutura, não a saúde do seu bot. Um bot pode parar devido a uma exceção não tratada, a um websocket que nunca volta a ligar ou ao OOM (out of memory) killer, enquanto o servidor permanece disponível durante todo o tempo. Portanto, a pergunta útil é o que acontece nos dez segundos depois de o processo terminar.
Execute o bot como um serviço systemd e deixe o sistema init gerir o reinício. Um ficheiro de unidade faz isso.
[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 é a linha que muitas pessoas ignoram. As predefinições do systemd permitem 5 arranques em 10 segundos, incluindo o arranque inicial e os arranques manuais; a configuração do gestor pode substituir essas predefinições. Ao atingir o limite, o systemd para de tentar reiniciar automaticamente, mas a unidade pode ser iniciada manualmente ou por um timer ou socket depois de terminado o intervalo. Defini-lo como 0 desativa o limite de frequência, por isso um bot preso num ciclo de falhas continua a tentar em vez de ficar parado. RestartSec=10 impede que esse ciclo sobrecarregue a exchange com novas ligações.
Verifique o ficheiro antes de confiar nele e depois inicie o serviço:
sudo systemd-analyze verify /etc/systemd/system/tradingbot.service
sudo systemctl daemon-reload
sudo systemctl enable --now tradingbot
systemctl status tradingbotenable é a parte que garante a persistência depois de um reboot, e as atualizações do kernel implicam reboots. Para saber se o bot tem parado silenciosamente, peça ao systemd o contador de reinícios:
systemctl show tradingbot -p NRestarts
journalctl -u tradingbot --since "24 hours ago" | tail -50NRestarts=0 conta os trabalhos de reinício automático desde a última reposição do contador; não prova que a semana tenha sido saudável ou sem falhas. Reinícios manuais e systemctl reset-failed repõem o contador, e um bot bloqueado pode continuar a apresentar zero. NRestarts=812 conta 812 trabalhos de reinício, não reconexões bem-sucedidas à exchange nem trades, e não indica quando ocorreram. Consulte o journal para verificar os horários e as causas, incluindo falhas ocorridas antes de o bot estabelecer ligação. A estrutura completa do ficheiro de unidade, incluindo timers para trabalhos agendados como um relatório diário, é apresentada em executar um programa como um serviço systemd.
Defina o relógio como UTC e confirme que está sincronizado
As APIs de exchange usam marcas temporais para validar pedidos assinados; a Binance Spot usa por predefinição uma janela de receção de 5 segundos e rejeita marcas temporais que estejam pelo menos 1 segundo adiantadas em relação à hora do servidor. Um relógio com desvio produz erros que parecem falhas de autenticação, por isso é possível passar horas a substituir chaves antes de verificar a hora. Nas APIs ao estilo da Binance, a mensagem é literal: Timestamp for this request was 1000ms ahead of the server's time.
Defina o servidor para UTC. Os fusos horários locais introduzem alterações de hora de verão nas horas apresentadas; as marcas temporais Unix usadas pelas APIs não mudam quando o fuso horário apresentado é alterado.
sudo timedatectl set-timezone UTC
timedatectlO Ubuntu usa por predefinição chrony a partir da versão 25.10; as instalações mais antigas podem usar systemd-timesyncd, um cliente SNTP (simple network time protocol). systemd-timesyncd ajusta o relógio, mas não consegue consultar vários servidores em simultâneo para detetar uma fonte de hora incorreta. Em vez disso, use chrony:
sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony
chronyc tracking
chronyc sources -vA linha a consultar em chronyc tracking é System time, por exemplo System time : 0.000031415 seconds fast of NTP time. Um valor pequeno indica que falta aplicar uma pequena correção ao relógio NTP do chrony; verifique também a sincronização, Root delay e Root dispersion antes de avaliar a precisão. Se apresentar Leap status : Not synchronised, o chrony não está sincronizado, mesmo que os servidores tenham respondido; as medições podem ser rejeitadas por serem demasiado imprecisas. Aguarde um minuto e verifique novamente antes de alterar as regras da firewall.
Mantenha as chaves de API fora dos locais que copia
Uma chave de exchange exposta é pior do que uma chave SSH exposta, porque a permissão de levantamento transforma-a imediatamente em dinheiro. Dois hábitos cobrem a maior parte do risco.
Primeiro, nunca conceda permissão de levantamento a uma chave de bot. Quando a exchange permitir, associe a chave ao endereço IP do servidor. Este é o único controlo que torna uma chave roubada praticamente inútil.
Segundo, mantenha o segredo fora do diretório do código. Tudo o que estiver dentro de /opt/tradingbot acabará mais cedo ou mais tarde num repositório git ou num arquivo de backup. Coloque-o num ficheiro pertencente a root que o systemd leia:
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.envO ficheiro contém linhas simples de KEY=value, sem aspas e sem export. O modo 640 dá ao proprietário root acesso de leitura e escrita e aos membros do grupo bot acesso de leitura, sem permissões para outros utilizadores. Verifique com sudo -u bot cat /etc/tradingbot/api.env e depois com um utilizador sem privilégios que não pertença ao grupo bot; nesse caso, o acesso tem de falhar com Permission denied.
O bot não deve ser executado como root nem como o utilizador com que inicia sessão. Crie uma conta de sistema com uma shell nologin e /var/lib/tradingbot como diretório pessoal antes de iniciar o serviço ou criar ficheiros pertencentes ao grupo bot:
sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/tradingbot --create-home botA explicação de cada uma dessas flags e do alcance efetivo de ProtectSystem=strict está em executar serviços como um utilizador sem privilégios. O resto da configuração base do servidor, incluindo chaves SSH e uma firewall, deve ser feito em os primeiros dez minutos num VPS novo.
Descubra que está inativo antes do seu broker
systemctl status indica que o processo está em execução. Isso não significa que o bot esteja a fazer alguma coisa. Um processo preso num ciclo de novas tentativas contra um websocket indisponível passa pelas verificações do processo na unidade acima.
Use um heartbeat. O Uptime Kuma tem monitores push: espera que o seu bot chame um URL num intervalo definido e emite um alerta quando essas chamadas deixam de chegar. Coloque a chamada no fim do loop principal, depois da parte que comprova que o bot está ativo, como uma leitura bem-sucedida de dados de mercado.
curl -fsS "http://monitor.example.com:3001/api/push/YOUR_TOKEN?status=up&msg=loop_ok"Defina o intervalo do monitor para aproximadamente o dobro do tempo do loop, para que pequenas variações normais não gerem alertas. Execute o monitor num servidor diferente do bot, porque um monitor que falhe juntamente com o serviço monitorizado não comunica nada. A configuração está descrita em monitorização de estado self-hosted com Uptime Kuma.
Adicione também um alerta de disco. Um bot que escreve logs detalhados pode encher o sistema de ficheiros root em poucas semanas. Um disco cheio impede a escrita na base de dados, mas não a chamada de rede, pelo que os sintomas podem ser estranhos. journalctl --vacuum-time=14d e uma linha SystemMaxUse= em /etc/systemd/journald.conf mantêm o journal dentro de limites.
A parte honesta: a latência depende sobretudo de fatores externos ao host
É aqui que o mercado de VPS para trading deixa de ser técnico. As páginas de marketing apresentam valores inferiores a 1 milissegundo e sugerem que o host é o que separa o utilizador de uma execução. Para quase todos os bots de retalho, não é.
A sua ordem percorre a Internet pública desde o bot até ao endpoint da exchange ou do broker. Esse percurso é determinado sobretudo pela distância física e pelo peering entre o seu fornecedor e o fornecedor do endpoint. Depois, os próprios sistemas do broker acrescentam a fila, as verificações de risco e os limites de pedidos.
Faça medições em vez de adivinhar. curl apresenta os tempos de ligação e do primeiro byte para um endpoint real:
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.comExecute esse comando num servidor candidato antes de o contratar. Se connect for 0.180 segundos, esse valor inclui a resolução DNS e a ligação TCP; não determina em que continente o servidor está. Se connect for 0.004 segundos e ttfb for 0.140 segundos, a diferença inclui a configuração TLS, a transmissão do pedido, os atrasos de rede e o processamento no servidor. Mudar de host pode afetar alguns desses componentes, por isso compare medições feitas a partir das localizações candidatas.
Quando é que o host importa? Quando está numa instalação colocada no mesmo local do venue, ou ligada a ele por uma ligação direta, e compete pela posição na fila. Esse é um negócio diferente, com um orçamento diferente. Também importa quando o seu próprio código é o estrangulamento: um bot que recalcula indicadores sobre todo o histórico a cada tick pode consumir 200 milissegundos de CPU por ciclo. Essa é uma latência real que pode controlar sem custos. Analise o ciclo antes de procurar um servidor mais rápido.
No host que escolher, o que importa é a localização geográfica, uma rede estável e memória suficiente para que o OOM killer nunca tenha de intervir. Adicione memória se mantiver o histórico de ticks numa base de dados local.
Uma breve lista de verificação antes da entrada em produção
systemctl is-enabled tradingbotapresentaenabled, e o serviço volta a arrancar depois desudo reboot.chronyc trackingindica sincronização, um desvio do relógio do sistema inferior a alguns milissegundos e um atraso e uma dispersão de root dentro do orçamento de temporização.- A chave da API tem permissão para negociar, não tem permissão para levantamentos e tem uma lista de permissões de IP, se a exchange disponibilizar essa opção.
- Terminar o processo com
sudo systemctl kill -s SIGKILL tradingbotfaz com que volte a arrancar depois do atraso deRestartSece do tempo de arranque. - O monitor de heartbeat envia-lhe um alerta depois do intervalo configurado e tenta novamente quando para o bot deliberadamente.
- Os logs têm limites definidos e o sistema de ficheiros root tem espaço disponível em
df -h.
Execute tudo no sandbox da exchange ou em modo de simulação durante uma semana antes de usar fundos reais. Todos os itens acima falham pelo menos uma vez nessa semana. Esse é o objetivo da semana.
FAQ
Um bot de trading precisa de um servidor de baixa latência ou bare metal?
Apenas se estiver a competir com outros participantes automatizados pela velocidade de execução no mesmo venue, o que normalmente significa colocation em vez de um VPS de uso geral. Para um bot de retalho, o tempo de ida e volta é dominado pela geografia e pelo processamento do próprio broker. Por isso, escolha um servidor próximo do endpoint da API e faça medições com curl e mtr antes de pagar por algo mais rápido.
De quanta RAM e CPU precisa um bot de trading?
A maioria dos bots de estratégia única é limitada pela rede e fica inativa entre eventos. A memória torna-se o fator limitante quando mantém o histórico de ticks em memória ou executa uma base de dados local. Por isso, monitorize free -h e o journal para procurar mensagens de OOM kill em vez de fazer estimativas.
Por que motivo a API da exchange rejeita pedidos com um erro de timestamp?
O timestamp do pedido está fora da janela aceite pela exchange. Tanto o desfasamento do relógio como os atrasos dos pedidos são relevantes. Instale o chrony, confirme que chronyc tracking mostra um desfasamento System time pequeno e um estado de leap synchronised, e verifique também o root delay e a dispersão. Definir a máquina para UTC mantém as horas apresentadas consistentes, mas não corrige o desfasamento do relógio. Rodar a API key não corrige um problema do relógio.
Como posso impedir que o meu bot pare durante a noite sem eu saber?
Execute-o com systemd usando Restart=always e StartLimitIntervalSec=0, para que um ciclo de falhas continue a tentar reiniciar em vez de atingir o start rate limit. Depois, adicione um heartbeat que o bot envie no final de cada ciclo concluído com sucesso. O restart trata do processo. O heartbeat deteta o caso em que o processo está ativo, mas bloqueado.
Posso executar o bot e o meu sistema de monitorização no mesmo VPS?
Pode, mas o sistema de monitorização irá fornecer informação incorreta precisamente no dia em que for necessário, porque uma falha que interrompa o bot também interromperá o monitor. Mantenha os alertas numa máquina separada, idealmente com outro provider ou noutra região, e use o servidor do bot apenas para o bot e os respetivos logs.