「回测」不等于「实盘」
Trader 记录的是研究口径下的调仓结果,官方材料里没有交易接口与报单能力的证据,实时行情还依赖 QMT 授权。把 ZVT 回测当作策略验证工具可以,当作实盘系统需要另找方案。
ZVT 项目研究站 · 策略与界面
ZVT 的策略写法非常统一:继承 StockTrader,实现 on_time(timestamp),在事件循环里决定买什么、卖什么,调用 trade_the_targets(...) 下单。跑完之后的结果查看有三个入口——zvt 命令的 Dash 界面、zvt_server 的 REST 服务、以及独立仓库里的前端。它们在 README 里散落各处,本页集中对照。
setup.py 的 console_scripts 与入口源码自绘(非官方架构图);zvt_ui 前端不在本仓库,端口与路径取自 README。README 给了一个完整的策略源码(跟着机构增持买的例子)。下表把它用到的每个关键点拆出来。
| 要素 | 写法 | 含义 | 适用场景 | 注意点 |
|---|---|---|---|---|
| 策略基类 | class XxxTrader(StockTrader): | 股票类策略基类,提供时间循环与交易记录 | 个股与股票池策略 | 基类会自动按交易日推进时间轴,你不需要自己写循环 |
| 时间回调 | def on_time(self, timestamp): | 每个时间点被调用一次,是策略仅有的事件入口 | 所有策略 | 官方示例里用一个 finish_date 属性避免同一报告期重复处理——这类幂等保护要自己写 |
| 选买卖集合 | long_selected=set(...) / short_selected=set(...) | 本时点要买 / 要卖的标的集合 | 按条件选股后交易 | 传的是实体 id 集合,不是代码字符串 |
| 下单调用 | self.trade_the_targets(due_timestamp=, happen_timestamp=, long_selected=, short_selected=) | 在指定时点按集合调仓 | 回测与模拟 | 两个时间参数分别表示「实际成交时点」与「信号发生时点」,做避免未来函数的检查时要盯住它们 |
| 运行参数 | start_timestamp / end_timestamp / entity_ids / provider / adjust_type / profit_threshold | 实例化时给出回测区间、标的、数据源、复权口径与止盈阈值 | 所有回测 | adjust_type 要与取数时的口径一致;profit_threshold=None 表示不启用止盈逻辑 |
| 运行方式 | XxxTrader(...).run() | 启动回测,结果写入本地记录 | 回测 | 结果通过界面或记录表查看,不在控制台直接输出绩效 |
class FollowIITrader(StockTrader):
finish_date = None
def on_time(self, timestamp):
recent_report_date = to_pd_timestamp(get_recent_report_date(timestamp))
if self.finish_date and is_same_date(recent_report_date, self.finish_date):
return
df = StockActorSummary.query_data(filters=[...])
long_df = df[df['change_ratio'] > 0.05]
short_df = df[df['change_ratio'] < -0.5]
self.trade_the_targets(due_timestamp=timestamp, happen_timestamp=timestamp,
long_selected=set(long_df['entity_id']),
short_selected=set(short_df['entity_id']))
FollowIITrader(start_timestamp='2002-01-01', end_timestamp='2021-01-01',
entity_ids=['stock_sh_600519'], provider='em',
adjust_type=AdjustType.qfq, profit_threshold=None).run()set(entity_id) 的选择也有 orchestrator 的买卖判定,你只负责选,成交规则由框架的交易日与价格口径决定;③示例本身是官方 README 的演示,不构成任何有效性或收益证据。README 明确区分了两种写法,很多人只看了第一种就以为 ZVT 只能这么写。
| 写法 | 做法 | 适合什么 | 局限 | 注意点 |
|---|---|---|---|---|
| solo(自由式) | 在 on_time 里自己查数据、自己写条件,像写一段普通脚本 | 事件驱动型策略(跟着公告、持仓变动、龙虎榜做) | 条件复杂后代码会变乱,复用性差 | README 自己也称这种例子「too simple, sometimes naive」——指的是逻辑简单,不是说框架简单 |
| formal(形式化) | 用二维索引的因子与 selector:因子产出 result_df,selector 按时间切片选标的 | 横截面选股、多因子组合 | 要先有完整数据与因子,起步门槛更高 | 这是 ZVT 区别于「单标的指标库」的核心能力;数据不全时结果会失真 |
README 的界面截图会让人以为装上就有完整系统。下表按 setup.py 与入口文件的实际代码说明现状。
| 入口 | 启动方式 | 地址与端口 | 现状(据源码) | 适用场景与注意点 |
|---|---|---|---|---|
| Dash 界面 | zvt | http://127.0.0.1:8050/ | 入口文件用 dash-bootstrap-components 起服务(host 0.0.0.0、debug=True),当前 layout 只注册了一个 factor 标签页 | 看因子与回测结果最直接;别期待 README 截图里的多模块界面,那可能是历史版本或商业化版本 |
| REST 服务 | zvt_server(需先装 uvicorn) | http://127.0.0.1:8090/docs | FastAPI 应用,挂 data / factor / work / trading / misc 五个 router,CORS 允许所有来源,开发模式 reload=True | 二次开发与前后端分离时的接口层;api-tests/ 里有可直接导入的 .http 样例 |
| 独立前端 | 另一个仓库 zvtvz/zvt_ui | http://127.0.0.1:3000/trade | 前端不在本仓库;需改 .env 的 NEXT_PUBLIC_SERVER 指向 zvt_server | README 称其更适合实时行情与人工交互;要额外维护一个前端项目 |
| 导出命令 | zvt_export | 命令行 | 由 setup.py 注册,对应 zvt.plugin:export | 批量导出数据时用;具体参数以源码为准 |
下面是让「策略 + 界面」这条链路转起来的最短路径,顺序错了会卡在数据上。
策略依赖本地库:至少要有标的清单、对应周期的 K 线,事件型策略还需要对应的事件表。预期:query_data 能查到连续数据;缺失时策略会静默跳过而不是报错。
实例化 trader 时的 adjust_type 要和取数时的表一致(默认表 vs hfq 表)。预期:回测价格与你预想的口径吻合;口径混用会让结果整体偏移。
第一版建议只做「固定选一只、固定买卖」这种可预期行为,确认框架跑通。预期:回测能跑完并在本地记录里看到交易记录。
zvt 命令起 8050,在 factor 标签页里查看标的、因子、信号与绩效。预期:能看到与你的交易记录一致的曲线;界面报错时先看 log_path 下的日志。
pip install uvicorn 后 zvt_server 起 8090,用 /docs 试接口。预期:接口返回结构化数据;需要跨域时注意其 CORS 允许所有来源,生产环境要自己收口。
这四条都来自源码与官方说明,官方文档没有集中提醒。
Trader 记录的是研究口径下的调仓结果,官方材料里没有交易接口与报单能力的证据,实时行情还依赖 QMT 授权。把 ZVT 回测当作策略验证工具可以,当作实盘系统需要另找方案。
入口源码里 dbc.Tabs 只注册了 factor 一个 tab,且应用以 debug=True 启动。生产使用要自己改入口文件;README 截图里的丰富界面与本仓库当前代码不完全对应。
allow_origins=["*"] 与 reload=True 是开发配置。要放在别人能访问的环境里,先改这两项,再加鉴权——框架本身没有提供账号体系。
README 的 Declaration 明确「当前不保证任何向后兼容」。策略里用到的类名、参数名与表结构都可能在升级后变化,回滚方案与版本锁定是必需的。
以 README 与入口源码为准;涉及效果的问题本站不答。
官方材料里没有交易接口、也没有报单相关模块的证据,实时行情还依赖 QMT 授权(README 要求联系作者)。所以本站不宣称它能做实盘。它更准确的定位是研究、因子与回测框架。
两个地方:一是 zvt 命令起的 Dash 界面(8050),二是框架写入本地的交易与绩效记录表,可用 query_data 查出来做二次分析。REST 服务(8090)则适合给外部程序消费。
因为当前入口文件(src/zvt/main.py)的 layout 里只注册了 factor 一个 tab,其余能力在 REST 服务与独立前端里。README 的界面截图可能来自更早版本或作者的另一套实现,以源码为准。
前者是期望成交的时点,后者是信号发生的时点。框架要求把两者分开传,作用是让「用哪天的数据决定哪天的交易」这件事显式化——这是避免未来函数的关键接口设计。具体撮合规则以源码为准。
官方示例里 profit_threshold=None,表示不启用止盈逻辑。其余参数的取值需要在你的策略里自己定义,框架不提供默认策略。任何参数推荐都会涉及投资决策,本站不予提供。
技能提供的是方法论与代码片段层面的帮助(风险指标、组合优化、回测注意事项),不运行 ZVT 的 trader,也不产生 ZVT 的交易记录。ZVT 则提供可复现的框架执行。两者无已证实集成,对照见「对比」页。