第 10 章 · 01 IBrokerage 接口与 40+ 券商


文档摘要

第 10 章 · 01 IBrokerage 接口与 40+ 券商 本节摘要:本节钻取 Lean 对接层——它怎么把订单发到真实券商跑实盘。 (217 行)枚举了 40+ 家券商(InteractiveBrokers/Binance/BinanceUS/BinanceFutures/BinanceCoinFutures/Alpaca/Oanda/Bybit/Coinbase/TradeStation/CharlesSchwab/Tastytrade/Webull/Kraken/Tradier/TradingTechnologies/Zerodha/BloombergFix/TerminalLink/DYDX 等),而 (161

第 10 章 · 01 IBrokerage 接口与 40+ 券商

本节摘要:本节钻取 Lean 对接层——它怎么把订单发到真实券商跑实盘。Common/Brokerages/BrokerageName.cs(217 行)枚举了 40+ 家券商(InteractiveBrokers/Binance/BinanceUS/BinanceFutures/BinanceCoinFutures/Alpaca/Oanda/Bybit/Coinbase/TradeStation/CharlesSchwab/Tastytrade/Webull/Kraken/Tradier/TradingTechnologies/Zerodha/BloombergFix/TerminalLink/DYDX 等),而 Common/Interfaces/IBrokerage.cs(161 行)定义了所有券商必须实现的接口(下单/撤单/改单/查账户/查持仓/连接 + 五个事件)。本节最重要的区分:BrokerageName 枚举定义的是"券商模型"(手续费/滑点/保证金/可用订单类型/杠杆),用于回测模拟,与 IBrokerage(真实连接实盘)是两个概念。回测里 SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) 让模拟成交按 IB 的费率算;实盘里 IBrokerage 实例真正连 IB 服务器下单。两者都叫 brokerage,但职责完全不同。

内容来源:原项目源码 Common/Brokerages/BrokerageName.csCommon/Interfaces/IBrokerage.csLauncher/config.json,精读并套用体系化模板。

⚠️ 注意:Lean 的 brokerage 体系最容易让初学者混淆。看完本节务必记住:回测用 BrokerageModel(算费率)、实盘用 IBrokerage(真实下单),两者通过 BrokerageName 枚举联系起来,但是不同的类

学习目标

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

  1. 说清 BrokerageName 枚举的 40+ 券商分布,以及 GDAX=12 的特殊编号原因。
  2. 解释 IBrokerage 接口的 8 个方法 + 5 个事件(订单/账户/消息回调)。
  3. 区分 IBrokerageModel(手续费/滑点/保证金,回测用)与 IBrokerage(真实连接,实盘用)两个概念。
  4. 知道 SetBrokerageModel(BrokerageName.XXX) 的作用是"设置回测模拟的券商行为"。

一、BrokerageName:40+ 券商枚举

Common/Brokerages/BrokerageName.cs:23-216 是一个 40+ 项的枚举:

20 /// <summary> 21 /// Specifices what transaction model and submit/execution rules to use 22 /// </summary> 23 public enum BrokerageName 24 { 28 Default, 34 QuantConnectBrokerage = Default, 39 InteractiveBrokersBrokerage, 44 TradierBrokerage, 49 OandaBrokerage, 54 FxcmBrokerage, 59 Bitfinex, 64 Binance, 69 [Obsolete("GDAX brokerage name is deprecated. Use Coinbase instead.")] 70 GDAX = 12, 75 Alpaca, 80 AlphaStreams, 85 Zerodha, 90 Samco, 95 Atreyu, 100 TradingTechnologies, 105 Kraken, 110 FTX, 115 FTXUS, 120 Exante, 125 BinanceUS, 130 Wolverine, 135 TDAmeritrade, 140 BinanceFutures, 145 BinanceCoinFutures, 150 RBI, 155 Bybit, 160 Eze, 165 Axos, 170 Coinbase, 175 TradeStation, 180 TerminalLink, 185 CharlesSchwab, 190 Tastytrade, 195 InteractiveBrokersFix, 200 DYDX, 205 Webull, 210 Public, 215 BloombergFix 216 }

枚举的 XML 注释("Specifices what transaction model and submit/execution rules to use")已经点出用途——这个枚举决定交易模型和提交/执行规则。券商分类大致是:

  • 股票:InteractiveBrokers、Tradier、Alpaca、TradeStation、CharlesSchwab(原 TD Ameritrade)、Tastytrade、Webull、BloombergFix、TerminalLink(Bloomberg 终端)。
  • 加密货币:Binance(现货)、BinanceUS、BinanceFutures(USDT 合约)、BinanceCoinFutures(币本位合约)、Coinbase(原 GDAX)、Kraken、Bybit、Bitfinex、FTX(已倒闭但保留兼容)、DYDX。
  • 外汇:Oanda、Fxcm。
  • 期货:TradingTechnologies、Atreyu、Wolverine、RBI、Eze。
  • 印度市场:Zerodha、Samco。
  • 欧洲:Exante。

1.1 GDAX = 12 的特殊编号

L69-70 的注释和值很特别:

69 [Obsolete("GDAX brokerage name is deprecated. Use Coinbase instead.")] 70 GDAX = 12,

GDAX 是 Coinbase Pro 的前身,改名后用 Coinbase(L170)替代。但 GDAX 没被删除,而是标了 Obsolete显式赋值 = 12——因为如果不赋值,C# 会自动给 GDAX 分配下一个整数(此时为 8),这会改变后续所有枚举值的数字,破坏已经序列化存储的配置(JSON 里可能存了 7 代表原 Alpaca 位置)。显式 GDAX = 12 让 GDAX 占住数字 12,后续枚举自动从 13 继续,保证旧配置的数字语义不变。

💡 钻取要点:这是 C# 枚举序列化稳定性的经典坑。枚举的数字值一旦发布就是公开契约——它会出现在配置文件、数据库、网络协议里。删除或重排都会破坏向后兼容。Lean 的处理方式是:保留旧名 + Obsolete + 锁定数字值,新增用新名从锁定值之后继续。这种"枚举值不可变"的纪律,是大型项目维护的必备素养。

二、IBrokerage 接口:实盘真实连接

Common/Interfaces/IBrokerage.cs:29-160 是实盘连接的统一接口。所有具体券商(InteractiveBrokersBrokerage / BinanceBrokerage / ...)都实现它:

29 public interface IBrokerage : IBrokerageCashSynchronizer, IDisposable 30 { 34 event EventHandler<BrokerageOrderIdChangedEvent> OrderIdChanged; 39 event EventHandler<List<OrderEvent>> OrdersStatusChanged; // 订单状态变化(成交/取消/拒绝) 47 event EventHandler<OrderUpdateEvent> OrderUpdated; // 订单价格等更新 53 event EventHandler<OrderEvent> OptionPositionAssigned; // 期权被行权 57 event EventHandler<OptionNotificationEventArgs> OptionNotification; 68 event EventHandler<DelistingNotificationEventArgs> DelistingNotification; 73 event EventHandler<AccountEvent> AccountChanged; // 账户余额变化 78 event EventHandler<BrokerageMessageEvent> Message; // 券商消息/错误 83 string Name { get; } 88 bool IsConnected { get; } 94 List<Order> GetOpenOrders(); // 查所有未成交订单 100 List<Holding> GetAccountHoldings(); // 查账户持仓 106 List<CashAmount> GetCashBalance(); // 查账户现金余额 113 bool PlaceOrder(Order order); // 下单 120 bool UpdateOrder(Order order); // 改单 127 bool CancelOrder(Order order); // 撤单 132 void Connect(); // 连接券商服务器 137 void Disconnect(); // 断开 147 string AccountBaseCurrency { get; } // 账户基础货币 154 IEnumerable<BaseData> GetHistory(HistoryRequest request); // 历史数据 159 bool ConcurrencyEnabled { get; set; } // 并发消息处理开关 160 }

2.1 方法三组

连接组:Connect / Disconnect / IsConnected——管理底层网络/会话连接。连接通常是异步的(WebSocket / FIX / REST),Connect 返回后连接可能仍在握手,真正就绪由 Message 事件通知。

账户查询组:GetCashBalance / GetAccountHoldings / GetOpenOrders——查当前账户状态。实盘启动时 BrokerageSetupHandler 会调这些方法同步真实账户状态(现金、持仓、未成交订单)到 Algorithm.Portfolio,保证实盘从真实状态出发(而不是从零开始)。

下单组:PlaceOrder / UpdateOrder / CancelOrder——下单/改单/撤单。返回 bool 表示请求是否被券商接受(不代表成交)。真实成交由 OrdersStatusChanged 事件异步推送。

2.2 事件回调组(实盘核心)

事件驱动是实盘的灵魂——所有成交、账户变化、错误都是券商推送而非主动查询。五个关键事件:

  • OrdersStatusChanged:订单状态变化(已提交/部分成交/全部成交/已取消/已拒绝)。Lean 收到后产生 OrderEvent,走与回测完全相同的处理流程(第 8 章 Fill 模型 + 第 3 章 TransactionHandler)。
  • AccountChanged:账户现金/余额变化(如外汇利息、股息)。
  • Message:券商原始消息(连接成功、错误、警告)。Lean 把错误码映射成 BrokerageResponseEvent 决定是否重试。
  • OptionPositionAssigned:期权空头被行权通知。
  • DelistingNotification:标的退市通知。

💡 钻取要点:注意 IBrokerage 继承了 IBrokerageCashSynchronizer——这是 Lean 实盘的"现金同步"抽象。实盘账户的现金可能因为利息、股息、过夜费等时刻变化,Lean 定期把券商的 GetCashBalance 同步到 Algorithm.Portfolio.CashBook,保证 Portfolio.TotalPortfolioValue 准确。这种"账户真实状态主导,本地状态跟随"的设计,是实盘与回测的关键差异。

三、关键区分:BrokerageModel 与 IBrokerage

这是本节最重要、也是初学者最常混淆的点。BrokerageName 枚举既给 BrokerageModel 用,也给 IBrokerage 用,但两者职责完全不同:

维度 IBrokerageModel(券商模型) IBrokerage(券商连接)
命名空间 QuantConnect.Brokerages QuantConnect.Interfaces
用途 回测模拟的费率/滑点/保证金 实盘真实下单/查询
内容 IFeeModel(手续费)、ISlippageModel(滑点)、IBuyingPowerModel(保证金/购买力)、IOrderProperties(可用订单类型/TIF)、杠杆设置 PlaceOrder / CancelOrder / Connect / 事件回调
装配 SetBrokerageModel(BrokerageName.XXX) config.jsonlive-mode-brokerage + environment
何时用 回测里精确模拟某券商的成交成本 实盘里真正连券商跑交易
实现 InteractiveBrokersBrokerageModelBinanceBrokerageModel InteractiveBrokersBrokerageBinanceBrokerage 等(注意:类名没有"Model"后缀)

3.1 BrokerageModel 的作用

回测时,Lean 用 BacktestingBrokerage(第 3 章)模拟成交——但成交的价格、手续费、滑点要接近真实BrokerageModel 决定这些"券商特定行为":

  • 手续费:IB 美股每股 0.005 美元最低 1 美元,Binance 加密 0.1%。IBrokerageModel.GetFeeModel() 返回对应的 IFeeModel
  • 滑点:市价单对流动性差的标的滑点大。GetSlippageModel() 返回 ISlippageModel
  • 保证金:外汇 50 倍杠杆、加密 2 倍、股票 2 倍(Reg T)。GetBuyingPowerModel() 返回 IBuyingPowerModel
  • 可用订单类型/TIF:IB 支持复杂条件单,Binance 不支持 IOC/FOK(只支持 GTC)。GetOrderProperties() 限制。

策略里设置:

public override void Initialize() { // 让回测按 IB 费率/滑点/保证金模拟 SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage); AddEquity("SPY"); // 现在 SPY 成交会按 IB 的每股 0.005 美元算手续费 }

3.2 IBrokerage 的作用

实盘时,config.json 里 environment 的 live-mode-brokerage 决定用哪个真实券商:

"live-interactive": { "live-mode-brokerage": "InteractiveBrokersBrokerage", "data-queue-handler": [ "InteractiveBrokersBrokerage" ], "transaction-handler": "QuantConnect.Lean.Engine.TransactionHandlers.BrokerageTransactionHandler", ... }

引擎启动时(第 3 章 SetupHandler)用反射实例化 InteractiveBrokersBrokerage,调用 Connect() 连 IB TWS/Gateway,后续所有 PlaceOrder 直接发到 IB 真实下单。

3.3 同一枚举,两种用法

BrokerageName.InteractiveBrokersBrokerage 这个枚举值两种场景都出现:

  • 回测:SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)——告诉引擎用 IB 的费率模型。
  • 实盘:config.json 里 "live-mode-brokerage": "InteractiveBrokersBrokerage"(字符串,不是枚举)——告诉引擎实例化真实 IB 连接。

两者共享同一名字是为了让回测和实盘的券商行为一致——你在回测里用 IB 模型算出的成本,实盘连 IB 时成本也大致如此(虽然实盘费率可能随账户而异)。这种"同名对应"是"回测实盘统一"在券商层的体现。

本节要点回顾

  1. BrokerageName 枚举(217 行,40+ 券商):股票(IB/Tradier/Alpaca/Schwab/Tastytrade/Webull)、加密(Binance 系列/Coinbase/Kraken/Bybit/DYDX)、外汇(Oanda/Fxcm)、期货(TT/Atreyu/Wolverine)、印度(Zerodha/Samco)。
  2. GDAX = 12 的特殊编号:Obsolete 旧名 + 显式锁数字值,避免破坏序列化兼容,体现"枚举值不可变"的工程纪律。
  3. IBrokerage 接口(161 行):继承 IBrokerageCashSynchronizer + IDisposable,8 个方法(Connect/Disconnect/PlaceOrder/UpdateOrder/CancelOrder/GetCashBalance/GetAccountHoldings/GetOpenOrders/GetHistory) + 7 个事件(OrdersStatusChanged/OrderUpdated/AccountChanged/Message/OptionPositionAssigned/...)。
  4. 方法三组:连接组、账户查询组(实盘启动同步真实状态)、下单组(返回 bool 表"已接受"非"已成交")。
  5. 事件驱动是实盘灵魂:成交/账户变化/错误都由券商推送而非主动查询。
  6. 关键区分:IBrokerageModel(费率/滑点/保证金,回测用)≠ IBrokerage(真实连接,实盘用),两者通过 BrokerageName 同名联系但职责完全不同。
  7. SetBrokerageModel(BrokerageName.XXX):设置回测模拟的券商行为(费率/滑点/保证金/订单类型)。

下一节钻取 Brokerages 项目的 WebSocket 公共基础设施(券商实时行情/订单推送的底座)、实盘的 BrokerageTransactionHandler 与 IDataQueueHandler、Docker 多架构部署以及 lean CLI。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U