Blankly / 实盘前检查
「回测到实盘只改一行」这句话,在代码里长什么样
Blankly 官方模板的写法是 if blankly.is_deployed: strategy.start() else: strategy.backtest(...)——策略回调确实可以复用,但「切换」是由一个环境判定分支完成的,而且 is_deployed 只在存在特定外部模块时才为真。更重要的是:代码复用不等于行为一致。这一页把 Blankly 回测与实盘之间的差异拆成四个面,并给出一份可以在上线前逐项打勾的清单。
回测与实盘的差异集中在哪四个地方?
先把「哪些能复用」说清楚:策略的信号逻辑与下单调用形式通常可以复用。下面这四类东西不能复用,必须逐项重验。
| 差异面 | 回测里的假设 | 实盘里的现实 | 你要做的验证 |
|---|---|---|---|
| 费率 | 离线模式构造函数默认 maker_fee=0、taker_fee=0;接入交易所时费率按账户档位下载 | 费率随成交额档位变化,且 maker 与 taker 不同 | 用一笔小额真实(或模拟)委托确认实际扣费,与回测假设对齐 |
| 成交与滑点 | 工程文档明确:当前假设无限挂单流动性,订单按当前价精确成交;尚无滑点模型 | 成交取决于盘口深度、排队顺序与下单方式 | 用最小金额下一笔真实委托,比较成交价与当时盘口价 |
| 权限与拒单 | 回测不会因为权限问题失败 | 密钥可能缺少下单权限、地区受限、余额不足、触发风控 | 逐项确认密钥权限范围;先用只读权限跑通,再逐步开放 |
| 异常与时区 | 回测是确定性的时间推进,不会断线 | 网络中断、限流、交易所维护、时区与夏令时差异 | 确认策略重启后能否从持仓状态恢复;确认所有时间基准一致 |
is_deployed 是什么?它的实际边界在哪
把 Blankly 的这套机制讲清楚,你才能判断「代码复用」这句话对你意味着多少工作量。
| 事实 | 具体内容 | 对你的影响 | 怎么核对 |
|---|---|---|---|
| 顶层有一个部署标记 | 包内定义了 is_deployed,初始为 False | 本地跑永远走 backtest 分支 | 在脚本里打印该值 |
| 它为真的条件 | 仅当环境中存在名为 blankly_external 的模块时,才被置为真并加载其中定义的 reporter | 它反映的是「运行环境」,不是「你连了实盘」 | 包初始化文件里可以读到这段逻辑 |
| 官方模板的写法 | if blankly.is_deployed: strategy.start() else: strategy.backtest(...) | 策略回调共用,但入口分支不同 | 看包内 data/templates/ 的模板文件 |
| 模板里另一个分支 | 部分模板在不同分支里用了不同的时间参数(例如本地分支用 to='1y') | 离线数据场景下 to='1y' 会失败,需要改成显式起止时间 | 见首个离线回测页的三种调用对照 |
| 平台部署路径 | CLI 的 login/deploy 子命令在源码中被整段注释 | 不能通过 CLI 上传到官方托管平台 | 见 CLI 与部署状态页 |
实盘前要检查哪些项?十六项清单
下表按「环境 → 数据 → 交易 → 风控 → 运维」的顺序排列。每一行都给出可执行的验证动作,而不是笼统的注意事项。
| 类别 | 检查项 | 验证动作 | 通过标准 |
|---|---|---|---|
| 环境 | 依赖版本已固化 | 运行 pip freeze 并保存 requirements.txt | 换机器能一键复现 |
| 环境 | 配置文件齐全 | 确认 Blankly 工作目录存在 settings.json、keys.json、backtest.json | 构造交易所不再抛异常 |
| 环境 | 时间基准一致 | 把系统时区、数据时间戳、交易所返回时间三者对齐 | 信号时间与预期偏差在可接受范围内 |
| 数据 | 标的代码正确 | 先用只读接口查一次产品信息 | 返回的标的与你预期的一致 |
| 数据 | 数据分辨率与实盘节奏匹配 | 确认策略信号频率与实盘轮询频率一致 | 不存在「回测按日、实盘按秒」这类错位 |
| 数据 | 历史预热可用 | 确认启动时能取到足够长的历史做指标预热 | 策略启动后立刻有有效指标值 |
| 交易 | 密钥权限最小化 | 先用只读权限跑通,再单独开放下单 | 无法读取的权限确实不需要 |
| 交易 | 最小下单量与增量满足要求 | 用最小金额下一笔委托,观察是否被拒 | 委托被接受而不是被规则拒绝 |
| 交易 | 计价币种与资金账户正确 | 查账户余额,确认策略读取的是正确账户 | 余额与预期一致 |
| 交易 | 费率假设与实盘一致 | 对同一笔委托比较回测扣费与实际扣费 | 差异在你的容忍范围内 |
| 风控 | 单笔与总仓位上限 | 在策略里显式限制下单规模 | 极端信号下不会超限 |
| 风控 | 重复信号保护 | 确认同一信号不会重复下单 | 成交记录无异常重复 |
| 风控 | 拒单与失败处理 | 构造一次被拒场景(如超最小量的反向情形) | 策略记录并在下一轮恢复,不静默退出 |
| 运维 | 断线重连 | 断开网络后恢复,观察策略行为 | 能重新连接并同步持仓 |
| 运维 | 进程崩溃恢复 | 重启进程,确认持仓状态不被误判 | 重启后不产生反向重复下单 |
| 运维 | 人工停止开关 | 准备一个能立刻停止策略的手段 | 可用且经过一次演练 |
动真钱之前怎么拆链路?三级递进
Blankly 提供了离线回测与模拟盘两种非真实资金路径。把它们当作上线的三个台阶,能让问题一次只暴露一层。
第一级:离线回测
用 KeylessExchange 加本地数据,完全零网络依赖。这一级验证的是「策略逻辑与指标计算是否正确」,不验证任何交易链路。它同时也是最快的迭代环境。
第二级:模拟盘
连接交易所但使用模拟或沙箱环境(框架里有对应的纸面交易接口,交易所侧也提供各自的测试环境)。这一级验证的是「密钥、权限、下单参数、订单状态读取」这些真实链路,同时不动用真实资金。
第三级:最小真实委托
用最小可达金额走一次真实下单与撤单,确认费率、成交价、订单回报与你的假设一致。这一级的目的是暴露「回测不可能暴露」的差异,而不是验证收益。
| 层级 | 能验证什么 | 验证不了什么 | 退出条件 |
|---|---|---|---|
| 离线回测 | 策略逻辑、指标计算、信号时序 | 任何网络与账户相关的行为 | 信号行为与你的预期一致 |
| 模拟盘 | 密钥连通性、权限范围、下单参数合法性、订单状态回读 | 真实成交价、真实费率、真实排队 | 连续若干轮无异常、订单记录完整 |
| 最小真实委托 | 真实费率、真实成交价、订单回报格式、拒单原因 | 大规模下的滑点与容量 | 各项实测值与你的假设差异已知且可接受 |
| 小规模真实运行 | 日内行为、断线恢复、长期稳定性 | 极端行情下的表现 | 按你的风险预算决定是否继续放大 |
哪六种情况「回测正常、实盘不对劲」?
下面每一行都给出了 Blankly 场景中的现象、可能原因与定位方法。这类问题的共同点是:回测阶段完全看不出来。
| 现象 | 可能原因 | 定位方法 | 处置方向 |
|---|---|---|---|
| 实盘收益明显低于回测 | 回测默认零手续费、且无滑点模型 | 把回测费率改成实际档位并加入滑点假设重跑 | 接受真实成本后重新评估策略是否仍成立 |
| 委托一直被拒 | 数量不满足最小下单量或增量要求,或余额不足 | 查看被拒返回的错误信息 | 按交易所规则调整下单数量取整方式 |
| 成交价与当时看到的价差很多 | 盘口深度不足,或用了市价单在流动性差时成交 | 对比成交价与下单瞬间的盘口 | 改用限价单,或缩小单笔规模 |
| 策略重复下单 | 缺少重复信号保护,或被拒后立刻重试 | 检查成交记录是否存在时间相近的同向委托 | 增加持仓状态判断与重试节流 |
| 重启后出现反向操作 | 策略把「重启」误判为「空仓」,于是重新建仓或反向平仓 | 重启一次观察订单行为 | 启动时从账户读取真实持仓,而不是用内部变量初始化 |
| 信号时间比回测晚一个周期 | 回测用收盘价生成信号并当日成交,实盘只能次日执行 | 对比回测的成交时点与实盘实际时点 | 在回测中显式加入信号延迟,让两边对齐 |
关于回测到实盘的高频问题
框架机制部分可在源码中核对;交易决策与风险承担由使用者自行负责。
is_deployed 什么时候为真?
Blankly 在包初始化时把它设为 False,只有当运行环境中存在名为 blankly_external 的模块时才被置为 True,并从中加载一个 reporter 对象。也就是说它反映的是「运行环境里有没有这个外部模块」,与「你有没有连接实盘账户」是两件事。本地直接跑脚本时它始终为假。
模拟盘能替代真实下单验证吗?
不能完全替代。模拟盘能验证密钥连通性、权限范围、下单参数合法性与订单状态回读这些链路问题,但成交价、费率和排队顺序都是模拟的。所以上线前仍需要一次最小金额的真实委托,用来确认费率和成交价的真实差异。
回测里怎么让「信号延后」这个现实约束体现出来?
最直接的方法是在回测中把信号整体延后一个周期再执行,例如用当期数据算出的信号在下一期成交。这样回测的成交时点就与实盘一致。反过来说,如果你的回测是「当日信号当日成交」,那么它天然比实盘乐观——这一点在有收盘集合竞价的市场上尤其明显。
策略重启后持仓状态怎么处理?
Blankly 策略的重启原则是「以账户为真相」:启动时不要用内部变量假定空仓,而要先从账户读取真实持仓与可用余额,再用这份状态初始化策略。否则一次重启就可能被误判为空仓,从而重复建仓或反向平仓。这一点在 16 项检查表的运维部分有对应条目。
官方托管平台还能部署吗?
可核对的事实是:当前发行版的 CLI 只提供 init 与 key 两个子命令,源码里 login/deploy/logout 三个子命令及其实现被整段注释掉了。因此「通过 CLI 部署到官方托管平台」这条路径在当前版本上不可用。详见 CLI 与部署状态页。
本站有实盘运行经验可以分享吗?
没有。本站的全部内容都是在一个临时虚拟环境里对框架做代码级与流程级验证,没有连接任何真实账户,也没有下过任何委托。因此本页是「框架机制与公开文档的整理」,加上一份通用的上线检查思路,而不是实盘经验分享。真实交易的风险请自行评估。