VPS مناسب ربات معاملاتی چه ویژگیهایی دارد؟
برای ربات معاملاتی، VPS باید با systemd پس از توقف دوباره اجرا شود، ساعت دقیقی داشته باشد، کلیدهای API را ایمن نگه دارد و با heartbeat از توقف باخبرتان کند.
یک ربات معاملاتی از VPS چه نیاز دارد؟
VPS برای رباتهای معاملاتی بر اساس 4 عامل ارزیابی میشود: آیا فرایند پس از متوقفشدن دوباره اجرا میشود، آیا ساعت سیستم دقیق است، آیا سرقت کلیدهای API (رابط برنامهنویسی کاربردی) دشوار است، و آیا هنگام توقف ربات از آن مطلع میشوید. برای یک ربات خردهفروشی، سرعت خام در رتبه بسیار پایینتری قرار دارد؛ زیرا بخش کند مسیر ارسال سفارش شما کارگزار و فاصله تا آن است، نه میزبانی که Python را اجرا میکند.
این یک راهنمای مهندسی است. هیچیک از مطالب اینجا توصیه مالی نیست و درباره هیچ راهبردی بحث نمیشود.
پایداری سرویس، انضباط در راهاندازی مجدد است؛ نه عددی در صفحه فروش
هر میزبان در جهان پایداری 99.9 درصدی را تبلیغ میکند. این رقم وضعیت hypervisor را توصیف میکند، نه ربات شما را. ربات بر اثر یک استثنای مدیریتنشده، یک websocket که هرگز دوباره متصل نمیشود، یا OOM (تمامشدن حافظه) killer از کار میافتد، در حالی که سرور در تمام این مدت فعال میماند. بنابراین پرسش مفید این است که در 10 ثانیه پس از خروج فرایند شما چه رخ میدهد.
ربات را بهصورت یک سرویس systemd اجرا کنید و مدیریت راهاندازی مجدد را به سیستم init بسپارید. یک فایل unit این کار را در 6 خط انجام میدهد.
[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 ثانیه منصرف میشود و unit را برای همیشه در وضعیت failed باقی میگذارد؛ این دقیقاً رفتاری است که در ساعت 03:00 نمیخواهید. تنظیم آن روی 0 محدودیت نرخ را غیرفعال میکند؛ بنابراین رباتی که وارد چرخه crash میشود، به تلاش ادامه میدهد و ساکت نمیشود. RestartSec=10 از ایجاد فشار مداوم این چرخه بر exchange با اتصالهای مجدد جلوگیری میکند.
پیش از اعتماد به فایل، آن را بررسی کنید، سپس سرویس را راهاندازی کنید:
sudo systemd-analyze verify /etc/systemd/system/tradingbot.service
sudo systemctl daemon-reload
sudo systemctl enable --now tradingbot
systemctl status tradingbotenable بخشی است که پس از راهاندازی مجدد باقی میماند، و بهروزرسانیهای kernel به راهاندازی مجدد نیاز دارند. برای مشاهده اینکه آیا ربات بیسروصدا از کار افتاده است یا نه، شمارنده راهاندازی مجدد را از systemd درخواست کنید:
systemctl show tradingbot -p NRestarts
journalctl -u tradingbot --since "24 hours ago" | tail -50NRestarts=0 پس از یک هفته نشاندهنده رباتی سالم است. NRestarts=812 یعنی با فرایندی معامله کردهاید که تمام شب دوباره متصل میشده است. ساختار کامل فایل unit، شامل timerها برای کارهای زمانبندیشده مانند گزارش روزانه، در اجرای یک برنامه بهعنوان سرویس systemd توضیح داده شده است.
ساعت را روی UTC تنظیم کنید و همگامسازی آن را اثبات کنید
APIهای صرافی درخواستها را با timestamp امضا میکنند و هر درخواستی را که خارج از یک بازه زمانی باشد، معمولاً 5 ثانیه یا کمتر، رد میکنند. ساعت ناهماهنگ خطاهایی ایجاد میکند که شبیه خطاهای احراز هویت هستند؛ بنابراین افراد پیش از بررسی زمان، ساعتها کلیدها را تعویض میکنند. در APIهای مشابه Binance، پیام صریح است: Timestamp for this request was 1000ms ahead of the server's time.
سرور را روی UTC تنظیم کنید. منطقههای زمانی محلی باعث جهش ناشی از تغییر ساعت تابستانی میشوند و این جهش ممکن است در میانه یک نشست معاملاتی رخ دهد.
sudo timedatectl set-timezone UTC
timedatectlUbuntu، systemd-timesyncd را ارائه میکند که یک client از نوع SNTP (simple network time protocol) است. این ابزار برای logها مناسب است، اما برای هر کاری که باید در محدوده چند میلیثانیه باقی بماند، ضعیف است؛ زیرا از یک server نظرسنجی میکند و ساعت را بهطور پیوسته تنظیم نمیکند. بهجای آن از 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 هنوز به server متصل نشده است؛ معمولاً به این دلیل که UDP 123 خروجی مسدود است. یک دقیقه صبر کنید، سپس پیش از تغییر قوانین firewall دوباره بررسی کنید.
کلیدهای API را در محلهای قابل کپی قرار ندهید
نشت یک کلید صرافی از نشت یک کلید SSH خطرناکتر است، زیرا مجوز برداشت، آن را فوراً به پول تبدیل میکند. دو عادت بیشتر این خطر را پوشش میدهند.
اول، هرگز به کلید یک bot مجوز برداشت ندهید و اگر صرافی از این قابلیت پشتیبانی میکند، کلید را به آدرس IP سرور خود محدود کنید. این تنها کنترلی است که یک کلید سرقتشده را تقریباً بیاستفاده میکند.
دوم، secret را خارج از code directory نگه دارید. هر چیزی که داخل /opt/tradingbot باشد، دیر یا زود وارد یک git repository یا backup archive میشود. آن را در فایلی با مالکیت 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 است؛ بدون quote و بدون export. حالت 640 همراه با گروه bot باعث میشود service user بتواند فایل را بخواند و هیچ کاربر دیگری نتواند. با sudo -u bot cat /etc/tradingbot/api.env بررسی کنید و سپس با هر کاربر دیگری نیز آزمایش کنید؛ در این حالت باید با خطای Permission denied مواجه شود.
خود bot نباید با root یا کاربر login شما اجرا شود. یک system account بدون shell و بدون home directory برای اجرای سرویس ایجاد کنید:
sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/tradingbot --create-home botدلیل استفاده از هر یک از این flagها و میزان واقعی اثرگذاری ProtectSystem=strict در اجرای سرویسها با کاربر غیرمجاز توضیح داده شده است. سایر بخشهای baseline سرور، یعنی SSH keys و firewall، باید در 10 دقیقه اول روی یک VPS جدید انجام شوند.
پیش از کارگزاری متوجه از کار افتادن آن شوید
systemctl status نشان میدهد که فرایند در حال اجرا است. اما نشان نمیدهد که ربات کاری انجام میدهد. فرایندی که در حلقه تلاش مجدد در برابر یک websocket ازکارافتاده گیر کرده باشد، تمام بررسیهایی را که systemd میتواند انجام دهد با موفقیت پشت سر میگذارد.
در عوض، از heartbeat استفاده کنید. Uptime Kuma دارای push monitor است: این قابلیت انتظار دارد ربات شما طبق یک برنامه زمانی، یک URL را فراخوانی کند و وقتی فراخوانیها متوقف شوند، هشدار میدهد. این فراخوانی را در انتهای حلقه اصلی، پس از بخشی قرار دهید که زنده بودن ربات را ثابت میکند؛ برای مثال، پس از یک خواندن موفق دادههای بازار.
curl -fsS "http://monitor.example.com:3001/api/push/YOUR_TOKEN?status=up&msg=loop_ok"فاصله زمانی monitor را تقریباً 2 برابر زمان اجرای حلقه تنظیم کنید تا نوسانهای عادی باعث ارسال هشدار نشوند. monitor را روی سروری متفاوت از ربات اجرا کنید، زیرا monitorی که همراه با چیزی که نظارت میکند از کار بیفتد، هیچ گزارشی ارسال نمیکند. راهاندازی آن در نظارت بر وضعیت با Uptime Kuma بهصورت self-hosted توضیح داده شده است.
برای دیسک نیز یک هشدار اضافه کنید. رباتی که logهای پرجزئیات مینویسد، ظرف چند هفته filesystem مربوط به root را پر میکند و دیسک پر مانع نوشتن database میشود، نه فراخوانی شبکه؛ بنابراین علائم غیرعادی خواهند بود. journalctl --vacuum-time=14d و یک خط SystemMaxUse= در /etc/systemd/journald.conf اندازه journal را محدود نگه میدارند.
بخش صادقانه: تأخیر عمدتاً به میزبان شما مربوط نیست
اینجاست که بازار محصولات VPS معاملاتی از جنبه فنی فاصله میگیرد. صفحات بازاریابی اعداد کمتر از یک میلیثانیه را اعلام میکنند و این تصور را ایجاد میکنند که میزبان میان شما و اجرای سفارش قرار دارد. برای تقریباً همه رباتهای خردهفروشی، چنین نیست.
سفارش شما از ربات به نقطه پایانی صرافی یا کارگزار، از طریق اینترنت عمومی منتقل میشود. این مسیر عمدتاً تحت تأثیر فاصله فیزیکی و ارتباط همتابههمتای ارائهدهنده شما با ارائهدهنده آنهاست. سروری در Frankfurt که با نقطه پایانی در Tokyo ارتباط دارد، صرفنظر از سرعت CPU، تقریباً 250 میلیثانیه زمان رفتوبرگشت نیاز دارد. سپس سامانههای خود کارگزار نیز زمان صف، بررسیهای ریسک و محدودیتهای نرخ را اضافه میکنند؛ این زمانها برای یک حساب خردهفروشی معمولاً در حد دهها یا صدها میلیثانیه هستند.
بهجای حدسزدن، آن را اندازهگیری کنید. 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 ثانیه است، تأخیر باقیمانده مربوط به پردازش کارگزار است و تغییر میزبان آن را کاهش نمیدهد.
پس میزبان چه زمانی اهمیت دارد؟ زمانی که با venue هممکان یا به آن cross-connect شدهاید و برای جایگاه در صف رقابت میکنید؛ این فعالیت کسبوکاری متفاوت با بودجهای متفاوت است. همچنین زمانی که کد خودتان گلوگاه است: رباتی که در هر tick، شاخصها را بر اساس کل تاریخچه دوباره محاسبه میکند، ممکن است در هر حلقه 200 میلیثانیه از CPU مصرف کند. این تأخیر واقعی است و میتوانید بدون هزینه آن را کنترل کنید. پیش از جستوجو برای سرور سریعتر، حلقه را profile کنید.
در میزبانی که انتخاب میکنید، جغرافیا، شبکه پایدار و حافظه کافی اهمیت دارد تا OOM killer هرگز نقشی نداشته باشد. از July 2026، یک ربات Python تکاستراتژی با چند صد نماد در حافظه، با 2 GB RAM و 2 vCPU بهراحتی اجرا میشود. اگر تاریخچه tick را در یک پایگاهداده محلی نگه میدارید، حافظه بیشتری اضافه کنید.
یک چکلیست کوتاه پیش از راهاندازی واقعی
systemctl is-enabled tradingbotمقدارenabledرا چاپ میکند و سرویس پس ازsudo rebootنیز به کار خود ادامه میدهد.chronyc trackingاختلاف زمان سیستم را کمتر از چند میلیثانیه گزارش میکند.- کلید API مجوز معامله دارد، اما مجوز برداشت ندارد. همچنین، اگر صرافی فهرست مجاز IP ارائه میکند، این فهرست برای کلید تنظیم شده است.
- متوقف کردن فرایند با
sudo systemctl kill -s SIGKILL tradingbotباعث میشود فرایند حداکثر ظرفRestartSecدوباره اجرا شود. - وقتی ربات را عمداً متوقف میکنید، مانیتور heartbeat حداکثر در یک بازه زمانی به شما هشدار میدهد.
- اندازه logها محدود است و سیستم فایل root در
df -hفضای خالی کافی دارد.
پیش از استفاده از وجوه واقعی، کل فرایند را به مدت یک هفته در sandbox صرافی یا در حالت paper اجرا کنید. همه موارد بالا در طول آن هفته دستکم یک بار شکست میخورند؛ هدف از اجرای یکهفتهای نیز همین است.
FAQ
آیا ربات معاملاتی به سروری با تأخیر کم یا سرور bare metal نیاز دارد؟
فقط زمانی که در همان venue با مشارکتکنندگان خودکار دیگر بر سر سرعت اجرا رقابت میکنید. در این حالت، معمولاً colocation لازم است، نه یک VPS عمومی. برای ربات خردهفروشی، زمان رفتوبرگشت عمدتاً به موقعیت جغرافیایی و پردازش خود کارگزار بستگی دارد. بنابراین سروری نزدیک به نقطه پایانی API انتخاب کنید و پیش از پرداخت برای گزینه سریعتر، با curl و mtr اندازهگیری کنید.
ربات معاملاتی به چه مقدار RAM و CPU نیاز دارد؟
بیشتر رباتهای تکراهبردی به شبکه محدود هستند و بین رویدادها در حالت بیکار میمانند. در July 2026، مقدار 2 vCPU و 2 GB RAM برای اجرای یک ربات Python که چندصد instrument را رصد میکند کافی است. زمانی که تاریخچه tick را در حافظه فرایند نگه میدارید یا یک پایگاه داده محلی اجرا میکنید، حافظه به عامل محدودکننده تبدیل میشود. بنابراین بهجای حدسزدن، free -h و journal را برای پیامهای OOM kill پایش کنید.
چرا exchange درخواستهای API من را با خطای timestamp رد میکند؟
ساعت سرور از پنجره زمانی امضای exchange خارج شده است. این اختلاف معمولاً چند ثانیه است. chrony را نصب کنید، بررسی کنید که chronyc tracking یک System time کوچک و وضعیت leap همگامسازیشده را نشان دهد، و ماشین را روی UTC تنظیم کنید تا تغییر ساعت تابستانی هرگز زمان آن را جابهجا نکند. چرخش API key مشکل ساعت را برطرف نمیکند.
چگونه مانع شِرِفشدن ربات در طول شب، بدون اطلاع خودم، شوم؟
ربات را با systemd و با استفاده از Restart=always و StartLimitIntervalSec=0 اجرا کنید تا در صورت ورود به چرخه crash، بهجای توقف دائمی، تلاش برای راهاندازی مجدد را ادامه دهد. سپس heartbeatی اضافه کنید که ربات در پایان هر loop موفق ارسال کند. راهاندازی مجدد، فرایند را مدیریت میکند. heartbeat حالتی را شناسایی میکند که فرایند زنده است اما گیر کرده است.
آیا میتوانم ربات و سامانه monitoring خود را روی همان VPS اجرا کنم؟
بله، اما روزی که این موضوع اهمیت پیدا میکند، monitoring اطلاعات نادرست به شما میدهد. زیرا قطعیای که ربات را از کار بیندازد، monitoring را نیز از کار میاندازد. سامانه alerting را روی ماشینی جداگانه نگه دارید؛ ترجیحاً ماشینی از provider یا regionی متفاوت. از سرور ربات فقط برای ربات و logهای آن استفاده کنید.