TuAlpha 架构¶
TuAlpha 采用 RQAlpha 风格的职责分层,面向日频 A 股/ETF 回测,并使用 Parquet + DuckDB 本地数据层。
src/tualpha/
├── apis/ # 策略函数,转发到 ExecutionContext
├── foundation/ # 跨模块配置、枚举、日期规范化与异常体系
├── core/ # TradingAlgorithm、回调阶段、D/D+1 事件循环
├── model/ # Asset、Order、Transaction、Position、Portfolio
├── broker/ # SimulationBroker、Matcher、费用和市场规则
├── data/
│ ├── bar.py # DailyBar 与回调 BarData
│ ├── portal.py # PIT Parquet DataPortal 与 NumPy 列缓存
│ ├── factors.py # 安全表达式 AST、窗口规划与向量化算子
│ ├── research.py # 离线 FactorData、PIT 资产池和过滤
│ ├── query.py # DuckDB 本地查询客户端
│ ├── trading_calendar.py
│ ├── quality/ # 表级质检和报告
│ └── bundle/ # Parquet schema、全量构建、更新、Catalog 和发布
├── analysis/ # 回测结果、绩效指标和 IC/RankIC 因子分析
├── report/ # 回测/因子图表、归因、格式化和 HTML 组装
├── cmds/ # build / update / quality
└── *.py # 稳定公开导入路径的轻量兼容门面
根目录模块只维护 tualpha.config、tualpha.metrics、tualpha.reporting
等既有导入契约;框架内部必须依赖上述职责包中的唯一实现,避免门面层重复逻辑。
依赖方向¶
apis → core.execution_context
core.algorithm → foundation + broker + data + model + analysis
broker → data.bar + model
DataPortal → DuckDB query + model.asset + calendar
bundle builder/updater → Parquet schema + Catalog + publication
quality → DuckDB query + table registry
report → analysis.result
model 不依赖策略 API 或回测循环;apis 不直接操作 Broker;Matcher 不调用策略代码。
每日执行顺序¶
D 日 handle_data
→ 创建订单意图,eligible_session = D+1
D+1
→ 应用公司行动
→ 读取所选 open/close 原始端点
→ 计算撮合前组合权益
→ Matcher 解析 quantity/value/percent/target 意图
→ 检查停牌、成交量、涨跌停、交易单位、T+1 和现金
→ Broker 记账并产生 Transaction
→ 收盘盯市
→ handle_data
查询热路径¶
- DuckDB 对 Parquet 执行分区裁剪、字段投影和过滤下推;
- 未预取的
current()/current_arrays()只读取当前交易日,history()只读取请求窗口,不再为短窗口物化全历史稠密矩阵; - 同表多字段在一次窗口查询中读取,减少重复 Parquet 扫描;
- 同日标量查询复用有界 snapshot cache,避免逐股票重复访问 DuckDB;
prefetch()面向会在大量回调中重复使用的固定资产池,显式生成受内存上限约束的二维 NumPy 列缓存,并自动预取价格复权因子;- 框架对实际持仓的收盘价、昨收价和复权因子自动建立受同一内存上限约束的热缓存,避免逐日或逐股重复扫描 Parquet;
- 宽历史结果通过 NumPy 堆叠一次构造 Pandas DataFrame,不再逐资产、逐字段插入列;
- 因子编译器先提取所有物理字段与最大前后窗口,一次加载共享矩阵;同批表达式复用 AST 子表达式缓存,截面与时序算子均按二维数组向量化;
FactorData对指数历史成分生成严格snapshot_date < D的布尔掩码,并在同一掩码上应用历史 ST、上市天数和停牌过滤;全算子长区间基准采用列预取和小批输出控制峰值内存;fundamental_arrays()按财务表执行一次投影和 PIT 哈希聚合,单资产财务接口只加载请求字段并复用窄历史缓存;- 指数日线按请求字段增量缓存,多字段当前值只触发一次投影查询;指数成分只缓存快照日期和实际访问的 PIT 快照,不再加载全部历史成分行。
Bundle 更新¶
Tushare → 检测各数据集缺失交易日
→ 可续传分区 CSV
→ hardlink 复用未变化年度 Parquet
→ 重写受影响年份
→ catalog.duckdb + manifest.json
→ 关键约束和 Reader 校验
→ bundle.lock → 原子发布
活动 Bundle 从不原地修改。失败保留上一 generation;首次迁移保留旧 HDF5 备份。