簡繁
ESC
↑↓ 選擇↵ 開啟站內全文搜尋
註冊幣安 ↗

Python 用 CCXT 連線幣安和歐易:查行情、餘額、下單與撤單

用 Python 的 CCXT 庫,同一套程式碼就能連線幣安和歐易:公開介面不需要 API Key 即可查行情、K 線和交易對精度,私有介面用環境變數傳入 Key 後可查餘額、掛單、撤單。本文附實測輸出、測試網與模擬盤切換方法、異常處理與重試寫法和完整可執行指令碼。

識途編輯部更新 閱讀 約 29 分鐘來源 4 個官方資料
目錄本文共 8 節
  1. 01CCXT 是什麼?為什麼用它連線幣安和歐易?
  2. 02怎麼安裝 CCXT?
  3. 03不用 API Key 怎麼查行情、K 線和交易對規則?
  4. 04私有介面要準備什麼?
  5. 05CCXT 怎麼切換到幣安測試網和歐易模擬盤?
  6. 06完整指令碼:查餘額、掛單、查掛單、撤單
  7. 07新手用 CCXT 最常遇到哪些問題?
  8. 08CCXT 異常怎麼處理?哪些錯誤可以重試?

CCXT 是一個開源的加密貨幣交易所介面庫,用 pip install ccxt 安裝後,同一套 Python 程式碼就能連線幣安和歐易:fetch_ticker 查行情、fetch_ohlcv 取 K 線、load_markets 讀交易對精度,這些公開介面不需要 API Key;傳入 Key 後再用 fetch_balance 查餘額、create_limit_buy_order 掛單、cancel_order 撤單。本文所有公開介面程式碼都在 CCXT 4.5.89、Python 3.13 下實際執行過,私有介面請先在幣安現貨測試網或歐易模擬盤執行。

CCXT 是什麼?為什麼用它連線幣安和歐易?

每家交易所的 API 寫法都不一樣:幣安的交易對叫 BTCUSDT,簽名放在查詢引數裡;歐易叫 BTC-USDT,簽名放在請求頭裡,還要多一個 Passphrase。CCXT 把這些差異封裝起來,對外提供統一的方法名和統一的資料格式:

  • 交易對統一寫成 BTC/USDT,CCXT 自動換成各交易所的內部程式碼。
  • 簽名、時間戳、請求頭都由 CCXT 處理,你只需要提供 Key。
  • 錯誤統一成 AuthenticationError、InsufficientFunds、InvalidOrder 等異常類型。

CCXT 支援上百家交易所,本文只講幣安和歐易。同一個安裝包裡有三種用法:import ccxt 是同步寫法,最適合入門和寫小指令碼,本文全部使用這種;import ccxt.async_support 是非同步寫法,適合同時請求很多交易對;import ccxt.pro 提供 WebSocket 即時推送,例如 watch_ticker,適合需要持續接收行情的程式。三者的方法名和返回格式基本一致,學會同步版本後遷移很容易。

要注意的是,CCXT 只是幫你「發請求」的工具,它不保管你的資產,也不會替你做任何交易決定。Key 存在你自己的電腦上,請求從你的電腦直接發往交易所,中間不經過第三方伺服器。要了解底層簽名是怎麼算的,可以看 交易所 API 簽名原理。

怎麼安裝 CCXT?

建議為每個專案建一個虛擬環境,避免和電腦自帶的 Python 環境互相干擾:

python3 -m venv .venv
source .venv/bin/activate        # Windows 用 .venv\Scripts\activate
pip install ccxt
python -c "import ccxt; print(ccxt.__version__)"

我們執行時輸出的版本號是 4.5.89。CCXT 更新很頻繁,方法名基本穩定,但個別交易所的預設引數可能變化,遇到和本文不一致的行為,先看看自己的版本號。

不用 API Key 怎麼查行情、K 線和交易對規則?

下面這個指令碼對幣安和歐易依次查詢伺服器時間、BTC/USDT 最新行情、最近 3 根 1 小時 K 線和交易對規則,全部是公開介面:

import ccxt

print("CCXT 版本:", ccxt.__version__)

binance = ccxt.binance({
    "enableRateLimit": True,
    "options": {"fetchMarkets": {"types": ["spot"]}},  # 只加載現貨市場,啟動更快
})
okx = ccxt.okx({"enableRateLimit": True})

SYMBOL = "BTC/USDT"

for ex in (binance, okx):
    print(f"\n===== {ex.id} =====")

    # 1. 伺服器時間:簽名請求前先確認本機時間沒有偏差
    server_ms = ex.fetch_time()
    print("伺服器時間:", ex.iso8601(server_ms), "本機偏差(ms):", ex.milliseconds() - server_ms)

    # 2. 最新行情
    t = ex.fetch_ticker(SYMBOL)
    print("最新價:", t["last"], "買一:", t["bid"], "賣一:", t["ask"],
          "24h 漲跌%:", round(t["percentage"], 2), "24h 成交量:", t["baseVolume"])

    # 3. 最近 3 根 1 小時 K 線:[時間, 開, 高, 低, 收, 成交量]
    for ts, o, h, l, c, v in ex.fetch_ohlcv(SYMBOL, timeframe="1h", limit=3):
        print(ex.iso8601(ts), o, h, l, c, round(v, 4))

    # 4. 交易對規則:精度與最小下單量
    markets = ex.load_markets()
    m = ex.market(SYMBOL)
    print("市場數量:", len(markets), "交易所內部程式碼:", m["id"])
    print("價格步長:", m["precision"]["price"], "數量步長:", m["precision"]["amount"])
    print("最小數量:", m["limits"]["amount"]["min"], "最小金額:", m["limits"]["cost"]["min"])
    print("數量 0.123456789 規整後:", ex.amount_to_precision(SYMBOL, 0.123456789))
    print("價格 65432.123456 規整後:", ex.price_to_precision(SYMBOL, 65432.123456))

2026 年 10 月 22 日執行時的真實輸出(價格為執行時資料,僅作格式示例):

CCXT 版本: 4.5.89

===== binance =====
伺服器時間: 2026-10-22T09:33:27.310Z 本機偏差(ms): -124
最新價: 81838.01 買一: 81838.0 賣一: 81838.01 24h 漲跌%: -2.11 24h 成交量: 21704.10475
2026-10-22T07:00:00.000Z 82491.56 82531.17 82111.0 82239.46 1264.4365
2026-10-22T08:00:00.000Z 82239.46 82267.79 81844.01 81861.24 1017.8519
2026-10-22T09:00:00.000Z 81861.25 81933.02 81653.0 81838.0 477.5245
市場數量: 3736 交易所內部程式碼: BTCUSDT
價格步長: 0.01 數量步長: 1e-05
最小數量: 1e-05 最小金額: 5.0
數量 0.123456789 規整後: 0.12345
價格 65432.123456 規整後: 65432.12

===== okx =====
伺服器時間: 2026-10-22T09:33:28.170Z 本機偏差(ms): -119
最新價: 81834.5 買一: 81834.4 賣一: 81834.5 24h 漲跌%: -2.13 24h 成交量: 7411.60789259
2026-10-22T07:00:00.000Z 82500.1 82543.3 82131.4 82249.9 669.1373
2026-10-22T08:00:00.000Z 82249.9 82278.4 81850.0 81861.2 445.3618
2026-10-22T09:00:00.000Z 81861.2 81940.0 81638.8 81834.5 214.3707
市場數量: 4578 交易所內部程式碼: BTC-USDT
價格步長: 0.1 數量步長: 1e-08
最小數量: 1e-05 最小金額: None
數量 0.123456789 規整後: 0.12345678
價格 65432.123456 規整後: 65432.1

fetch_ticker 和 fetch_ohlcv 返回了什麼?

fetch_ticker 返回一個字典,常用欄位有 last(最新成交價)、bid/ask(買一、賣一)、high/low(24 小時最高最低)、baseVolume(24 小時成交量,單位是 BTC)、percentage(24 小時漲跌幅)。fetch_ohlcv 返回列表,每一項依次是 K 線開盤時間(毫秒時間戳)、開、高、低、收、成交量,最後一根是還沒走完的當前 K 線。時間週期寫 1m、5m、1h、1d 等,limit 控制根數。

本機偏差那一行也值得留意:簽名請求帶時間戳,幣安預設只接受 5 秒內的請求,歐易超過 30 秒會拒絕。偏差在幾百毫秒內很正常,如果差了好幾秒,先開啟電腦的自動對時。

fetch_order_book:怎麼看買賣盤深度?

想知道當前價位掛了多少單,用 fetch_order_book。下面的程式碼取買賣盤前 3 檔,並順便演示交易對寫錯時的異常:

import ccxt

binance = ccxt.binance({"options": {"fetchMarkets": {"types": ["spot"]}}})
okx = ccxt.okx()

for ex in (binance, okx):
    ob = ex.fetch_order_book("BTC/USDT", limit=5)
    asks = [row[:2] for row in ob["asks"][:3]]  # 每檔只取 [價格, 數量]
    bids = [row[:2] for row in ob["bids"][:3]]
    print(ex.id, "賣盤:", asks)
    print(ex.id, "買盤:", bids)
    print(ex.id, "買賣價差:", round(asks[0][0] - bids[0][0], 2))

try:
    binance.fetch_ticker("BTC/USDC.X")  # 故意寫一個不存在的交易對
except ccxt.BadSymbol as e:
    print("BadSymbol:", e)

執行時輸出:

binance 賣盤: [[81791.5, 0.13627], [81791.51, 0.00042], [81791.69, 7e-05]]
binance 買盤: [[81791.49, 11.21318], [81791.25, 0.04184], [81791.24, 2.06615]]
binance 買賣價差: 0.01
okx 賣盤: [[81796.8, 1.38093972], [81797.7, 0.21551712], [81798.0, 1.02e-05]]
okx 買盤: [[81796.7, 1.0170818], [81796.6, 0.04428254], [81796.3, 0.15659987]]
okx 買賣價差: 0.1
BadSymbol: binance does not have market symbol BTC/USDC.X

賣盤按價格從低到高排,買盤從高到低排,第一檔就是賣一和買一。BTC/USDT 這種主流交易對的價差只有一個價格步長;小幣種的價差和每檔數量可能差很多,市價單滑點也會更大。歐易返回的每檔資料比幣安多一個欄位,所以程式碼裡用 row[:2] 只取價格和數量,兩家的處理方式就一致了。

為什麼下單前一定要看精度和最小下單量?

交易所對每個交易對都規定了價格步長、數量步長和最小下單量,不符合就會被拒單。從上面的輸出整理成表:

規則 幣安 BTC/USDT 歐易 BTC/USDT
價格步長 0.01 0.1
數量步長 0.00001 BTC 0.00000001 BTC
最小數量 0.00001 BTC 0.00001 BTC
最小金額 5 USDT 介面未返回(以數量限制為準)

另外,幣安現貨還有 PERCENT_PRICE_BY_SIDE 規則:執行時 BTCUSDT 的買單價格不能低於近 5 分鐘均價的 50%,否則報價格過濾失敗。所以測試掛單時,價格「遠離市價」也要有個度。

amount_to_precision 和 price_to_precision 會按步長規整數字,數量是向下截斷而不是四捨五入:0.123456789 在幣安變成 0.12345。截斷後金額可能掉到最小金額以下,計算數量時要留一點餘量。各種訂單類型的區別見 限價單、市價單與止盈止損。

私有介面要準備什麼?

查餘額、下單、撤單需要 API Key。申請方法和權限設定分別見 幣安 API Key 申請教程 和 歐易 API 建立教程,核心原則只有三條:只開讀取和現貨交易、不開提現、繫結 IP。

Key 不要寫進程式碼,用環境變數傳入:

# macOS / Linux:只在當前終端視窗有效
export BINANCE_API_KEY="你的幣安測試網 API Key"
export BINANCE_API_SECRET="你的幣安測試網 Secret Key"
export OKX_API_KEY="你的歐易模擬盤 API Key"
export OKX_API_SECRET="你的歐易模擬盤 Secret Key"
export OKX_API_PASSPHRASE="你的歐易模擬盤 Passphrase"

Windows PowerShell 寫成 $env:BINANCE_API_KEY="..."。不要把帶 Key 的命令儲存進指令碼檔案再上傳到程式碼倉庫。

環境變數只在當前終端視窗有效,關掉就沒了。長期使用時,可以把這幾行放進一個只有你自己能讀的本地配置檔案,在執行前載入;如果專案用 Git 管理,記得把這個檔案加進 .gitignore。私有介面的權限也要對得上:只查餘額,讀取權限就夠;要跑下面的掛單和撤單指令碼,測試網 Key 需要同時有讀取和現貨交易權限。

CCXT 怎麼切換到幣安測試網和歐易模擬盤?

截至 CCXT 4.5.89,兩家交易所的切換方式如下(均已實測):

寫法 效果
幣安 set_sandbox_mode(True) 請求地址換成 testnet.binance.vision,只能用現貨 /api 介面
幣安 enable_demo_trading(True) 請求地址換成 demo-api.binance.com,對應幣安網頁版模擬交易
歐易 set_sandbox_mode(True) 域名不變,所有請求自動加上 x-simulated-trading: 1

幣安的兩種模式不能同時開啟,實測先開 sandbox 再開 demo 會丟擲 NotSupported。另外,歐易模擬盤有獨立的訂單簿,價格和實盤不同,不要用模擬盤行情做判斷。

完整指令碼:查餘額、掛單、查掛單、撤單

下面的指令碼流程是:查 USDT 餘額 → 按市價的 70% 計算一個不會成交的限價買單 → 下單 → 查當前掛單 → 立即撤單。儲存為 trade_demo.py,執行 python trade_demo.py binance 或 python trade_demo.py okx:

import os
import sys
import time

import ccxt

USE_TESTNET = True      # 先在幣安現貨測試網 / 歐易模擬盤跑通,再考慮改成 False
SYMBOL = "BTC/USDT"


def make_exchange(name):
    if name == "binance":
        ex = ccxt.binance({
            "apiKey": os.environ["BINANCE_API_KEY"],
            "secret": os.environ["BINANCE_API_SECRET"],
            "enableRateLimit": True,
            "options": {"defaultType": "spot", "fetchMarkets": {"types": ["spot"]}},
        })
    elif name == "okx":
        ex = ccxt.okx({
            "apiKey": os.environ["OKX_API_KEY"],
            "secret": os.environ["OKX_API_SECRET"],
            "password": os.environ["OKX_API_PASSPHRASE"],  # 歐易的 Passphrase 填在 password
            "enableRateLimit": True,
        })
    else:
        raise ValueError("只支援 binance 或 okx")
    if USE_TESTNET:
        ex.set_sandbox_mode(True)  # 幣安→testnet.binance.vision;歐易→加請求頭 x-simulated-trading: 1
    return ex


RETRYABLE = (ccxt.RequestTimeout, ccxt.ExchangeNotAvailable, ccxt.RateLimitExceeded, ccxt.DDoSProtection)


def with_retry(fn, *args, retries=3, **kwargs):
    """只用於查詢類請求:網路抖動或限頻時等待後重試。"""
    for i in range(retries):
        try:
            return fn(*args, **kwargs)
        except RETRYABLE as e:
            wait = 2 ** i
            print(f"{type(e).__name__},{wait} 秒後重試……")
            time.sleep(wait)
    return fn(*args, **kwargs)


def main(name):
    ex = make_exchange(name)
    with_retry(ex.load_markets)
    market = ex.market(SYMBOL)

    # 1. 查餘額
    balance = with_retry(ex.fetch_balance)
    usdt = balance.get("USDT", {})
    print("USDT 可用:", usdt.get("free"), "凍結:", usdt.get("used"))

    # 2. 算一個遠低於市價、不會成交的限價買單
    last = with_retry(ex.fetch_ticker, SYMBOL)["last"]
    price = float(ex.price_to_precision(SYMBOL, last * 0.7))
    min_cost = market["limits"]["cost"]["min"] or 5
    amount = max(market["limits"]["amount"]["min"], min_cost * 1.2 / price)
    amount = float(ex.amount_to_precision(SYMBOL, amount))
    print(f"準備掛單:買入 {amount} BTC,價格 {price}(市價約 {last})")

    # 3. 下單:不自動重試,避免網路超時後重複下單
    order = ex.create_limit_buy_order(SYMBOL, amount, price)
    print("下單成功,訂單號:", order["id"], "狀態:", order["status"])

    try:
        # 4. 查當前掛單
        open_orders = with_retry(ex.fetch_open_orders, SYMBOL)
        print("當前掛單:", [(o["id"], o["price"], o["amount"]) for o in open_orders])
    finally:
        # 5. 無論如何都撤掉剛才的訂單
        ex.cancel_order(order["id"], SYMBOL)
        print("已撤單:", order["id"])


if __name__ == "__main__":
    name = sys.argv[1] if len(sys.argv) > 1 else "binance"
    try:
        main(name)
    except KeyError as e:
        print("缺少環境變數:", e)
    except ccxt.AuthenticationError as e:
        print("認證失敗:檢查 Key/Secret/Passphrase、IP 白名單、權限,以及是不是用了實盤 Key 連測試環境。", e)
    except ccxt.InsufficientFunds as e:
        print("餘額不足:", e)
    except ccxt.InvalidOrder as e:
        print("訂單引數不符合交易對規則(價格、數量、最小金額):", e)
    except ccxt.NetworkError as e:
        print("網路問題,稍後再試:", e)
    except ccxt.ExchangeError as e:
        print("交易所返回錯誤:", e)

這個指令碼我們測到了哪一步?

查餘額、下單這些私有介面需要你自己的測試網 Key。下面是 2026 年 10 月用這段程式碼實際執行的結果:

  • 沒設環境變數時輸出 缺少環境變數: 'BINANCE_API_KEY'。
  • 用假 Key 連幣安測試網,異常被正確捕獲:認證失敗:…… binance {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."}。
  • 用假 Key 連歐易模擬盤:認證失敗:…… okx {"msg":"Invalid OK-ACCESS-KEY","code":"50111"}。
  • 掛單引數計算(攔截請求、不實際傳送):幣安算出價格 57281.01、數量 0.0001、金額約 5.73 USDT,滿足 5 USDT 最小金額;歐易算出價格 57849.3、數量 0.00010371。CCXT 實際發往幣安測試網的是 POST /api/v3/order,發往歐易的是 POST /api/v5/trade/batch-orders,訂單模式為現貨 cash。

換成你自己的測試網 Key 後,正常會依次列印餘額、掛單引數、訂單號、當前掛單列表和「已撤單」。

兩個細節:一是 CCXT 預設會在訂單的自定義訂單號里加上自己的標識字首(幣安是 x- 開頭的 newClientOrderId,歐易是 clOrdId 和 tag),想用自己的訂單號,可以在下單時通過 params 傳入 newClientOrderId 或 clOrdId;二是 CCXT 對幣安預設使用 10000 毫秒的 recvWindow,比幣安文件預設的 5000 毫秒寬鬆。

新手用 CCXT 最常遇到哪些問題?

現象 原因 解決辦法
BadSymbol: ... does not have market symbol 交易對寫錯,或該交易所沒有這個交易對 用 BTC/USDT 這種統一寫法,先 load_markets() 再查 ex.symbols
幣安 load_markets 很慢 默認同時載入現貨、U 本位和幣本位合約市場 實測預設載入 4697 個市場用時約 1.6 秒,只加載現貨是 3736 個、約 0.5 秒
歐易提示缺少 password 沒傳 Passphrase 在 password 引數裡填 Passphrase
測試網能查行情,查餘額報 -2015 用了實盤 Key,或測試網 Key 已隨重置失效 到 testnet.binance.vision 重新生成 Key
訂單狀態一直是 open 限價單價格沒到,正常掛單中 用 fetch_order 查詢,或 cancel_order 撤單

訂單的 status 欄位在 CCXT 裡統一為幾種取值:open 表示還在掛單,closed 表示全部成交,canceled 表示已撤單。部分成交的訂單仍然是 open,可以看 filled(已成交數量)和 remaining(剩餘數量)兩個欄位判斷進度。

CCXT 異常怎麼處理?哪些錯誤可以重試?

CCXT 把各交易所的錯誤碼對映成統一的異常類,大致分兩類:

異常 含義 能否重試
RequestTimeout、ExchangeNotAvailable 超時、交易所暫時不可用 查詢可以,下單要先確認
RateLimitExceeded、DDoSProtection 請求太快 等待後重試
InvalidNonce 時間戳過期,例如歐易 50102 對時後重試
AuthenticationError Key、簽名、Passphrase、IP 有問題,例如幣安 -2015、歐易 50113 不要重試,先修配置
InsufficientFunds 餘額不足,例如歐易 51008 不要重試
InvalidOrder 訂單引數違規,例如幣安 -2010、歐易 51020 不要重試,改引數

前三類在 CCXT 裡都屬於 NetworkError,後三類屬於 ExchangeError。下單請求超時並不代表沒下成功:請求可能已經到達交易所,只是響應沒回來。如果這時盲目重發,可能掛出兩筆一樣的訂單。穩妥的做法是:下單時傳入自己生成的訂單號,超時後先用 fetch_open_orders 查一下這筆訂單在不在,再決定是否補單。

常見問題

CCXT 連線歐易為什麼提示缺少 password?

歐易的 API 除了 API Key 和 Secret Key,還需要建立 Key 時你自己設定的 Passphrase。在 CCXT 裡 Passphrase 填在 password 引數中,不傳或填錯就無法呼叫餘額、下單等私有介面,歐易會返回 50104 或 50105。

CCXT 查行情需要 API Key 嗎?

不需要。fetch_ticker、fetch_ohlcv、fetch_order_book、load_markets 這些行情類方法呼叫的都是交易所公開介面,直接建立 ccxt.binance() 或 ccxt.okx() 例項就能用。只有查餘額、下單、撤單等私有接口才需要 Key。

CCXT 下單報 InvalidOrder 怎麼辦?

InvalidOrder 通常是訂單引數不符合交易對規則,例如價格步長不對、數量低於最小值、下單金額低於最小金額,或限價偏離市價太多。先用 load_markets 讀出精度和限制,再用 amount_to_precision 和 price_to_precision 規整。

CCXT 支援幣安測試網和歐易模擬盤嗎?

支援。截至 CCXT 4.5.89,對幣安呼叫 set_sandbox_mode(True) 會切到現貨測試網,enable_demo_trading(True) 會切到幣安模擬交易;對歐易呼叫 set_sandbox_mode(True) 會自動加上 x-simulated-trading: 1 請求頭。三者都要配合對應環境的專用 Key。

CCXT 的 enableRateLimit 有什麼用?

開啟後,CCXT 會按交易所的限頻規則在請求之間自動等待,避免請求過快被拒絕或封禁 IP。新版 CCXT 預設就是開啟狀態,程式碼裡寫上可以讓意圖更清楚。

準備好出發了嗎?

幣安邀請
幣安

全球交易量最大的加密貨幣交易所之一,幣種與流動性領先

邀請碼
註冊幣安 ↗含推廣連結 · 註冊前請確認當地法規 · 幣安評測
歐易邀請
歐易

老牌頭部交易所,App 體驗與 Web3 錢包整合出色

邀請碼
註冊歐易 ↗含推廣連結 · 註冊前請確認當地法規 · 歐易評測

參考來源

  1. CCXT 官方文件(Manual)
  2. Binance Spot API 文件:Filters(PRICE_FILTER、LOT_SIZE、NOTIONAL)
  3. Binance Spot Test Network
  4. OKX API v5 文件:Demo Trading Services

以上資訊核實於 2026-10-22,交易所規則可能調整,請以官方最新說明為準。

本文僅供學習參考,不構成投資建議。交易所的費率、活動與功能可能隨時調整,請以官方頁面為準。文中部分連結為推廣連結,詳見推廣披露。