Selector 回测方案
当前状态:本文档描述的最小链路已经完成第一版落地,对应实现包括:
zelqor.strategy.interfaces.DailyPoolSelectorzelqor.strategy.interfaces.SelectorContextzelqor.strategy.selector.build_daily_poolszelqor.api.run_selector_backtestexamples/run_selector_backtest.pyexamples/selector_numpy_skeleton.pyexamples/selector_polars_skeleton.pytests/test_selector_pipeline.py
本文档定义 zelqor 下一阶段要实现的最小链路:
selectordaily_poolsbacktest
目标不是立即做成完整平台,而是先让策略脚本可以直接 import zelqor,生成每日股票池,再交给当前最小回测执行核心。
1. 目标
当前已经完成:
ClickHouseProviderMarketDataProvider接口层run_precomputed_backtest(...)
现在缺的是:
- 谁来生成
daily_pools
因此下一阶段的目标是补齐:
selector.select(...)build_daily_pools(...)run_selector_backtest(...)
形成一条完整但最小的链路:
selector -> daily_pools -> run_precomputed_backtest
2. 设计原则
这一阶段遵循以下原则:
- 先支持库模式
- 不先做策略文件动态加载
- 不先做 CLI 托管执行
- 不先做复杂 selector registry
- 先把最小调用链打通
也就是说,策略脚本可以直接:
from zelqor import ...
然后自己把 selector 和回测执行串起来。
3. 最小职责拆分
3.1 selector
职责:
- 接收某一个交易日
- 基于 provider 和参数生成当日股票池
- 返回股票代码列表
建议最小接口:
class DailyPoolSelector(Protocol):
def select(self, context: SelectorContext) -> list[str]:
...
推荐同时提供一个轻量上下文对象:
@dataclass(slots=True)
class SelectorContext:
trade_date: str
provider: MarketDataProvider
params: dict[str, Any]
3.2 daily_pools builder
职责:
- 遍历一段交易日
- 调用 selector
- 生成标准
daily_pools
建议最小接口:
def build_daily_pools(
trade_dates: list[str],
selector: DailyPoolSelector,
provider: MarketDataProvider,
params: dict[str, Any] | None = None,
) -> dict[str, list[str]]:
...
3.3 selector backtest API
职责:
- 调用
build_daily_pools(...) - 组装
PrecomputedPoolBacktestInput - 调用
run_precomputed_backtest(...)
建议最小接口:
def run_selector_backtest(
*,
trade_dates: list[str],
selector: DailyPoolSelector,
provider: MarketDataProvider,
initial_cash: float,
holding_days: int = 1,
max_positions: int = 10,
params: dict[str, Any] | None = None,
) -> BacktestResult:
...
4. 数据流
最小数据流如下:
- 调用方准备
provider - 调用方准备
trade_dates - selector 针对每个
trade_date生成股票池 - 构造
daily_pools - 调用
run_precomputed_backtest(...) - 得到
BacktestResult
结果上不会新增新的总结果类型,继续复用当前已有的:
BacktestResult
5. 非目标
这一阶段明确不做:
- 动态加载外部
.py策略文件 - selector 多类型注册系统
- selector sandbox
- selector 与 CLI 的统一托管
run_backtest(request)的完整接线- 与 Rust 的重新集成
6. 推荐实现顺序
建议按下面顺序推进:
- 调整
strategy/interfaces.py - 实现
build_daily_pools(...) - 实现
run_selector_backtest(...) - 增加最小 selector 测试
- 增加
examples/run_selector_backtest.py
7. 最小示例形态
最小 selector 示例可以先很简单,例如:
class DemoSelector:
def select(self, context: SelectorContext):
universe = context.get_universe()
return universe[:2]
然后:
result = run_selector_backtest(
trade_dates=provider.get_trading_dates("2025-03-24", "2025-03-28"),
selector=DemoSelector(),
provider=provider,
initial_cash=100000,
holding_days=1,
)
8. 预期产出
完成这一阶段后,zelqor 将具备三层最小能力:
- 数据读取层
- selector 股票池生成层
- 最小回测执行层
这时库模式就已经基本闭环,可以让策略脚本直接 import 并运行一条完整的研究链路。