SSD Nodes Learn 8GB RAM — $66/năm
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-01

VPS cho trading bot: cần quan tâm điều gì?

Trading bot cần systemd tự restart, clock đúng, API key an toàn và heartbeat cảnh báo. Hiểu giới hạn latency thực tế thay vì tin uptime 99.9% trên trang bán VPS.

VPS cần gì cho trading bot

Một VPS chạy trading bot được đánh giá trên 4 yếu tố: process có tự chạy lại sau khi dừng không, đồng hồ hệ thống có chính xác không, các API key (application programming interface) có khó bị đánh cắp không, và bạn có biết khi bot dừng không. Tốc độ xử lý thuần túy đứng khá thấp trong danh sách này đối với bot bán lẻ, vì phần chậm trong đường đi của order thường nằm ở broker và khoảng cách đến broker, không phải ở host chạy Python của bạn.

Đây là hướng dẫn kỹ thuật. Nội dung này không phải tư vấn tài chính và không đề cập đến chiến lược.

Uptime là kỷ luật khởi động lại, không phải một con số trên trang bán hàng

Mọi host trên thế giới đều quảng cáo uptime 99.9 phần trăm. Con số đó mô tả hypervisor, không phải bot của bạn. Bot có thể dừng do exception không được xử lý, websocket không bao giờ reconnect hoặc OOM (out of memory) killer, trong khi server vẫn hoạt động suốt thời gian đó. Vì vậy, câu hỏi hữu ích là điều gì xảy ra trong 10 giây sau khi process của bạn thoát.

Chạy bot dưới dạng systemd service và để init system quản lý việc restart. Một unit file thực hiện việc này chỉ trong 6 dòng.

[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 là dòng mà nhiều người bỏ sót. Theo mặc định, systemd sẽ từ bỏ sau 5 lần restart trong 10 giây và để unit ở trạng thái failed vĩnh viễn. Đây chính xác là điều bạn không muốn xảy ra lúc 03:00. Đặt giá trị này thành 0 sẽ tắt giới hạn tần suất, để bot bị crash-loop tiếp tục thử lại thay vì im lặng dừng hoạt động. RestartSec=10 ngăn vòng lặp đó liên tục gửi reconnect đến sàn giao dịch.

Kiểm tra file trước khi tin cậy, rồi start service:

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

enable là phần giúp service vẫn hoạt động sau khi reboot, mà kernel update đồng nghĩa với reboot. Để xem bot có âm thầm dừng hay không, yêu cầu systemd hiển thị bộ đếm restart:

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

NRestarts=0 sau một tuần cho thấy bot hoạt động ổn định. NRestarts=812 nghĩa là bạn đã giao dịch trên một process phải reconnect suốt đêm. Phân tích đầy đủ cấu trúc unit file, bao gồm timer cho các job được lập lịch như báo cáo hằng ngày, được trình bày trong chạy một chương trình dưới dạng systemd service.

Đặt đồng hồ theo UTC và xác nhận đồng bộ

Exchange API ký request bằng timestamp và từ chối mọi request nằm ngoài một khoảng thời gian, thường là 5 giây hoặc ít hơn. Đồng hồ bị lệch tạo ra các lỗi trông giống lỗi xác thực, nên nhiều người xoay vòng key trong nhiều giờ trước khi kiểm tra thời gian. Với các API kiểu Binance, thông báo này có nội dung đúng như sau: Timestamp for this request was 1000ms ahead of the server's time.

Đặt server theo UTC. Múi giờ cục bộ có thể tạo ra bước nhảy do giờ mùa hè ngay giữa phiên giao dịch.

sudo timedatectl set-timezone UTC
timedatectl

Ubuntu tích hợp systemd-timesyncd, một client SNTP (simple network time protocol). Công cụ này phù hợp cho log nhưng không đủ tin cậy cho các tác vụ phải duy trì độ lệch trong vài mili giây, vì nó chỉ polling một server và không liên tục hiệu chỉnh đồng hồ. Thay vào đó, dùng chrony:

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

Dòng cần đọc trong chronyc trackingSystem time, ví dụ System time : 0.000031415 seconds fast of NTP time. Giá trị dưới vài mili giây là bình thường. Nếu hiển thị Leap status : Not synchronised, chrony chưa kết nối được tới server, thường là vì outbound UDP 123 bị chặn. Chờ một phút rồi kiểm tra lại trước khi thay đổi firewall rules.

Giữ API key ngoài những nơi bạn sao chép

Một exchange key bị lộ nguy hiểm hơn một SSH key bị lộ, vì quyền rút tiền có thể lập tức biến nó thành tiền. Hai thói quen giúp giảm phần lớn rủi ro.

Trước tiên, không bao giờ cấp quyền rút tiền cho bot key. Nếu exchange hỗ trợ, hãy giới hạn key cho địa chỉ IP của server. Đây là biện pháp kiểm soát duy nhất khiến key bị đánh cắp gần như vô dụng.

Tiếp theo, giữ secret bên ngoài thư mục code. Mọi thứ nằm trong /opt/tradingbot sớm muộn cũng sẽ xuất hiện trong git repository hoặc backup archive. Đặt secret trong một file do root sở hữu để chỉ systemd đọc:

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

File này chứa các dòng KEY=value thuần, không có dấu ngoặc kép và không có export. Mode 640 với group bot cho phép service user đọc file, còn mọi user khác thì không. Xác minh bằng sudo -u bot cat /etc/tradingbot/api.env, sau đó thử bằng một user khác; thao tác này phải thất bại với Permission denied.

Bot không được chạy dưới quyền root hoặc user dùng để đăng nhập. Hãy tạo một system account không có shell và không có home directory để đăng nhập:

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

Phần giải thích cho từng flag và mức độ bảo vệ thực tế của ProtectSystem=strict có trong chạy service dưới user không đặc quyền. Các thiết lập nền tảng còn lại của server, gồm SSH key và firewall, có trong 10 phút đầu tiên trên một VPS mới.

Phát hiện bot dừng trước khi broker phát hiện

systemctl status cho biết process đang chạy. Nó không cho biết bot có đang làm việc hay không. Một process bị kẹt trong vòng lặp retry tới websocket đã chết vẫn vượt qua mọi kiểm tra mà systemd có thể thực hiện.

Thay vào đó, hãy dùng heartbeat. Uptime Kuma có push monitor: nó yêu cầu bot gọi một URL theo lịch và gửi cảnh báo khi không còn nhận được lệnh gọi. Đặt lệnh gọi ở cuối vòng lặp chính, sau phần xác nhận bot đang hoạt động, chẳng hạn như đọc dữ liệu thị trường thành công.

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

Đặt khoảng thời gian của monitor gần bằng 2 lần thời gian chạy vòng lặp để jitter thông thường không tạo cảnh báo giả. Chạy monitor trên server khác với bot, vì monitor dừng cùng đối tượng mà nó theo dõi thì sẽ không báo cáo được gì. Xem hướng dẫn thiết lập tại giám sát trạng thái tự quản lý bằng Uptime Kuma.

Đồng thời thêm cảnh báo dung lượng đĩa. Bot ghi log chi tiết sẽ làm đầy root filesystem trong vài tuần. Khi đĩa đầy, thao tác ghi database sẽ dừng, còn lệnh gọi mạng vẫn hoạt động, nên triệu chứng sẽ khó xác định. journalctl --vacuum-time=14d và một dòng SystemMaxUse= trong /etc/systemd/journald.conf sẽ giới hạn kích thước journal.

Phần cần nói thẳng: độ trễ phần lớn không nằm ở máy chủ của bạn

Đây là lúc thị trường VPS cho giao dịch không còn mang tính kỹ thuật. Các trang marketing đưa ra con số dưới 1 mili giây và ngụ ý rằng máy chủ là yếu tố ngăn bạn nhận được khớp lệnh. Với gần như mọi bot bán lẻ, điều đó không đúng.

Lệnh của bạn đi từ bot đến endpoint của sàn hoặc broker qua Internet công cộng. Đường truyền đó chủ yếu bị chi phối bởi khoảng cách vật lý và kết nối peering giữa nhà cung cấp của bạn với nhà cung cấp của họ. Một server ở Frankfurt kết nối đến endpoint ở Tokyo sẽ có thời gian khứ hồi khoảng 250 mili giây, bất kể CPU nhanh đến đâu. Sau đó, hệ thống của broker còn thêm thời gian xếp hàng, kiểm tra rủi ro và giới hạn tốc độ. Với tài khoản bán lẻ, các khoảng thời gian này thường được tính bằng hàng chục hoặc hàng trăm mili giây.

Hãy đo thay vì phỏng đoán. curl báo cáo thời gian kết nối và thời gian nhận byte đầu tiên từ một endpoint thực:

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

Chạy lệnh đó trên server ứng viên trước khi quyết định. Nếu connect là 0.180 giây, bạn đang ở sai châu lục và cần khắc phục điều đó. Nếu connect là 0.004 giây và ttfb là 0.140 giây, phần độ trễ còn lại là thời gian xử lý của broker. Đổi host sẽ không làm giảm được phần này.

Vậy khi nào host có ảnh hưởng? Khi bạn colocate hoặc cross-connect với venue và cạnh tranh về vị trí trong hàng đợi. Đây là một hoạt động kinh doanh khác với ngân sách khác. Host cũng quan trọng khi chính code của bạn là nút thắt. Một bot tính toán lại indicator trên toàn bộ lịch sử ở mỗi tick có thể dùng 200 mili giây CPU cho mỗi vòng lặp. Đây là độ trễ thực tế mà bạn có thể kiểm soát miễn phí. Hãy profile vòng lặp trước khi tìm server nhanh hơn.

Điều thực sự quan trọng khi chọn host là vị trí địa lý, mạng ổn định và đủ bộ nhớ để OOM killer không bao giờ có cơ hội can thiệp. Tính đến July 2026, một bot Python chạy một chiến lược với vài trăm symbol trong bộ nhớ hoạt động ổn định với 2 GB RAM và 2 vCPU. Hãy tăng bộ nhớ nếu bạn lưu lịch sử tick trong cơ sở dữ liệu cục bộ.

Danh sách kiểm tra ngắn trước khi chạy production

  1. systemctl is-enabled tradingbot in ra enabled và service vẫn hoạt động sau sudo reboot.
  2. chronyc tracking báo độ lệch thời gian hệ thống dưới vài mili giây.
  3. API key có quyền trading, không có quyền withdrawal và có IP allowlist nếu sàn hỗ trợ.
  4. Dùng sudo systemctl kill -s SIGKILL tradingbot để dừng process thì process tự khởi động lại trong vòng RestartSec.
  5. Heartbeat monitor gửi cảnh báo cho bạn trong vòng một interval khi bạn cố ý dừng bot.
  6. Log có giới hạn dung lượng và filesystem root còn đủ dung lượng trống trong df -h.

Chạy toàn bộ hệ thống trong sandbox của sàn hoặc ở paper mode trong 1 tuần trước khi dùng tiền thật. Mỗi mục trên sẽ lỗi ít nhất 1 lần trong tuần đó. Đó chính là mục đích của việc chạy thử 1 tuần.

FAQ

Bot giao dịch có cần server có độ trễ thấp hoặc bare metal không?

Chỉ khi bạn cạnh tranh về tốc độ thực thi với các bên tự động khác tại cùng venue. Trường hợp đó thường cần colocation thay vì VPS đa dụng. Với bot bán lẻ, thời gian round trip chủ yếu phụ thuộc vào vị trí địa lý và quá trình xử lý của broker. Vì vậy, hãy chọn server gần API endpoint và đo bằng curlmtr trước khi trả tiền cho phần cứng nhanh hơn.

Bot giao dịch cần bao nhiêu RAM và CPU?

Hầu hết bot chạy một strategy chỉ bị giới hạn bởi network và ở trạng thái idle giữa các event. Tính đến tháng 7 năm 2026, 2 vCPU và 2 GB RAM đủ để chạy một bot Python theo dõi vài trăm instrument. Memory trở thành giới hạn khi bạn giữ lịch sử tick trong process hoặc chạy database cục bộ. Vì vậy, hãy theo dõi free -h và journal để tìm các thông báo OOM kill thay vì phỏng đoán.

Vì sao exchange API từ chối request với lỗi timestamp?

Clock của server đã lệch khỏi signing window của exchange, thường là vài giây. Hãy cài chrony, xác nhận chronyc tracking hiển thị offset System time nhỏ và trạng thái leap đã được đồng bộ, đồng thời đặt machine dùng UTC để thay đổi daylight saving không bao giờ làm lệch thời gian. Xoay vòng API key không khắc phục được vấn đề về clock.

Làm cách nào để bot không dừng qua đêm mà tôi không biết?

Hãy chạy bot dưới systemd với Restart=alwaysStartLimitIntervalSec=0 để crash loop tiếp tục retry thay vì dừng vĩnh viễn. Sau đó, thêm heartbeat mà bot gửi vào cuối mỗi loop thành công. Cơ chế restart xử lý trường hợp process bị crash. Heartbeat phát hiện trường hợp process vẫn hoạt động nhưng bị stuck.

Tôi có thể chạy bot và hệ thống monitoring trên cùng một VPS không?

Bạn có thể, nhưng monitoring sẽ báo sai đúng vào ngày bạn cần nó nhất. Nguyên nhân là outage làm bot dừng cũng sẽ làm monitor dừng theo. Hãy đặt hệ thống alerting trên một machine riêng, tốt nhất là dùng provider hoặc region khác, và chỉ dùng server của bot cho bot cùng các log của nó.

#trading#bots#vps#uptime#systemd#giám sát