nautilus-kraken 适配器实战:用 NautilusTrader 对接 Kraken Spot 与 Futures 双市场
【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader
导读
本文讲解 NautilusTrader 仓库中nautilus-krakencrate 的核心设计与实战用法:它针对 Kraken 交易所同时提供 Spot(REST v2 / WebSocket v2)与 Futures(Derivatives v3)两套相互独立的客户端,覆盖 Instrument、Ticker、Trade、Orderbook、OHLC 数据流,并已为执行(下单、持仓、余额)预留了客户端骨架。读完本文,你将掌握该适配器的架构取舍、客户端类型、符号映射规则、特性开关、配置参数以及开箱即用的示例运行方式,并了解底层源码中 URL 构建、限流配额与配置校验的实现细节。
1. 适配器定位:nautilus-kraken 是什么
nautilus-kraken是 NautilusTrader 生态中对接 Kraken 中描述为:
"Kraken Pro exchange integration adapter for the Nautilus trading engine"
从 crates/adapters/kraken/src/lib.rs 的 crate 级文档可以看到它的功能边界:
- REST API v2 客户端:用于行情数据与账户操作;
- WebSocket v2 客户端:用于实时数据推送;
- 同时支持 Spot 与 Futures 市场;
- 覆盖 Instrument、Ticker、Trade、Orderbook、OHLC 数据;
- 已为执行(orders、positions、balances)做好准备(当前状态为 WIP,即尚未完全开放)。
值得强调的是,该 crate 面向的是Kraken Pro(即 Kraken 的 API 交易平台)接口,遵循官方Kraken API v2规范。适配器与整个 NautilusTrader 引擎共享同一套事件驱动架构:行情数据经由数据客户端流入引擎的消息总线,回测与实盘语义一致,实现 research-to-live 的对齐。
从 crates/adapters/kraken/src/lib.rs 的模块划分看,适配器内部按职责分为:
| 模块 | 职责 |
|---|---|
common | 常量、URL 构建、凭据、枚举与序列化辅助 |
config | 数据/执行客户端配置类型 |
http | Spot 与 Futures 的 HTTP 客户端(含 Raw 原始客户端) |
websocket | Spot v2(含 L3 盘口)与 Futures 的 WebSocket 客户端 |
data | 数据客户端(DataClient 实现) |
execution | 执行客户端(ExecutionClient 实现) |
factories | 客户端工厂 |
python(可选) | PyO3 Python 绑定 |
2. 为什么 Spot 与 Futures 要分成两套客户端
Kraken 的 Spot 与 Futures 在历史上是两个独立平台:Kraken Futures 前身是 Crypto Facilities,被 Kraken 收购后 API 依然各自独立,并未统一。因此适配器分别为 Spot 和 Futures 提供独立的 HTTP 与 WebSocket 客户端,这一设计在 crates/adapters/kraken/README.md 中有明确对比:
| 方面 | Spot | Futures |
|---|---|---|
| API 版本 | REST API v2 | Derivatives API v3 |
| Base URL | api.kraken.com | futures.kraken.com |
| 认证头 | API-Key、API-Sign | APIKey、Authent、Nonce |
| 请求格式 | URL-encoded form | JSON body |
| WebSocket | v2 协议 | Futures 专属协议 |
在源码 crates/adapters/kraken/src/common/urls.rs 中,这些差异被固化为显式的 URL 构建函数,按(product_type, environment)组合返回对应地址。底层常量定义于 crates/adapters/kraken/src/common/consts.rs:
// Spot API URLs (v2) pub const KRAKEN_SPOT_HTTP_URL: &str = "https://api.kraken.com"; pub const KRAKEN_SPOT_WS_PUBLIC_URL: &str = "wss://ws.kraken.com/v2"; pub const KRAKEN_SPOT_WS_PRIVATE_URL: &str = "wss://ws-auth.kraken.com/v2"; pub const KRAKEN_SPOT_WS_L3_URL: &str = "wss://ws-l3.kraken.com/v2"; // Futures API URLs pub const KRAKEN_FUTURES_HTTP_URL: &str = "https://futures.kraken.com"; pub const KRAKEN_FUTURES_WS_URL: &str = "wss://futures.kraken.com/ws/v1"; // Demo URLs(仅 Futures 提供) pub const KRAKEN_FUTURES_DEMO_HTTP_URL: &str = "https://demo-futures.kraken.com"; pub const KRAKEN_FUTURES_DEMO_WS_URL: &str = "wss://demo-futures.kraken.com/ws/v1";2.1 一个关键约束:Spot 不支持 Demo 环境
虽然KrakenEnvironment枚举(定义于 crates/adapters/kraken/src/common/enums.rs)同时提供Live与Demo两个取值,但Kraken Spot 并没有 Demo 环境,只有 Futures 提供demo-futures.kraken.com。这一约束体现在两处:
get_kraken_http_base_url/get_kraken_ws_public_url等函数在收到(Spot, Demo)组合时直接panic!("Kraken Spot does not support the demo environment");- 配置类型的
validate()方法(见 crates/adapters/kraken/src/config.rs)会执行同样的校验并返回错误。
2.2 客户端类型总览
适配器对外暴露四种核心客户端,均可在 crates/adapters/kraken/src/lib.rs 的pub use中找到:
KrakenSpotHttpClient/KrakenSpotWebSocketClient:面向现货交易对,例如BTC/USD、ETH/EUR;KrakenFuturesHttpClient/KrakenFuturesWebSocketClient:面向永续与固定到期合约,例如PF_XBTUSD、PI_ETHUSD。
此外还有两组 Raw 原始客户端(KrakenSpotRawHttpClient、KrakenFuturesRawHttpClient),它们直接返回 Kraken 的原始 JSON 响应,适合快速调试与自定义解析。
3. 符号格式:Spot 用 BTC,Futures 用 XBT
Kraken 在 Spot 与 Futures 两个平台上对同一标的采用了不同的符号写法,适配器在 crates/adapters/kraken/README.md 中给出了规范:
| 市场 | 格式 | 示例 | 说明 |
|---|---|---|---|
| Spot | BTC | BTC/USD | XBT 被归一化为 BTC(无论出现在 base 还是 quote 位置) |
| Futures | XBT | PI_XBTUSD | 使用 Kraken 原生的 XBT 格式 |
在源码层面,crates/adapters/kraken/src/common/enums.rs 提供了product_type_from_symbol函数,通过前缀判断一个符号属于哪个市场:
/// - `PI_` - Perpetual Inverse futures (e.g., `PI_XBTUSD`) /// - `PF_` - Perpetual Fixed-margin futures (e.g., `PF_XBTUSD`) /// - `PV_` - Perpetual Vanilla futures (e.g., `PV_XRPXBT`) /// - `FI_` - Fixed maturity Inverse futures (e.g., `FI_XBTUSD_230929`) /// - `FF_` - Flex futures /// /// All other symbols are considered spot. pub fn product_type_from_symbol(symbol: &str) -> KrakenProductType { if symbol.starts_with("PI_") || symbol.starts_with("PF_") || symbol.starts_with("PV_") || symbol.starts_with("FI_") || symbol.starts_with("FF_") { KrakenProductType::Futures } else { KrakenProductType::Spot } }配套的KrakenInstrumentType枚举区分了FuturesInverse(反向永续,如PI_XBTUSD)与FlexibleFutures(线性/灵活永续,如PF_XBTUSD)。同一文件中还定义了大量与 Kraken 报文一一对应的枚举(订单类型、订单状态、成交分类、触发信号等),并通过From实现双向映射到 Nautilus 领域模型,例如KrakenOrderType::StopLoss => OrderType::StopMarket。需要留意的是,trailing 类订单在重建(reconciliation)时会被映射为非 trailing 等价类型,因为 Kraken 的回报中缺少重建 trailing 订单所需的偏移字段。
4. 快速上手:三个开箱即用的示例
适配器的[[bin]]目标在 crates/adapters/kraken/Cargo.toml 中声明,运行时不需要额外启用 feature:
cargo run --bin kraken-http-spot-raw cargo run --bin kraken-http-spot-public cargo run --bin kraken-ws-spot-data4.1kraken-http-spot-raw:验证连接与公共端点
源码位于 crates/adapters/kraken/bin/http_spot_raw.rs,它使用KrakenSpotRawHttpClient依次调用公共接口:
get_server_time():获取服务器时间;get_system_status():获取系统状态;get_asset_pairs(Some(vec!["XBTUSDT"]), None):查询交易对信息;get_ticker(vec!["XBTUSDT"], None):获取行情。
这是最快验证网络连通性与 API 可用性的方式,全程无需 API 密钥。
4.2kraken-http-spot-public:公共数据方法骨架
源码位于 crates/adapters/kraken/bin/http_spot_public.rs,创建默认的KrakenSpotHttpClient实例。当前该示例仅验证客户端可创建,request_instruments、request_bars、request_trades等方法标注为 TODO,这些方法将负责把 Kraken 响应解析为 Nautilus 领域类型——与适配器整体"数据客户端已完成、执行客户端 WIP"的状态一致。
4.3kraken-ws-spot-data:实时订阅行情流
源码位于 crates/adapters/kraken/bin/ws_spot_data.rs,它演示了完整的 WebSocket 数据流链路:
let config = KrakenDataClientConfig::default(); let token = CancellationToken::new(); let mut client = KrakenSpotWebSocketClient::new(config, token.clone(), None); client.connect().await?; client .subscribe(KrakenWsChannel::Ticker, vec![Ustr::from("BTC/USD")], None) .await?; client .subscribe(KrakenWsChannel::Trade, vec![Ustr::from("BTC/USD")], None) .await?; let stream = client.stream()?; // ... tokio::select! 循环消费消息,Ctrl+C 触发 disconnect示例中通过KrakenWsChannel::Ticker/KrakenWsChannel::Trade订阅BTC/USD的实时行情,配合tokio::select!在收到 Ctrl+C 时优雅断开连接。
4.4 进阶示例与基准
除bin/下的三个示例外,Cargo.toml 还声明了需要examplesfeature 的示例程序(路径均已确认存在于 crates/adapters/kraken/examples 目录):
cargo run -p nautilus-kraken --example kraken-data-tester --features examples cargo run -p nautilus-kraken --example kraken-exec-tester --features examples cargo run -p nautilus-kraken --features examples --example kraken-hurst-vpin-backtest --release cargo run -p nautilus-kraken --features examples --example kraken-hurst-vpin-live其中kraken-hurst-vpin-backtest与kraken-hurst-vpin-live对应仓库教程 docs/tutorials/hurst_vpin_kraken.md 中基于 Hurst 指数与 VPIN 因子的 Kraken 策略示例,可以分别跑回测与实盘。此外还提供了 WebSocket 解析基准(cargo bench -p nautilus-kraken --bench websocket),用于评估消息解析吞吐。
5. 特性开关(Feature Flags)
nautilus-kraken通过 Cargo feature 控制编译期包含的代码,完整定义见 crates/adapters/kraken/Cargo.toml:
| Feature | 默认 | 作用 |
|---|---|---|
high-precision | ✅ 默认开启 | 启用 128 位值类型(high-precision mode)。Futures 场景务必保持默认,因为 Kraken 返回的合约精度可能超过标准精度模式下九位小数的上限 |
examples | ❌ | 启用示例程序(引入nautilus-backtest、nautilus-tardis等依赖与 node 支持) |
python | ❌ | 启用基于 PyO3 的 Python 绑定 |
extension-module | ❌ | 以 Python 扩展模块形式构建(隐式包含python) |
各开关的依赖关系(如python会级联开启nautilus-common/python、nautilus-live/python、pyo3、pyo3-stub-gen等)同样定义在 Cargo.toml 的[features]段中。docs.rs元数据也指定了["examples", "high-precision"]作为文档构建特性。
6. 配置详解:数据客户端与执行客户端
适配器的两类配置类型定义于 crates/adapters/kraken/src/config.rs,均支持serde(JSON/TOML)反序列化与bon::Builder构建器,并且都带deny_unknown_fields,因此配置拼写错误会直接报错而非静默忽略。
6.1KrakenDataClientConfig
| 字段 | 默认值 | 说明 |
|---|---|---|
api_key/api_secret | None | 数据客户端的可选 API 凭据(SecretString类型,Debug 输出自动脱敏) |
product_type | Spot | Spot或Futures |
environment | Live | Live或Demo(Spot 不支持 Demo) |
base_url/ws_public_url/ws_private_url | None(自动推导) | 覆盖默认端点地址 |
ws_l3_url | wss://ws-l3.kraken.com/v2 | L3 盘口 WebSocket 地址覆盖 |
validate_l3_checksum | true | 对每个 L3 更新校验 Kraken 的 CRC32 校验和 |
proxy_url | None | HTTP 与 WebSocket 传输的可选代理 |
timeout_secs | 30 | HTTP 超时(秒) |
heartbeat_interval_secs | 30 | 心跳间隔(秒) |
ws_idle_timeout_ms | 10_000 | Spot v2 WebSocket 空闲超时(毫秒);0表示禁用 |
max_requests_per_second | None | 每秒最大请求数 |
transport_backend | 默认 | 底层 WebSocket 传输后端 |
其中ws_idle_timeout_ms的实现注释非常值得关注:当订阅被后端确认但数据扇出未真正挂上时,连接会"看似活着"(无 close 帧、无传输错误),普通机制无法察觉。该超时一旦在窗口内收不到任何应用数据帧(文本或二进制)就判定连接死亡并自动重连、重订阅。Kraken 在存在至少一个订阅时每秒发送一次heartbeat文本帧,因此正常订阅连接会不断重置计时器;而 keepaliveping得到的pong也是文本帧,同样会重置计时器。如果连接没有任何订阅,应将此值设为0或调高到heartbeat_interval_secs之上,避免误杀。
6.2KrakenExecutionClientConfig
执行客户端配置(当前执行功能为 WIP)除account_id(默认KRAKEN-001)、api_key/api_secret、product_type、environment、URL 覆盖、timeout_secs、heartbeat_interval_secs、auth_timeout_secs(Futures 登录认证超时)、max_requests_per_second、max_retries(可重试 REST 请求的最大重试次数,默认3)、transport_backend等基础字段外,还包含 Spot 交易特有的字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
spot_account_type | Cash | Spot 账户类型:Cash或Margin。Margin时适配器调用TradeBalance做保证金报告、OpenPositions做持仓对账;单笔杠杆通过SubmitOrder.params["leverage"](u16 倍数)设置 |
default_leverage | None | Spot 保证金单的默认杠杆倍数,按"N:1"格式发送给 Kraken(如3→"3:1")。合法档位见AssetPairInfo.leverage_buy/leverage_sell。None表示现金单(不发送 leverage 字段)。Cash 账户下设置该值会校验失败 |
use_spot_position_reports | false | 是否基于 Spot 钱包余额生成PositionStatusReport。纯现货(现金)账户需要从余额快照跟踪持仓时设为true;保证金账户保持false(走OpenPositions对账) |
spot_positions_quote_currency | USDT | 合成现货持仓报告使用的计价货币(仅use_spot_position_reports=true时相关) |
margin_balance_asset | None | TradeBalance保证金汇总指标的计价资产(如ZUSD、ZGBP、ZEUR、USDT);None时 Kraken 默认ZUSD。仅影响展示,OpenPositions的逐仓数字仍以交易对的计价货币计 |
use_ws_trade | true | 下单/改单/撤单/批量下单是否优先走已认证的 WebSocket v2(连接不活跃时回退 REST);false则全部走 REST |
ws_request_timeout_secs | 5 | WebSocket 订单响应超时(秒),超时保留请求关联但不发出终结事件;submit_order/submit_order_list还会发送尽力而为的补偿性撤单 |
配置校验(validate())会拦截两类非法组合:(Spot, Demo)环境组合,以及default_leverage与Cash账户并存。配置文件中的tests模块(crates/adapters/kraken/src/config.rs 末尾)用rstest验证了凭据脱敏、默认值(use_ws_trade=true、ws_request_timeout_secs=5、max_retries=3、ws_idle_timeout_ms=10_000)以及 TOML 最小配置解析。
一个最小化的 TOML 数据客户端配置示例(与源码测试用例同构):
product_type = "spot" environment = "live" timeout_secs = 45 validate_l3_checksum = false7. 底层实现要点:限流、枚举映射与工厂
7.1 WebSocket 限流配额
Kraken 对 WebSocket 消息有严格的速率限制,适配器在 crates/adapters/kraken/src/common/consts.rs 中预置了保守配额:
- Futures WS:
90请求/秒(官方硬上限 100/秒,留出 10% 余量); - Spot WS 订阅:
20请求/秒、允许突发10(Spot 的动态消息速率限制未公开固定数值,超限时服务器返回{"Error": "Exceeded msg rate"}); - Spot WS 下单:
10请求/秒、允许突发10(与订阅共享连接级预算,撮合引擎另按交易对执行分档限速:Starter 60 / Intermediate 125 / Pro 180)。
7.2 枚举的双向映射
common/enums.rs 是适配器与 Kraken 报文之间的"翻译层":KrakenOrderType、KrakenOrderStatus、KrakenFuturesOrderType、KrakenFillType、KrakenPairStatus等枚举都实现了与 Nautilus 领域枚举的From转换(例如KrakenFillType::Maker => LiquiditySide::Maker,清算类成交映射为NoLiquiditySide),并覆盖了大量反序列化测试用例(见同文件mod tests与 crates/adapters/kraken/test_data 目录下的 70+ 个 JSON 样本)。
7.3 客户端工厂
factories.rs 提供KrakenDataClientFactory与KrakenExecutionClientFactory,实现 Nautilus 的DataClientFactory/ExecutionClientFactorytrait,让适配器客户端能以统一方式接入nautilus-live的节点生命周期。数据客户端(KrakenSpotDataClient/KrakenFuturesDataClient)与执行客户端(KrakenSpotExecutionClient/KrakenFuturesExecutionClient)的公开导出见 lib.rs。
8. 测试与集成资料
适配器自带完整的测试资产,便于验证与二次开发:
- 单元/集成测试:crates/adapters/kraken/tests 目录包含 12 个测试文件,覆盖 HTTP 客户端行为与 WebSocket 解析;
- 样本数据:crates/adapters/kraken/test_data 目录包含 70+ 个 JSON 样本,用于枚举反序列化、报文解析等测试;
- 性能基准:
benches/websocket.rs提供 WebSocket 消息处理基准。
Python 侧的用户可通过nautilus_trader.adapters.kraken模块(由pythonfeature 生成绑定,对应源码 crates/adapters/kraken/src/python)在 Python 中构造KrakenDataClientConfig/KrakenExecutionClientConfig并接入 live 节点。
9. 小结与注意事项
- 架构上:Spot 与 Futures 因历史原因 API 分裂,适配器尊重这一现实,提供四套独立客户端,切勿混用 URL 与认证方式;
- 符号上:Spot 用
BTC/USD风格(XBT 归一化为 BTC),Futures 用PI_XBTUSD风格(前缀PI_/PF_/PV_/FI_/FF_判定市场类型); - 配置上:Spot 不支持 Demo 环境;
default_leverage仅适用于 Margin 账户;无订阅的 WebSocket 连接应调整ws_idle_timeout_ms;Futures 场景务必保持high-precision特性默认开启; - 功能状态上:数据链路(HTTP + WebSocket + L3 盘口 + 校验和验证)已就绪,执行链路(下单/持仓/余额)处于 WIP 阶段,示例与配置已预先铺好,适合跟进仓库后续版本;
- 官方依据:Kraken 官方 API 参考文档(REST 与 WebSocket v2)是适配器字段映射与限流注释的直接依据,适配器源码中均有对应引用。
以上内容均以当前仓库 crates/adapters/kraken 下的 README、Cargo.toml 与源码为准,读者可以按文末列出的文件路径逐一核对与深入阅读。
【免费下载链接】nautilus_traderProduction-grade Rust-native trading engine with deterministic event-driven architecture项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考