SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-07

راهنمای انتخاب VPS مناسب برای ربات‌های معامله‌گر

برای اجرای ربات معامله‌گر به جای سرعت خام، روی پایداری تمرکز کنید. یاد بگیرید چگونه با تنظیم systemd، دقت ساعت سیستم و مدیریت API keys، از توقف ناگهانی ربات جلوگیری کنید.

نیازهای یک ربات معامله‌گر از VPS

یک VPS برای ربات‌های معامله‌گر بر اساس چهار معیار ارزیابی می‌شود: آیا فرآیند پس از توقف به‌طور خودکار بازیابی می‌شود، آیا ساعت سیستم دقیق است، آیا سرقت کلیدهای API (رابط برنامه‌نویسی کاربردی) دشوار است، و آیا در صورت توقف ربات، از آن مطلع می‌شوید. سرعت خام در این فهرست برای یک ربات خرده‌فروشی در اولویت‌های پایین قرار دارد، زیرا بخش کند در مسیر سفارش شما، کارگزار و فاصله جغرافیایی تا آن است، نه میزبانی که کد Python شما را اجرا می‌کند.

این یک راهنمای مهندسی است. هیچ‌کدام از مطالب اینجا توصیه مالی نیست و هیچ استراتژی معاملاتی مورد بحث قرار نگرفته است.

آپ‌تایم یعنی نظم در راه‌اندازی مجدد، نه یک عدد در صفحه فروش

هر میزبان در دنیا ادعای آپ‌تایم 99.9 درصدی دارد. این رقم توصیف‌کننده هایپروایزر است، نه ربات شما. ربات ممکن است به دلیل یک استثنای مدیریت‌نشده، یک وب‌سوکت که هرگز دوباره متصل نمی‌شود، یا OOM (خروج از حافظه) کیلر از کار بیفتد، در حالی که سرور تمام مدت روشن باقی می‌ماند. بنابراین پرسش مفید این است که در ده ثانیه پس از خروج پردازش شما چه اتفاقی می‌افتد.

ربات را به عنوان یک سرویس 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 بخشی است که پس از reboot زنده می‌ماند و به‌روزرسانی‌های کرنل به معنای reboot هستند. برای اینکه ببینید آیا ربات در سکوت در حال مرگ بوده است، از systemd شمارنده راه‌اندازی مجدد را بخواهید:

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

NRestarts=0 پس از یک هفته نشان‌دهنده یک ربات سالم است. NRestarts=812 به این معناست که شما در حال معامله با پردازشی بوده‌اید که تمام شب در حال اتصال مجدد بوده است. کالبدشکافی کامل فایل unit، شامل تایمرها برای کارهای زمان‌بندی‌شده مانند گزارش روزانه، در اجرای یک برنامه به عنوان سرویس systemd پوشش داده شده است.

تنظیم ساعت روی UTC و اطمینان از همگام‌سازی آن

APIهای صرافی‌ها درخواست‌ها را با یک timestamp امضا می‌کنند و هر درخواستی که خارج از بازه زمانی مجاز (معمولاً 5 ثانیه یا کمتر) باشد را رد می‌کنند. انحراف ساعت باعث بروز خطاهایی می‌شود که شبیه به شکست در احراز هویت هستند؛ به همین دلیل کاربران ممکن است ساعت‌ها وقت خود را صرف چرخش کلیدها (key rotation) کنند، در حالی که مشکل اصلی زمان است. در APIهای مشابه Binance، پیام خطا دقیقاً به این صورت است: Timestamp for this request was 1000ms ahead of the server's time.

ساعت سرور را روی UTC تنظیم کنید. مناطق زمانی محلی (Local time zones) باعث تغییر ساعت در زمان شروع یا پایان Daylight Saving می‌شوند که ممکن است دقیقاً در میانه یک جلسه معاملاتی رخ دهد.

sudo timedatectl set-timezone UTC
timedatectl

اوبونتو به‌صورت پیش‌فرض از systemd-timesyncd استفاده می‌کند که یک کلاینت SNTP (پروتکل ساده زمان شبکه) است. این ابزار برای لاگ‌ها مناسب است، اما برای مواردی که نیاز به دقت در حد چند میلی‌ثانیه دارند ضعیف عمل می‌کند؛ زیرا تنها از یک سرور استعلام می‌گیرد و ساعت را به‌طور مداوم اصلاح (discipline) نمی‌کند. به‌جای آن از 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 در خروجی رخ می‌دهد. یک دقیقه صبر کنید و پیش از تغییر قوانین فایروال، دوباره وضعیت را بررسی کنید.

کلیدهای API را از مکان‌هایی که کپی می‌کنید دور نگه دارید

نشت یک کلید صرافی، بدتر از نشت یک کلید SSH است؛ زیرا دسترسی برداشت، آن را بلافاصله به پول نقد تبدیل می‌کند. دو عادت، بخش بزرگی از این ریسک را پوشش می‌دهند.

نخست، هرگز اجازه برداشت را به یک کلید ربات ندهید و در صورتی که صرافی پشتیبانی می‌کند، کلید را به آدرس IP سرور خود محدود کنید. این تنها کنترلی است که یک کلید سرقت‌شده را تقریباً بی‌فایده می‌کند.

دوم، secret را خارج از دایرکتوری کد نگه دارید. هر چیزی که داخل /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 یا به عنوان کاربر لاگین شما اجرا شود. یک حساب سیستمی بدون shell و بدون دایرکتوری home برای لاگین ایجاد کنید:

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

دلیل استفاده از هر یک از این فلگ‌ها و اینکه ProtectSystem=strict دقیقاً تا کجا پیش می‌رود، در اجرای سرویس‌ها به عنوان کاربر بدون دسترسی ویژه آمده است. مابقی تنظیمات پایه سرور، کلیدهای SSH و فایروال، در ده دقیقه اول روی یک VPS جدید توضیح داده شده‌اند.

پیش از آنکه کارگزار متوجه شود، از خرابی سرویس مطلع شوید

systemctl status نشان می‌دهد که پردازش در حال اجرا است، اما به این معنا نیست که ربات واقعاً کاری انجام می‌دهد. پردازشی که در یک حلقه تلاش مجدد (retry loop) روی یک websocket قطع‌شده گیر کرده باشد، تمام بررسی‌های systemd را با موفقیت پشت سر می‌گذارد.

به‌جای آن از یک heartbeat استفاده کنید. Uptime Kuma دارای مانیتورهای push است: این ابزار انتظار دارد ربات شما در زمان‌بندی مشخصی یک URL را فراخوانی کند و در صورت متوقف شدن این فراخوانی‌ها، هشدار می‌دهد. این فراخوانی را در انتهای حلقه اصلی (main loop) خود قرار دهید، یعنی پس از بخشی که زنده بودن ربات را اثبات می‌کند، مانند خواندن موفقیت‌آمیز داده‌های بازار.

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

بازه زمانی مانیتور را تقریباً دو برابر زمان اجرای حلقه خود تنظیم کنید تا نوسانات عادی باعث ارسال هشدار کاذب نشود. مانیتور را روی سروری متفاوت از ربات اجرا کنید، زیرا مانیتوری که همزمان با سرویس تحت نظارت از کار بیفتد، هیچ گزارشی ارسال نخواهد کرد. نحوه راه‌اندازی در مانیتورینگ وضعیت به صورت self-hosted با Uptime Kuma توضیح داده شده است.

یک هشدار برای فضای دیسک نیز اضافه کنید. رباتی که لاگ‌های پرحجم می‌نویسد، در عرض چند هفته فایل‌سیستم root را پر می‌کند. پر شدن دیسک باعث توقف نوشتن در دیتابیس می‌شود، نه فراخوانی شبکه، بنابراین علائم آن عجیب و گمراه‌کننده خواهد بود. journalctl --vacuum-time=14d و یک خط SystemMaxUse= در /etc/systemd/journald.conf باعث محدود ماندن حجم journal می‌شود.

بخش صادقانه: تأخیر (latency) عمدتاً به میزبان شما مربوط نیست

اینجاست که بازار محصولات VPS برای ترید، از جنبه فنی خارج می‌شود. صفحات تبلیغاتی اعداد زیر یک میلی‌ثانیه را ذکر می‌کنند و القا می‌کنند که میزبان، تنها مانع بین شما و انجام معامله است. برای تقریباً تمام ربات‌های خرده‌فروشی، این‌طور نیست.

سفارش شما از ربات به سمت endpoint صرافی یا کارگزار از طریق اینترنت عمومی حرکت می‌کند. آن مسیر تحت تأثیر فاصله فیزیکی و peering بین ارائه‌دهنده شما و آن‌هاست. سروری در فرانکفورت که با endpointای در توکیو ارتباط دارد، صرف‌نظر از سرعت CPU، حدود 250 میلی‌ثانیه تأخیر رفت‌وبرگشت (round trip) خواهد داشت. سپس سیستم‌های خود کارگزار، صف، بررسی‌های ریسک و محدودیت‌های نرخ (rate limits) خود را اضافه می‌کنند که برای یک حساب خرده‌فروشی معمولاً در مقیاس ده‌ها یا صدها میلی‌ثانیه اندازه‌گیری می‌شود.

به‌جای حدس زدن، آن را اندازه‌گیری کنید. curl زمان اتصال و زمان دریافت اولین بایت را برای یک endpoint واقعی گزارش می‌دهد:

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 ثانیه باشد، تأخیر باقی‌مانده مربوط به پردازش کارگزار است و هیچ تغییری در میزبان بر آن تأثیری نخواهد داشت.

پس میزبان چه زمانی اهمیت پیدا می‌کند؟ زمانی که شما در محل صرافی colocated هستید یا به آن cross-connect شده‌اید و برای جایگاه در صف رقابت می‌کنید، که این یک کسب‌وکار متفاوت با بودجه‌ای متفاوت است. همچنین زمانی که کد خودتان گلوگاه (bottleneck) است: رباتی که در هر تیک، شاخص‌ها را روی کل تاریخچه بازمحاسبه می‌کند، می‌تواند 200 میلی‌ثانیه از CPU را در هر حلقه مصرف کند که این تأخیر واقعی است و شما می‌توانید آن را به‌رایگان کنترل کنید. پیش از خرید سرور سریع‌تر، حلقه پردازشی خود را پروفایل کنید.

آنچه در انتخاب میزبان اهمیت دارد، موقعیت جغرافیایی، شبکه پایدار و حافظه کافی است تا OOM killer هرگز فرصت مداخله پیدا نکند. تا ژوئیه 2026، یک ربات Python با استراتژی واحد و چند صد نماد در حافظه، به‌راحتی با 2 GB رم و 2 vCPU اجرا می‌شود. اگر تاریخچه تیک‌ها را در یک دیتابیس محلی نگه می‌دارید، حافظه بیشتری اضافه کنید.

چک‌لیست کوتاه پیش از عملیاتی‌سازی

  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. حجم لاگ‌ها محدود است و فایل‌سیستم root در df -h فضای کافی دارد.

پیش از استفاده از سرمایه واقعی، کل سیستم را به مدت یک هفته در محیط sandbox صرافی یا در حالت paper mode اجرا کنید. هدف از این یک هفته این است که هر یک از موارد بالا حداقل یک‌بار با شکست مواجه شود.

FAQ

آیا یک ربات معاملاتی به سرور با تأخیر کم (low-latency) یا سرور اختصاصی (bare metal) نیاز دارد؟

تنها در صورتی که در سرعت اجرا با سایر شرکت‌کنندگان خودکار در همان صرافی رقابت می‌کنید، که معمولاً به معنای استفاده از colocation به‌جای یک VPS عمومی است. برای یک ربات خرده‌فروشی، زمان رفت و برگشت (round trip) عمدتاً تحت تأثیر موقعیت جغرافیایی و پردازش‌های خودِ کارگزار است؛ بنابراین سروری نزدیک به API endpoint انتخاب کنید و پیش از پرداخت هزینه برای گزینه‌های سریع‌تر، با استفاده از curl و mtr اندازه‌گیری‌های لازم را انجام دهید.

یک ربات معاملاتی به چه مقدار RAM و CPU نیاز دارد؟

بیشتر ربات‌های تک‌استراتژی محدود به شبکه هستند و در فواصل بین رویدادها بیکار می‌مانند. تا جولای 2026، تعداد 2 هسته vCPU و 2 گیگابایت RAM برای یک ربات پایتون که چند صد نماد را ردیابی می‌کند، کافی است. زمانی که تاریخچه قیمت (tick history) را در حافظه نگه می‌دارید یا یک دیتابیس محلی اجرا می‌کنید، حافظه به عامل محدودکننده تبدیل می‌شود؛ پس به‌جای حدس زدن، free -h و لاگ‌های سیستم را برای پیام‌های OOM kill بررسی کنید.

چرا API صرافی درخواست‌های مرا با خطای timestamp رد می‌کند؟

ساعت سرور از بازه زمانی مجاز صرافی (که معمولاً چند ثانیه است) خارج شده است. برنامه chrony را نصب کنید، تأیید کنید که chronyc tracking یک offset کوچک System time و وضعیت همگام‌سازی leap را نشان می‌دهد، و ساعت ماشین را روی UTC تنظیم کنید تا تغییرات ساعت تابستانی (daylight saving) باعث جابه‌جایی آن نشود. چرخاندن (rotate) کلید API مشکل ساعت را حل نمی‌کند.

چگونه از توقف ربات در طول شب بدون اطلاع خودم جلوگیری کنم؟

آن را تحت مدیریت systemd با Restart=always و StartLimitIntervalSec=0 اجرا کنید تا در صورت بروز خطا، به‌جای توقف دائمی، تلاش مجدد (retry) انجام شود. سپس یک heartbeat اضافه کنید که ربات در پایان هر حلقه موفق ارسال می‌کند. قابلیت restart، پروسه را مدیریت می‌کند و heartbeat مواردی را که پروسه زنده است اما در یک وضعیت گیر کرده (stuck) قرار دارد، شناسایی می‌کند.

آیا می‌توانم ربات و ابزار مانیتورینگ را روی یک VPS اجرا کنم؟

می‌توانید، اما در روزی که واقعاً به مانیتورینگ نیاز دارید، این ابزار به شما دروغ خواهد گفت؛ زیرا قطعی که باعث از کار افتادن ربات شود، مانیتور را نیز از دسترس خارج می‌کند. سیستم هشداردهی را روی یک ماشین جداگانه، ترجیحاً با ارائه‌دهنده یا در منطقه‌ای متفاوت نگه دارید و از سرور ربات فقط برای خودِ ربات و لاگ‌های آن استفاده کنید.