MarketData 与宿主运行契约方案
本文档定义 zelqor 在完成策略加载与统一运行之后,下一步最值得推进的能力:把 marketData 和宿主调用契约正式化。
一句话总结:
当前仓库已经解决了“策略怎么被框架运行”,下一步要解决的是“外部宿主怎么稳定、明确、可扩展地调用这套运行系统”。
1. 为什么下一步应该做这个
当前仓库已经具备:
strategyrequest schemapython_file/python_module策略加载run_backtest(...)真实执行run-backtest --request-file ...真实执行
这说明:
- 策略接入链路已经不是主要瓶颈
- CLI 已经不再是 scaffold
- request schema 已经能驱动真实回测
但当前仍有一个明显短板:
marketData仍然是“最小可用”建模- request 还缺少更明确的宿主控制项
- 外部系统调用这套能力时,缺少更稳的契约边界
因此下一步更有价值的事情,不是继续扩展策略形态,而是把“宿主如何调用”这件事产品化。
2. 当前边界
当前 BacktestRequest 里关于宿主运行契约的字段主要是:
marketDatastrategydateRangecapitalexecutioncostsparams
其中 marketData 当前正式支持:
{
"type": "clickhouse",
"source": {
"mode": "config_file",
"configPath": "config.toml"
}
}
并且 request 里已经有最小宿主输出控制:
{
"runtime": {
"output": {
"includeDailyPools": true,
"includeDailyDecisions": true,
"includeTrades": true,
"includePositionsByDate": true,
"includeEquityCurve": true
}
}
}
旧的扁平字段:
configPathuseEnv
已经不再是正式 schema 的一部分。
这已经比原来更清晰,但还不够完整地表达宿主调用方式,比如:
- provider 配置到底来自哪里
- provider 专属配置如何建模
- 是否允许不同运行环境覆盖配置
- 回测结果输出粒度如何控制
- debug / metadata 是否需要显式约束
3. 目标
这一阶段建议聚焦三个目标。
3.1 目标一:正式化 marketData schema
建议把 marketData 从“最小兼容结构”升级为“明确的 provider 配置入口”。
最少应明确:
- provider 类型
- provider 配置来源
- provider 专属配置结构
对 ClickHouse 来说,当前已经统一到:
source.mode == "config_file"source.mode == "env"
后面再决定是否允许 inline config
3.2 目标二:正式化宿主运行控制项
当前 request 已经能描述“运行什么”,但还不够清晰地描述“输出什么”和“保留什么”。
建议后续增加或正式化:
- 输出粒度控制
- 是否保留
dailyPools - 是否保留
dailyDecisions - 是否保留
trades - 是否保留
positionsByDate - debug / metadata 输出控制
这类字段不一定要一次性全部实现,但应该开始设计统一入口。
3.3 目标三:把 request 当成宿主契约来测试
当前测试更多是在验证:
- loader 是否正常
- API 是否能跑通
- CLI 是否能跑通
下一阶段应增加一层面向宿主的契约测试,覆盖:
- 最小 request
- 完整 request
- 非法 provider 配置
- 空交易日区间
strategy.kind不匹配- provider 类型不支持
- provider 配置缺失
4. 推荐 schema 演进方向
4.1 marketData
建议保留统一入口:
{
"marketData": {
"type": "clickhouse",
...
}
}
但内部进一步细化成更稳定的形状,例如:
{
"marketData": {
"type": "clickhouse",
"source": {
"mode": "config_file",
"configPath": "config.toml"
}
}
}
或者:
{
"marketData": {
"type": "clickhouse",
"source": {
"mode": "env"
}
}
}
这样做的好处是:
- provider 来源更清晰
- 未来支持更多 provider 时更容易扩展
- 不会让顶层 request 长出太多 provider 细节字段
4.2 runtime
建议新增独立的宿主运行控制对象,例如:
{
"runtime": {
"output": {
"includeDailyPools": true,
"includeDailyDecisions": true,
"includePositionsByDate": false
}
}
}
这层不是策略逻辑本身,而是宿主如何消费结果的配置。
4.3 metadata
如果后面桌面端、服务端或任务系统要接入,建议允许 request 带一层宿主元数据,例如:
{
"metadata": {
"requestId": "bt_20260326_001",
"caller": "desktop",
"profile": "research"
}
}
这样更利于:
- 审计
- 日志关联
- 调试
- 宿主区分
5. 推荐实现顺序
5.1 第一步:写清 marketData 的下一版 shape
先形成统一约定:
- 当前保留什么
- 哪些旧字段需要淘汰
- 哪些字段属于 provider 通用层
- 哪些字段属于 ClickHouse 专用层
5.2 第二步:补 provider 配置契约测试
增加:
marketData.type错误测试configPath缺失测试- 旧
configPath/useEnv字段拒绝测试 - 配置文件不存在测试
5.3 第三步:引入 runtime 控制层
先不必一次性让所有输出控制都生效,但建议先把 request 结构定出来。
5.4 第四步:补宿主调用示例
建议增加:
- 一个最小宿主 request 示例
- 一个完整宿主 request 示例
- 一个错误 request 示例
6. 当前不建议优先做什么
这一阶段不建议优先做:
- 新增更多策略模式
- 分钟级回测
- 更复杂 broker 撮合
- 参数扫描调度系统
- UI 层联动逻辑
这些都应该排在“宿主契约稳定”之后。
7. 风险与取舍
7.1 过早把 marketData 设计得太重
建议:
- 先围绕 ClickHouse 抽象
- 不急着假装已经支持很多 provider
7.2 把宿主控制项和策略参数混在一起
建议明确分层:
params给策略runtime给宿主marketData给 provider
7.3 让 request 顶层继续膨胀
建议把宿主相关字段拆进:
marketDataruntimemetadata
而不是把所有东西都塞在顶层。
8. 验收标准
这一阶段建议以这些结果作为完成标志:
marketData的下一版 shape 形成正式约定- request 中宿主控制层有明确位置
- provider 配置错误有清晰报错
- 宿主 request 示例与契约测试补齐
9. 结论
zelqor 当前下一步最应该做的,不是继续证明策略模式,而是正式定义:
- provider 怎么接入
- request 怎么表达宿主意图
- 宿主怎么稳定消费运行结果
也就是说,下一阶段的关键词不是“更多策略”,而是:
- 更清晰的宿主运行契约
完成这一阶段后,仓库会从:
- 策略能被加载
- 回测能被执行
进一步进入:
- provider 配置边界清晰
- request 契约更稳定
- 更适合桌面端、服务端或任务系统接入