ساخت ربات ترید با هوش مصنوعی از چیزی که فکر می‌کنید ساده‌تر است: قانون معامله را به زبان ساده برای Claude Code یا ChatGPT می‌نویسید و کد پایتونش را تحویل می‌گیرید. سخت‌ترین بخش کار نوشتن کد نیست؛ این است که بفهمید آن قانون واقعاً جواب می‌دهد یا فقط روی کاغذ خوب است. راه امن پنج قدم دارد: استراتژی را دقیق بنویسید، با هوش مصنوعی بک‌تست بسازید، نتیجه را با شک بخوانید، چند هفته بدون پول معامله آزمایشی کنید و فقط بعد از آن، با کلیدی که اجازه برداشت ندارد، ربات را به حساب واقعی وصل کنید.

ما همین مسیر را برای این مقاله رفتیم. Claude یک ربات ساده برای بیت‌کوین نوشت که با دو میانگین متحرک خرید و فروش می‌کند و ما آن را روی قیمت‌های واقعی روزانه از دی ۱۳۹۸ تا مهر ۱۴۰۵ اجرا کردیم. نتیجه شاید غافلگیرتان کند: ربات از کسی که فقط بیت‌کوین خریده و نگهش داشته بود عقب ماند. کد، عددها و دلیل این نتیجه را پایین‌تر می‌بینید، همراه با خطاهایی که نتیجه بک‌تست را بهتر از واقعیت نشان می‌دهند.

ربات ترید هوش مصنوعی یعنی چه؟

وقتی کسی از «ربات ترید هوش مصنوعی» حرف می‌زند، معمولاً منظورش یکی از این دو است:

  • هوش مصنوعی ربات را می‌سازد. شما قانون را تعیین می‌کنید، هوش مصنوعی کدش را می‌نویسد و ربات از آن به بعد همان قانون ثابت را اجرا می‌کند. ربات نهایی هیچ «هوشی» ندارد و دقیقاً همان کاری را می‌کند که گفته‌اید و به همین دلیل می‌شود آزمایشش کرد. این مقاله درباره همین نوع است.
  • هوش مصنوعی خودش تصمیم می‌گیرد. یک مدل زبانی هر بار بازار را می‌خواند و می‌گوید بخر یا بفروش. جواب این مدل‌ها از یک اجرا تا اجرای بعد عوض می‌شود و چون با داده‌های همین سال‌ها آموزش دیده‌اند، امتحان کردنشان روی گذشته هم نتیجه قابل اعتمادی نمی‌دهد.

اگر می‌خواهید بدانید هوش مصنوعی کجای ترید واقعاً به کار می‌آید و کجا نه، راهنمای کامل ترید با هوش مصنوعی را بخوانید. اینجا فقط سراغ ساختن می‌رویم.

قدم اول: استراتژی را دقیق و بدون ابهام بنویسید

هوش مصنوعی فقط چیزی را درست کد می‌کند که شما دقیق گفته باشید. «وقتی بازار صعودی شد بخر» قانون نیست، چون معلوم نیست صعودی یعنی چه، با کدام قیمت، چه زمانی و با چه مبلغی. قانون خوب قانونی است که اگر به دو نفر بدهید، هر دو دقیقاً یک کار کنند. قانون نمونه ما این است:

  1. بازار: بیت‌کوین به تتر (BTC/USDT)، با قیمت‌های روزانه.
  2. ورود: هر وقت میانگین قیمت ۵۰ روز اخیر بالای میانگین ۲۰۰ روز اخیر بود و بیت‌کوین نداشتی، با همه موجودی بیت‌کوین بخر.
  3. خروج: هر وقت میانگین ۵۰ روزه زیر ۲۰۰ روزه بود و بیت‌کوین داشتی، همه را بفروش و تتر نگه دار.
  4. زمان: تصمیم بعد از بسته شدن کندل روزانه گرفته می‌شود و معامله با قیمت باز شدن روز بعد انجام می‌شود.
  5. هزینه: هر خرید یا فروش ۰٫۲٪ هزینه دارد. این عدد را برای کارمزد و لغزش قیمت (Slippage) با هم فرض کرده‌ایم. لغزش یعنی فاصله قیمتی که انتظارش را داشتید با قیمتی که معامله واقعاً با آن انجام شد.
  6. معیار مقایسه: کسی که روز اول با همان پول بیت‌کوین خریده و دیگر به آن دست نزده است.

میانگین متحرک (Moving Average) یعنی میانگین قیمت بسته شدن چند روز آخر که هر روز یک قدم جلو می‌رود. به لحظه‌ای که میانگین ۵۰ روزه از پایین بالای ۲۰۰ روزه می‌رود «تقاطع طلایی» (Golden Cross) می‌گویند و از معروف‌ترین قانون‌های تحلیل تکنیکال است. این قانون را چون ساده است انتخاب کردیم، نه چون فکر می‌کردیم سود می‌دهد.

بند ۴ و ۶ را جدی بگیرید. بند ۴ جلوی رایج‌ترین باگ بک‌تست را می‌گیرد و بند ۶ نشان می‌دهد ساختن ربات اصلاً می‌ارزد یا نه. کارمزد واقعی سواپ‌ولت را هم در صفحه کارمزدها ببینید و اگر با فرض ما فرق داشت، عدد خودتان را در کد بگذارید. اگر هدفتان فقط خرید منظم و بی‌دردسر است، اصلاً ربات لازم ندارید؛ خرید پله‌ای یا DCA همین کار را با یک یادآور ساده انجام می‌دهد.

قدم دوم: بک‌تست را با Claude Code یا ChatGPT بنویسید

بک‌تست (Backtest) یعنی اجرای قانون روی قیمت‌های گذشته، تا ببینید اگر آن موقع ربات را روشن کرده بودید چه اتفاقی می‌افتاد. برای این کار سه چیز لازم دارید: پایتون، که رایگان است و از python.org نصب می‌شود، یک دستیار هوش مصنوعی و حدود یک ساعت وقت.

Claude Code کد را روی سیستم خود شما می‌نویسد، اجرا می‌کند، خطا را می‌بیند و درستش می‌کند. با ChatGPT یا نسخه چت Claude هم می‌شود؛ فقط باید کد را کپی کنید، خودتان اجرا کنید و اگر خطا داد، پیام خطا را به چت برگردانید. نصب و شروع کار با Claude Code را در آموزش Claude Code گفته‌ایم. این ابزار در نسخه رایگان Claude نیست و یکی از اشتراک‌های پولی را می‌خواهد. Anthropic هنوز ایران را در فهرست کشورهای پشتیبانی‌شده‌اش ندارد و این اشتراک معمولاً از فروشنده خریده می‌شود؛ راهش را در خرید اکانت Claude در ایران توضیح داده‌ایم. حساب را روی ایمیل خودتان بسازید و با کسی شریکش نشوید تا پایدار بماند.

این درخواست را به Claude Code بدهید یا در ChatGPT بچسبانید:

درخواست: یک اسکریپت پایتون به اسم backtest.py بنویس که فقط از کتابخانه‌های استاندارد پایتون استفاده کند. قیمت‌های روزانه BTCUSDT را از API عمومی بایننس (data-api.binance.vision) از تاریخ 2019-06-01 بگیرد و در یک فایل ذخیره کند تا دفعه بعد دوباره دانلود نشود. این استراتژی را از 2020-01-01 تا 2026-09-30 بک‌تست کن: اگر میانگین ۵۰ روزه قیمت بسته شدن بالای میانگین ۲۰۰ روزه است، با همه موجودی بیت‌کوین بخر و اگر پایین است، همه را بفروش و تتر نگه دار. تصمیم را با قیمت بسته شدن دیروز بگیر و معامله را با قیمت باز شدن امروز انجام بده. برای هر خرید یا فروش ۰٫۲٪ هزینه کم کن. با ۱۰۰۰ تتر شروع کن و نتیجه را با خرید یک‌باره و نگه داشتن مقایسه کن: ارزش نهایی، تعداد معامله، بیشترین افت از اوج و درصد روزهایی که در بازار بوده. بعد اجرایش کن و توضیح بده کجای کد ممکن است ناخواسته از داده آینده استفاده کند.

تاریخ‌ها را میلادی نوشته‌ایم چون API همین قالب را می‌خواهد. داده از ۱۱ خرداد ۱۳۹۸ شروع می‌شود تا وقتی بک‌تست در دی ۱۳۹۸ شروع می‌شود، بیش از ۲۰۰ روز قیمت در دست باشد و میانگین ۲۰۰ روزه آماده باشد. کد زیر را Claude برای همین مقاله با درخواستی مثل بالا نوشت و ما اجرایش کردیم. جز خود پایتون به هیچ کتابخانه‌ای احتیاج ندارد:

Python
# backtest.py: SMA crossover vs buy-and-hold on BTC/USDT daily candles.
# Standard-library Python only (3.8+). Run: python3 backtest.py
import json, os, urllib.request
from datetime import datetime, timezone

FEE = 0.002              # 0.2% on every buy and sell (fee + slippage): an assumption
FAST, SLOW = 50, 200     # moving-average lengths, in days
START, END = "2020-01-01", "2026-09-30"
CACHE = "btc_daily.json"


def load_candles():
    """Daily [date, open, close] from Binance's public market-data API, cached to a file."""
    if os.path.exists(CACHE):
        return json.load(open(CACHE))
    rows, start = [], 1559347200000      # 2019-06-01, so the 200-day average is ready by START
    while True:
        url = ("https://data-api.binance.vision/api/v3/klines"
               f"?symbol=BTCUSDT&interval=1d&startTime={start}&limit=1000")
        batch = json.load(urllib.request.urlopen(url))
        rows += batch
        if len(batch) < 1000:
            break
        start = batch[-1][0] + 86_400_000
    candles = [[datetime.fromtimestamp(r[0] / 1000, timezone.utc).strftime("%Y-%m-%d"),
                float(r[1]), float(r[4])] for r in rows[:-1]]   # drop today's unfinished candle
    json.dump(candles, open(CACHE, "w"))
    return candles


def sma(closes, n, day):
    """Average of the n closing prices up to and including `day`."""
    return sum(closes[day - n + 1:day + 1]) / n


def crossover(fast, slow):
    return lambda closes, day: sma(closes, fast, day) > sma(closes, slow, day)


def hold(closes, day):
    return True


def run(candles, rule, start, end, peek=False):
    """Start with 1000 USDT. Decide on yesterday's close, trade at today's open.
    peek=True decides on today's close instead: the look-ahead bug."""
    dates, opens, closes = zip(*candles)
    first, last = dates.index(start), dates.index(end)
    cash, btc, orders, days_in, peak, max_dd, curve = 1000.0, 0.0, 0, 0, 1000.0, 0.0, []
    for i in range(first, last + 1):
        want_btc = rule(closes, i if peek else i - 1)
        if want_btc and btc == 0:
            btc, cash, orders = cash * (1 - FEE) / opens[i], 0.0, orders + 1
        elif not want_btc and btc > 0:
            cash, btc, orders = btc * opens[i] * (1 - FEE), 0.0, orders + 1
        value = cash + btc * closes[i]
        days_in += btc > 0
        peak = max(peak, value)
        max_dd = max(max_dd, 1 - value / peak)
        curve.append(value)
    return {"final": value, "orders": orders, "max_dd": max_dd,
            "in_market": days_in / len(curve), "curve": curve}


if __name__ == "__main__":
    candles = load_candles()
    tests = [("buy and hold", hold, False),
             (f"SMA {FAST}/{SLOW}", crossover(FAST, SLOW), False),
             ("look-ahead bug", crossover(FAST, SLOW), True)]
    for name, rule, peek in tests:
        r = run(candles, rule, START, END, peek)
        print(f"{name:15} final {r['final']:7.0f} USDT | orders {r['orders']:3} | "
              f"max drawdown {r['max_dd']:4.0%} | in market {r['in_market']:4.0%}")

فایل را با اسم backtest.py ذخیره کنید و در ترمینال، داخل همان پوشه، این دستور را بزنید (در ویندوز به‌جای python3 بنویسید python):

python3 backtest.py

بار اول قیمت‌ها از API عمومی بایننس دانلود می‌شوند و در فایل btc_daily.json می‌مانند تا اجراهای بعدی سریع باشند. اگر این آدرس از اینترنت شما باز نشد، هر فایل CSV از قیمت روزانه که تاریخ، قیمت باز شدن و قیمت بسته شدن داشته باشد کار را راه می‌اندازد؛ از Claude بخواهید تابع load_candles را برای خواندن همان فایل عوض کند. خروجی اجرای ما این بود:

متن ساده
buy and hold    final   11599 USDT | orders   1 | max drawdown  77% | in market 100%
SMA 50/200      final    4464 USDT | orders  15 | max drawdown  57% | in market  57%
look-ahead bug  final    4749 USDT | orders  15 | max drawdown  55% | in market  57%

قدم سوم: نتیجه واقعی بک‌تست را با شک بخوانید

با ۱٬۰۰۰ تتر پول اولیه و قیمت روزانه بیت‌کوین از ۱۱ دی ۱۳۹۸ تا ۸ مهر ۱۴۰۵، نتیجه این شد:

معیار

نگه داشتن بیت‌کوین

ربات میانگین ۵۰ و ۲۰۰ روزه

ارزش نهایی ۱٬۰۰۰ تتر

۱۱٬۵۹۹ تتر

۴٬۴۶۴ تتر

بیشترین افت از اوج

۷۷٪

۵۷٪

تعداد خرید و فروش

۱

۱۵

روزهایی که بیت‌کوین داشت

همه روزها

۵۷٪ روزها

نمودار بک‌تست: ارزش ۱۰۰۰ تتر از دی ۱۳۹۸ تا مهر ۱۴۰۵ با ربات میانگین متحرک ۵۰ و ۲۰۰ روزه در برابر نگه داشتن بیت‌کوین

دو چیز در این نمودار مهم است. اول اینکه ربات همیشه دیر می‌رسد. میانگین‌های طولانی کند حرکت می‌کنند، پس ربات بعد از اینکه بخش خوبی از رشد گذشته بود می‌خرید و بعد از اینکه بخش خوبی از ریزش گذشته بود می‌فروخت. مثلاً ۲ خرداد ۱۴۰۴ حدود ۱۱۱٬۷۰۰ تتر خرید و ۲۶ آبان ۱۴۰۴ حدود ۹۴٬۳۰۰ تتر فروخت. اولین معامله‌اش هم همین‌طور بود: ۳۰ بهمن ۱۳۹۸ حدود ۱۰٬۲۰۰ تتر خرید و ۷ فروردین ۱۳۹۹ حدود ۶٬۷۰۰ تتر فروخت.

دوم اینکه ربات بی‌فایده هم نبود. «بیشترین افت از اوج» یعنی حساب از بالاترین نقطه‌اش حداکثر چند درصد پایین آمده است. برای کسی که بیت‌کوین را نگه داشته بود این عدد ۷۷٪ بود: حسابش از آبان ۱۴۰۰ تا آبان ۱۴۰۱ از ۹٬۳۶۶ تتر به ۲٬۱۸۹ تتر رسید. برای ربات این افت ۵۷٪ بود. بعضی‌ها حاضرند سود کمتری بگیرند تا افت کمتری را تحمل کنند و بک‌تست کمک می‌کند این انتخاب را آگاهانه انجام دهید. ولی اگر هدف فقط بیشترین سود در همین دوره بود، ربات بازنده است.

این عددها فقط مال همین دوره‌اند. اگر شروع یا پایان را چند ماه جابه‌جا کنید، عوض می‌شوند. بک‌تست می‌گوید یک قانون در گذشته چطور رفتار کرده، نه اینکه در آینده چه می‌شود.

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

بک‌تست هر قدر هم دقیق به نظر برسد، از کدی که حسابش می‌کند درست‌تر نیست. سه خطای زیر در بک‌تست‌ها رایج‌اند، چه کد را خودتان نوشته باشید چه هوش مصنوعی، و هر سه نتیجه را بهتر از واقعیت نشان می‌دهند.

خطای نگاه به آینده (Look-ahead bias)

این خطا یعنی کد در لحظه تصمیم از چیزی استفاده کند که آن موقع هنوز معلوم نبوده است. رایج‌ترین شکلش این است که تصمیم با قیمت بسته شدن امروز گرفته شود و معامله با قیمت باز شدن همان امروز انجام شود. در دنیای واقعی صبح نمی‌دانید قیمت شب کجا بسته می‌شود. در کد ما فرق درست و غلط فقط یک عبارت کوچک است:

Python
want_btc = rule(closes, i - 1)   # right: decide on yesterday's close, trade at today's open
want_btc = rule(closes, i)       # look-ahead bug: today's close isn't known at today's open

برای اینکه ببینید این تفاوت کوچک چه می‌کند، قانون ساده‌تری را امتحان کردیم: «هر وقت قیمت بسته شدن بالای میانگین ۲۰ روزه است، بیت‌کوین داشته باش». نسخه درست این قانون ۱٬۰۰۰ تتر را در همان دوره به ۳٬۶۶۸ تتر رساند و نسخه‌ای که یک روز جلوتر را می‌دید، به ۷۳ میلیون تتر. در شش سال و نه ماه، هیچ قانون ساده‌ای پول را ۷۳ هزار برابر نمی‌کند؛ این عدد فقط نشان می‌دهد کد از آینده خبر داشته است.

بدتر اینکه این باگ همیشه خودش را نشان نمی‌دهد. در قانون ۵۰ و ۲۰۰ روزه، که کم معامله می‌کند، همین خطا نتیجه را فقط از ۴٬۴۶۴ به ۴٬۷۴۹ تتر رساند. چنین تفاوتی به چشم نمی‌آید، پس منتظر عدد عجیب نمانید و از اول کد را برای همین خطا بررسی کنید.

بیش‌برازش (Overfitting): وقتی بهترین تنظیم فقط خوش‌شانس بوده

وسوسه بعدی این است که از هوش مصنوعی بخواهید «بهترین عددها» را پیدا کند: به‌جای ۵۰ و ۲۰۰، کدام ترکیب بیشترین سود را می‌داد؟ ما این کار را کردیم. ۴۹۹ ترکیب مختلف از دو میانگین (میانگین کوتاه از ۵ تا ۱۰۰ روز و بلند از ۲۰ تا ۳۰۰ روز) را روی چهار سال اول، از دی ۱۳۹۸ تا دی ۱۴۰۲، امتحان کردیم و بهترینش را برداشتیم. بعد همه را بدون هیچ تغییری روی دو سال و نه ماه بعد اجرا کردیم.

نمودار بیش‌برازش: بهترین تنظیم میانگین متحرک در چهار سال اول، در دو سال و نه ماه بعد رتبه ۴۱۸ از ۴۹۹ شد

قهرمان چهار سال اول، یعنی میانگین ۲۵ و ۴۰ روزه، ۱٬۰۰۰ تتر را به ۱۰٬۴۹۳ تتر رسانده بود؛ حدود ۱٫۸ برابر نگه داشتن بیت‌کوین که به ۵٬۸۶۵ تتر رسیده بود. در دوره بعد همین ترکیب با ۱٬۳۵۶ تتر رتبه ۴۱۸ از ۴۹۹ را گرفت و از نگه داشتن ساده (۱٬۹۷۴ تتر) عقب ماند. عکسش هم درست بود: بهترین ترکیب دوره دوم، یعنی ۶۵ و ۹۰ روزه، در دوره اول رتبه ۴۷۶ را داشت. در کل فقط ۱۹٪ ترکیب‌ها در دوره دوم از نگه داشتن بهتر بودند.

بیش‌برازش یعنی همین. وقتی تنظیم‌های زیادی را امتحان کنید، بالاخره یکی پیدا می‌شود که روی گذشته عالی است، فقط به این دلیل که با بالا و پایین‌های تصادفی همان دوره جور درآمده. هر چه بیشتر بگردید، این خطر بیشتر می‌شود. سه کار کمک می‌کند:

  • بخشی از داده‌ها را از اول کنار بگذارید و فقط یک بار، آخر کار، قانون را روی آن امتحان کنید.
  • قانون‌هایی را ترجیح دهید که پارامتر کمی دارند و می‌توانید دلیلشان را به زبان ساده توضیح دهید.
  • اگر عوض کردن کوچکی، مثلاً ۴۵ به‌جای ۵۰، نتیجه را زیرورو می‌کند، به آن تنظیم اعتماد نکنید.

کارمزد و لغزش قیمت

قانونی که زیاد معامله می‌کند، کارمزد زیادی هم می‌دهد. قانون «قیمت بالای میانگین ۱۰ روزه» در همین دوره ۴۲۴ بار خرید یا فروش کرد. ببینید هزینه هر معامله چقدر نتیجه را عوض می‌کند:

هزینه هر خرید یا فروش

ارزش نهایی ۱٬۰۰۰ تتر

صفر

۶٬۴۲۵ تتر

۰٫۱٪

۴٬۲۰۴ تتر

۰٫۲٪

۲٬۷۴۹ تتر

۰٫۵٪

۷۶۷ تتر (ضرر)

بک‌تستی که کارمزد را حساب نمی‌کند، یا کارمزد را حساب می‌کند ولی لغزش را نه، برای ربات‌های پرمعامله تقریباً بی‌معنی است. برای اطمینان، بک‌تست را یک بار هم با دو برابر هزینه‌ای که انتظار دارید اجرا کنید.

چک‌لیست بررسی کدی که هوش مصنوعی نوشته

کد هوش مصنوعی ممکن است تمیز باشد و بی‌خطا اجرا شود و باز هم چیزی را غلط حساب کند. پیش از اینکه به عددها دل ببندید، این شش کار را بکنید:

  1. از خودش بپرسید. بنویسید: «کجای این کد ممکن است از داده آینده استفاده کند؟ خط به خط توضیح بده تصمیم هر روز با چه قیمتی گرفته و با چه قیمتی اجرا می‌شود.»
  2. چند معامله را با چشم چک کنید. تاریخ دو سه خرید و فروش را از کد بگیرید و روی نمودار قیمت ببینید منطقی هست یا نه.
  3. با نگه داشتن مقایسه کنید. ربات وقتی می‌ارزد که یا سود بیشتری بدهد یا افت کمتری داشته باشد.
  4. هزینه را دو برابر کنید. اگر نتیجه با هزینه بیشتر از بین رفت، استراتژی شکننده است.
  5. دوره آزمون را جدا نگه دارید. تنظیم‌ها را روی بخش اول داده انتخاب کنید و بخش آخر را فقط یک بار ببینید.
  6. به نتیجه خیلی خوب شک کنید. سود چندهزار درصدی معمولاً باگ است، نه کشف.

قدم چهارم: معامله آزمایشی با قیمت زنده سواپ‌ولت

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

اسکریپت زیر را در همان پوشه backtest.py بگذارید. سیگنال را از همان قانون می‌گیرد و قیمت را از API عمومی سواپ‌ولت، که قیمت لحظه‌ای هر ارز را به تتر و تومان می‌دهد و برای خواندنش کلید لازم نیست:

Python
# paper.py: run once a day, after the daily candle closes. It places no orders:
# it only logs what the bot would have done, at SwapWallet's live BTC/USDT price.
import csv, json, os, urllib.request
from datetime import datetime
from backtest import sma, FAST, SLOW, FEE

STATE = "paper_state.json"


def get(url):
    return json.load(urllib.request.urlopen(url))


candles = get("https://data-api.binance.vision/api/v3/klines"
              f"?symbol=BTCUSDT&interval=1d&limit={SLOW + 1}")
closes = [float(r[4]) for r in candles[:-1]]          # finished days only
last = len(closes) - 1
want_btc = sma(closes, FAST, last) > sma(closes, SLOW, last)
price = float(get("https://swapwallet.app/api/v1/market/prices")["result"]["BTC/USDT"])

state = json.load(open(STATE)) if os.path.exists(STATE) else {"usdt": 1000.0, "btc": 0.0}
action = "HOLD"
if want_btc and state["btc"] == 0:
    state["btc"], state["usdt"], action = state["usdt"] * (1 - FEE) / price, 0.0, "BUY"
elif not want_btc and state["btc"] > 0:
    state["usdt"], state["btc"], action = state["btc"] * price * (1 - FEE), 0.0, "SELL"
json.dump(state, open(STATE, "w"))

value = state["usdt"] + state["btc"] * price
with open("paper_trades.csv", "a", newline="") as f:
    csv.writer(f).writerow([datetime.now().isoformat(timespec="minutes"), price, action, round(value, 2)])
print(f"{action} | BTC/USDT {price} | paper value {value:.2f} USDT")

آن را روزی یک بار، کمی بعد از ساعت ۳:۳۰ بامداد به وقت ایران که کندل روزانه بایننس بسته می‌شود، اجرا کنید. در لینوکس و مک با cron و در ویندوز با Task Scheduler می‌شود این کار را خودکار کرد؛ اگر بلد نیستید، از Claude Code بخواهید برایتان تنظیمش کند. هر اجرا یک خط به فایل paper_trades.csv اضافه می‌کند.

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

قدم پنجم: ربات را با کمترین دسترسی به حساب وصل کنید

API سواپ‌ولت چه امکاناتی دارد؟

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

  • گرفتن قیمت لحظه‌ای ارزها به تتر و تومان؛
  • خواندن موجودی حساب و تاریخچه تراکنش‌ها؛
  • سواپ؛ یا «سواپ سریع» که بی‌درنگ با قیمت همان لحظه انجام می‌شود، یا اول قفل کردن قیمت برای ۱۰ ثانیه و بعد تأیید آن؛
  • برداشت کریپتو به هر آدرس و برداشت تومان به شبای ثبت‌شده خودتان؛
  • خرید از فروشگاه سواپ‌ولت و ساختن فاکتور پرداخت برای فروشگاه‌ها.

کلید را در اپ سواپ‌ولت از مسیر پروفایل ← کلید API ← ایجاد کلید جدید می‌سازید و در هدر هر درخواست می‌فرستید. پیش از نوشتن بخش اجرای ربات، در همان مستندات ببینید ارزی که می‌خواهید در فهرست ارزهای بخش سواپ هست یا نه.

کلید ربات نباید اجازه برداشت داشته باشد

این مهم‌ترین بخش این مقاله است. مستندات سواپ‌ولت می‌گوید کلیدهای API برای کار برنامه‌نویسی ساخته شده‌اند و موقع استفاده از آن‌ها تأیید دومرحله‌ای با پیامک، ایمیل یا Google Authenticator انجام نمی‌شود. همان‌جا آمده که برای کلیدی با دسترسی خاص، مثلاً محدود به یک IP یا با سطح دسترسی سفارشی، باید با پشتیبانی تماس بگیرید. در عمل یعنی:

  1. برای ربات کلید محدود بخواهید. از پشتیبانی کلیدی بخواهید که فقط کارهای ربات را انجام دهد، یعنی خواندن موجودی و قیمت و سواپ، و دسترسی برداشت نداشته باشد. اگر ربات روی سروری با IP ثابت اجرا می‌شود، کلید را به همان IP محدود کنید.
  2. کلید را داخل کد ننویسید. آن را در متغیر محیطی (Environment variable) نگه دارید و فایل کد را با کلید جایی آپلود نکنید.
  3. کلید واقعی را به هوش مصنوعی ندهید. وقتی از Claude یا ChatGPT می‌خواهید بخش اتصال را بنویسد، به‌جای کلید یک متن جایگزین مثل YOUR_API_KEY بگذارید. هر چه در چت بنویسید به ارائه‌دهنده آن هوش مصنوعی می‌رسد.
  4. با پول کم شروع کنید و ترمز بگذارید. سقف مبلغ هر معامله و سقف ضرر روزانه را در کد بنویسید تا اگر ربات به آن رسید، خودش متوقف شود.
  5. اگر کلید لو رفت، فوراً عوضش کنید. از مسیر پروفایل ← کلید API ← جایگزینی با کلید جدید کلید تازه بگیرید؛ کلید قبلی همان لحظه از کار می‌افتد.

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

سرور MCP برای پایش ربات، نه برای اجرای خودکار

راه دیگری هم برای وصل کردن هوش مصنوعی به حساب هست: سرور MCP سواپ‌ولت. کافی است یک بار با شماره موبایل و کد پیامک وارد شوید و دسترسی‌ها را تأیید کنید تا Claude یا هر دستیار سازگار دیگری بتواند حسابتان را بخواند. اگر فقط برای پایش وصل می‌شوید، در همان صفحه فقط دسترسی‌های خواندن را تیک بزنید. خواندن موجودی، سود و زیان و تاریخچه تراکنش‌ها بدون تأیید جداگانه انجام می‌شود و برای کسی که ربات ساخته ابزار خوبی است. مثلاً می‌توانید از Claude بپرسید «سود و زیان بیت‌کوینم از اول این ماه چقدر بوده؟» و جوابش را با گزارش ربات مقایسه کنید.

ابزارهای درخواست MCP، مثل سواپ و برداشت، به درد ربات بی‌وقفه نمی‌خورند و عمداً همین‌طور ساخته شده‌اند. هر درخواست اول در ربات تلگرام سواپ‌ولت برایتان می‌آید و تا دکمه تأیید را نزنید اجرا نمی‌شود. اگر ۱۵ دقیقه جواب ندهید، درخواست منقضی می‌شود و اگر ورود دومرحله‌ای حسابتان روشن باشد، برداشت کریپتو و انتقال را اصلاً نمی‌شود از MCP درخواست کرد. یک نکته را هم بدانید: سواپ‌ولت متن گفت‌وگوی شما را نمی‌بیند، ولی هر چه دستیار از حسابتان بخواند به ارائه‌دهنده همان هوش مصنوعی می‌رسد.


کلید API

سرور MCP

چه کسی وصل می‌شود

برنامه یا ربات شما

دستیار هوش مصنوعی مثل Claude

ورود

کلیدی که در پروفایل می‌سازید

شماره موبایل و کد پیامک، با دسترسی‌هایی که خودتان انتخاب می‌کنید

سواپ

بی‌درنگ و بدون تأیید

فقط درخواست؛ اجرا بعد از تأیید شما در تلگرام

مناسب برای

ربات خودکار

پایش، گزارش سود و زیان و کارهایی که خودتان تأیید می‌کنید

بهترین هوش مصنوعی برای نوشتن ربات ترید کدام است؟

برای اسکریپتی در اندازه این مقاله، هر مدل خوب امروزی کد درستی می‌نویسد. فرق اصلی در محیط کار است، نه در خود مدل:

  • Claude Code کد را روی سیستم شما اجرا می‌کند و خطاها را خودش رفع می‌کند. برای کسی که برنامه‌نویس نیست، این بزرگ‌ترین کمک است.
  • ChatGPT و چت Claude کد را می‌نویسند و معمولاً شما اجرایش می‌کنید. برای شروع و پرسیدن سؤال کافی‌اند.
  • Cursor ویرایشگر کد با هوش مصنوعی است و به درد کسی می‌خورد که می‌خواهد کد را خودش هم ببیند و تغییر دهد. مقایسه کاملش را در Cursor یا Claude Code ببینید.

اگر منظورتان از «ساخت ربات تریدر بدون برنامه‌نویسی» این است که خودتان کد ننویسید، هوش مصنوعی دقیقاً همین را ممکن کرده است؛ فقط باید بتوانید یک فایل پایتون را اجرا کنید و نتیجه را بخوانید. اگر بعدها امکانات بیشتری خواستید، Freqtrade یک ربات ترید متن‌باز و رایگان به زبان پایتون است که بک‌تست و حالت آزمایشی (Dry-run) دارد. سازندگانش هم توصیه می‌کنند هر ربات را اول در همین حالت آزمایشی اجرا کنید و تا نفهمیده‌اید چطور کار می‌کند، پول واقعی واردش نکنید.

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

پرسش‌های رایج

ساخت ربات ترید با هوش مصنوعی رایگان است؟

پایتون، داده‌های قیمتی که در این مقاله استفاده کردیم و API قیمت سواپ‌ولت رایگان‌اند. نسخه رایگان ChatGPT و Claude هم می‌تواند کدی در این اندازه بنویسد. فقط Claude Code اشتراک پولی می‌خواهد. هزینه واقعی از جایی شروع می‌شود که ربات با پول واقعی معامله کند و کارمزد بدهد.

با چت جی‌پی‌تی هم می‌شود ربات ترید ساخت؟

بله. همان درخواست را در ChatGPT بنویسید؛ فرقش این است که کد را خودتان اجرا می‌کنید و خطاها را به چت برمی‌گردانید. چک‌لیست بررسی کد را برای خروجی ChatGPT هم انجام دهید، چون هیچ مدلی از خطای نگاه به آینده در امان نیست.

ربات ترید هوش مصنوعی سود تضمینی دارد؟

نه. کمیسیون معاملات آتی کالای آمریکا (CFTC) در هشدار خود درباره ربات‌های ترید هوش مصنوعی می‌گوید فناوری هوش مصنوعی نمی‌تواند آینده یا تغییرات ناگهانی بازار را پیش‌بینی کند و کلاهبردارها با وعده سود بالا یا تضمینی سراغ مردم می‌آیند. ربات همین مقاله هم در آزمون روی گذشته از نگه داشتن ساده عقب ماند.

برای بک‌تست چند سال داده لازم است؟

عدد ثابتی ندارد، ولی داده باید هم دوره رشد و هم یک ریزش جدی را در بر بگیرد. داده ما از دی ۱۳۹۸ شروع می‌شود و ریزش سال ۱۴۰۱ را هم دارد. یک بخش از داده را هم برای آزمون نهایی کنار بگذارید.

می‌توانم ربات را مستقیم به حساب سواپ‌ولتم وصل کنم؟

بله، با API سواپ‌ولت. برای ربات از پشتیبانی کلیدی بخواهید که دسترسی برداشت نداشته باشد و اگر می‌شود به IP سرورتان محدود باشد. برای پایش حساب و گزارش سود و زیان هم می‌توانید Claude را از راه اتصال هوش مصنوعی به صرافی به حسابتان وصل کنید.