第 9 章 · 01 交易所适配与 ccxt


文档摘要

第 9 章 · 01 交易所适配与 ccxt 本节摘要:freqtrade 支持几十个交易所,底层靠 ccxt 这个统一封装库抹平各交易所 API 的差异,上层再用 类和每个交易所的独立子类( 、 、 等)做针对交易机器人的二次封装。本节讲清这套适配层的工作原理:ccxt 是什么、Exchange 类的核心职责(下单、行情、订单管理、 能力声明)、各交易所子类为什么要存在(处理特有行为和坑)、以及配置交易所时的常见要点(限流、key、止损上交易所)。读完你会理解 freqtrade 是怎么做到「一套策略跑遍几十个交易所」的。 内容来源:原项目文档 ,源码 及各子类,汉化并套用体系化模板。 ⚠️ 风险提示:不同交易所的限制、费率、地理封锁各不相同。

第 9 章 · 01 交易所适配与 ccxt

本节摘要:freqtrade 支持几十个交易所,底层靠 ccxt 这个统一封装库抹平各交易所 API 的差异,上层再用 Exchange 类和每个交易所的独立子类(binance.pybybit.pyokx.py 等)做针对交易机器人的二次封装。本节讲清这套适配层的工作原理:ccxt 是什么、Exchange 类的核心职责(下单、行情、订单管理、_ft_has 能力声明)、各交易所子类为什么要存在(处理特有行为和坑)、以及配置交易所时的常见要点(限流、key、止损上交易所)。读完你会理解 freqtrade 是怎么做到「一套策略跑遍几十个交易所」的。

内容来源:原项目文档 docs/exchanges.md,源码 freqtrade/exchange/exchange.py 及各子类,汉化并套用体系化模板。

⚠️ 风险提示:不同交易所的限制、费率、地理封锁各不相同。部署前务必阅读对应交易所的专属说明,确认你的服务器所在地不被封锁。

学习目标

阅读完本节,你应当能够:

  1. 说清 ccxt 的定位与 freqtrade 如何用它。
  2. 描述 Exchange 类的核心职责与 _ft_has 能力声明机制。
  3. 理解为什么每个交易所有独立子类
  4. 配置交易所的限流API key止损上交易所
  5. 知道主流交易所的特有坑(Binance 地理封锁、Kraken 历史 K 线、OKX 密码短语等)。

一、ccxt:抹平交易所差异的统一层

加密货币世界有上百个交易所,每个的 API 都不一样——下单参数名不同、返回格式不同、限流规则不同。ccxt 这个开源库把这些差异抽象成一套统一接口:不管哪个交易所,fetch_ohlcvcreate_orderfetch_balance 的调用方式都一样。

freqtrade 在 ccxt 之上再做一层封装(即 Exchange 类),原因有二:一是 ccxt 偶尔有 bug 或不准确的地方,需要针对交易机器人场景修正;二是交易机器人有特殊需求(止损上交易所、异步行情、订单簿定价等),需要统一处理。配置里只要写交易所名,freqtrade 就会自动实例化对应子类:

"exchange": { "name": "binance", "key": "your_exchange_key", "secret": "your_exchange_secret", "ccxt_config": {}, "ccxt_async_config": {} }

💡 ccxt 支持远不止 freqtrade 测试过的那些。freqtrade 官方测试覆盖 Binance、Bybit、OKX、Gate、Kraken 等,但 ccxt 支持 100+ 交易所。其他交易所大多能跑,但可能有边缘问题,社区会持续提交反馈和 PR。

二、Exchange 类:能力声明与核心职责

Exchange 类(freqtrade/exchange/exchange.py)是所有交易所子类的基类。它的一个关键设计是 _ft_has(freqtrade has)能力声明——用字典声明这个交易所支持哪些功能、有哪些限制:

class Exchange: _ft_has_default: FtHas = { "stoploss_on_exchange": False, # 是否支持止损单挂到交易所 "ohlcv_has_history": True, # 是否能拉历史 K 线 "tickers_have_quoteVolume": True, # ticker 是否含成交额 "trades_limit": 1000, # 单次拉成交的上限 "ccxt_futures_name": "swap", # ccxt 里合约的叫法 "ws_enabled": False, # 是否启用 websocket # ... 还有几十项 } _ft_has: FtHas = {} # 子类覆写自己的能力 _ft_has_futures: FtHas = {} # 合约模式下的额外覆写 _supported_trading_mode_margin_pairs = [ (TradingMode.SPOT, MarginMode.NONE), # 默认只支持现货 ]

每个子类通过覆写 _ft_has 来声明自己的特殊能力。比如 Binance 子类会声明 stoploss_on_exchange: True(支持止损上交易所),而 Kraken 子类会覆写 ohlcv_has_history: False(历史 K 线要从成交数据重建)。

构造函数里还读取 trading_modemargin_mode,决定是现货还是合约:

def __init__(self, config, ...): self._api: ccxt.Exchange # 同步接口 self._api_async: ccxt_pro.Exchange # 异步接口(行情订阅) self.trading_mode = TradingMode(config.get("trading_mode", TradingMode.SPOT)) self.margin_mode = MarginMode(config.get("margin_mode", MarginMode.NONE)) self.liquidation_buffer = config.get("liquidation_buffer", 0.05)

Exchange 类的核心职责:

  • 行情:拉 K 线(fetch_ohlcv)、ticker、订单簿。
  • 下单:市价、限价、止损单。
  • 账户:查余额、查持仓、查订单。
  • 风控:算强平价、算保证金、处理资金费率。
  • 数据清洗:处理各交易所返回格式的差异。

三、交易所子类:处理特有行为

打开 freqtrade/exchange/ 目录,每个主流交易所都有独立的 .py 文件:

exchange/ ├── exchange.py # 基类 ├── binance.py # 币安 ├── bybit.py # Bybit ├── okx.py # OKX ├── gate.py # Gate.io ├── kraken.py # Kraken ├── krakenfutures.py # Kraken 合约 ├── bingx.py # BingX ├── bitget.py # Bitget ├── htx.py # HTX(火兔) ├── hyperliquid.py # Hyperliquid(链上 DEX) ├── kucoin.py # Kucoin └── ...

子类要做的事:

  1. 覆写 _ft_has 声明能力(如是否支持止损上交易所、K 线历史、websocket)。
  2. 覆写 _supported_trading_mode_margin_pairs 声明支持哪些交易模式。
  3. 修正 ccxt 行为:覆写或扩展方法,处理 ccxt 不准确或缺失的部分。
  4. 处理特有限制:如 Kraken 的成交数据重建、Binance 的 BNFCR 模式。

💡 为什么不用 ccxt 原生就够了? 因为 ccxt 是通用库,不会为「交易机器人」做专门优化。比如止损上交易所、异步行情订阅、订单簿定价、强平价计算这些机器人刚需,ccxt 要么不支持要么各交易所不一致,freqtrade 的子类就是来填这些缝的。

四、配置要点:限流、key、止损

限流(rate limit) 是最容易踩的坑。ccxt 默认的限流通常靠谱,但遇到 DDOS 异常时可以手动调:

"exchange": { "name": "kraken", "key": "...", "secret": "...", "ccxt_config": {"enableRateLimit": true}, "ccxt_async_config": { "enableRateLimit": true, "rateLimit": 3100 // Kraken 建议 3.1 秒一次 } }

⚠️ rateLimit 单位是毫秒(延迟),不是每秒请求数。Kraken 报「Rate limit exceeded」时,要把这个值调大而不是调小。最优值取决于交易所和白名单大小。

API key 与密码短语:大多数交易所只要 keysecret,但 Kucoin 和 OKX 还要 password(API 密钥的密码短语):

"exchange": { "name": "okx", "key": "...", "secret": "...", "password": "your_api_key_passphrase" }

💡 Binance RSA 密钥:Binance 支持 RSA 格式 API 密钥。推荐用环境变量传入,避免 JSON 里处理换行符的麻烦:
export FREQTRADE__EXCHANGE__SECRET="$(cat ./rsa_binance.private)"

止损上交易所(stoploss_on_exchange):把止损单直接挂到交易所,而不是靠机器人轮询触发。好处是即使机器人掉线,止损也会执行。配置在 order_types.stoploss:

"order_types": { "stoploss": "limit", // 或 "market" "stoploss_on_exchange": true }

各交易所支持的止损类型不同——Binance 现货用 stop-loss-limit、合约支持 stop-limitstop-market;Kraken 支持 stop-loss-marketstop-loss-limit

五、主流交易所的特有坑

交易所 关键坑与要点
Binance 地理封锁(加拿大、马来西亚、荷兰、美国);分 binance(国际)和 binanceus(美国)两个 ID;合约需设「单向仓位」「单资产模式」;建议黑名单加 BNB 避免手续费扣币导致卖不掉;合约必须用订单簿定价
Kraken API 只给 720 根历史 K 线,回测必须用 --dl-trades 下成交数据再重建;下载极耗内存和时间;rateLimit 是毫秒延迟
OKX API key 要密码短语;每次只返回 100 根 K 线(回测数据偏少);合约有「仓位模式」(买卖/对冲),建议用买卖模式,不能交易中途切换;my.okx.com 注册的要用 myokx 作为交易所名
Kucoin API key 要密码短语;建议黑名单加 KCS(同 BNB 道理)
Gate.io API key 需「现货交易」或「永续合约」+「钱包(只读)」+「账户(只读)」权限;支持用 POINT 付手续费需配 unknown_fee_rate
Hyperliquid 链上 DEX,适配层覆盖 CEX 和链上

⚠️ 多 bot 同账户:合约/保证金模式下,不能在同一账户跑两个 bot。freqtrade 假设自己是账户唯一使用者,强平价计算基于此假设。

六、止损上交易所与强平保护

合约模式下,止损和强平的关系需要特别关注。freqtrade 不会自动追踪强平手续费,所以用 liquidation_buffer(默认 0.05)在真实强平价和止损价之间留缓冲:

freqtrade强平价 = 强平价 ± |开仓价 - 强平价| × liquidation_buffer (+ 做多,- 做空)

⚠️ liquidation_buffer 设 0 或太低会真的被强平,而 freqtrade 不追踪强平手续费,导致盈亏统计不准。建议配合 stoploss_on_exchange 使用,且别把 buffer 设太低。

本节要点回顾

  1. ccxt 定位:开源库,统一封装 100+ 交易所的 API 差异;freqtrade 在其上再做一层针对交易机器人的封装。
  2. Exchange 类:基类用 _ft_has 字典声明能力(止损上交易所、K 线历史、websocket 等),子类覆写;构造时读 trading_mode/margin_mode
  3. 子类存在意义:覆写能力声明、修正 ccxt 行为、处理特有限制(Kraken 重建 K 线、Binance BNFCR 等)。
  4. 配置要点:rateLimit 单位是毫秒延迟(Kraken 报错要调大);OKX/Kucoin 要密码短语;止损上交易所靠 order_types.stoploss + stoploss_on_exchange
  5. 交易所特有坑:Binance 地理封锁+双 ID、Kraken 必须下成交数据、OKX 仓位模式不能中途换、合约不能同账户多 bot。
  6. 强平保护:liquidation_buffer(默认 0.05)在强平价和止损间留缓冲;设太低会被真强平且统计不准。

下一节,我们深入现货与合约杠杆——trading_modemargin_mode(isolated/cross)、leverage 回调、强平机制。


发布者: 作者: 灏天文库 转发
评论区 (0)
U