Files
Neo-ZQYY/docs/prd/specs/P19-index-backtest-task-simulation.md
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

5.3 KiB
Raw Blame History

P19历史指数回测 + 任务引擎模拟

版本v1.0 | 日期2026-03-29 | 来源:本轮对话需求讨论


1. 背景

任务引擎P17 + OS 分级分配)已实现,但缺乏历史验证手段。需要:

  • 回测过去一个月的指数变化,验证指数算法的稳定性
  • 模拟任务引擎运行一个月,验证分级分配、升级、转移逻辑的合理性
  • 最终数据落库(test_zqyy_app),可在小程序和管理后台中查看

2. 需求拆分

2.1 指数历史回测Phase 1

目标:给 4 个指数任务加 as_of_date 参数,支持"假装今天是 X 日"重算指数。

涉及任务

任务 输入数据源 时间依赖点
DWS_WINBACK_INDEX (WBI) dws_member_visit_detail + dws_member_consumption_summary 距上次到店天数、到店频率衰减
DWS_NEWCONV_INDEX (NCI) dws_member_visit_detail + dws_member_consumption_summary 新客首次到店后的天数
DWS_RELATION_INDEX (RS/OS/MS/ML) dwd_assistant_service_log 服务记录的时间衰减halflife
DWS_SPENDING_POWER_INDEX (SPI) dws_member_consumption_summary 消费金额时间窗口

改动要点

  • 每个指数任务的 _do_extract() 中,将 NOW() / CURRENT_DATE 替换为 as_of_date 参数
  • 衰减计算中的"距今天数"改为"距 as_of_date 天数"
  • 输出表新增 calc_date 字段(或复用 calc_time),标记是哪天的快照

回测参数

  • 时间范围:过去 30 天2026-02-27 ~ 2026-03-29
  • 回测间隔:每 6 小时一个快照(共 120 个快照点)
  • 数据落库:每个快照覆盖写入 ETL 测试库的指数表delete-before-insert by calc_date

CLI 接口设计

# 单次回测(指定日期)
python -m cli.main --tasks DWS_WINBACK_INDEX --as-of-date "2026-03-01"

# 批量回测(日期范围 + 间隔)
python scripts/ops/backtest_indexes.py \
  --start "2026-02-27" --end "2026-03-29" \
  --interval-hours 6 \
  --store-id 2790685415443269

2.2 任务引擎模拟Phase 2

目标:基于回测的指数快照,模拟任务引擎运行一个月,数据落入业务测试库。

模拟参数

  • 时间范围2026-02-27 ~ 2026-03-29
  • 模拟粒度每小时一次720 次循环)
  • 指数数据:使用 Phase 1 回测的快照(每 6 小时更新一次,中间小时复用最近快照)
  • 回店判定:使用 DWD 真实服务记录(dwd_assistant_service_log.create_time

模拟流程(每小时)

1. 设置模拟时钟 sim_time
2. 如果 sim_time 是 6 小时整点 → 切换到对应的指数快照
3. 检查 DWD 服务记录中 create_time 在 [sim_time-1h, sim_time] 的记录
   → 匹配 active 召回任务 → 标记 completedcompleted_at = sim_time
4. 检查过期任务expires_at < sim_time→ 标记 abandoned
5. 执行任务生成逻辑OS 分级分配):
   a. MAIN 助教:生成召回/关系构建任务
   b. COMANAGE仅生成关系构建检查升级条件升级倍数 ≥ 3
   c. 转移检查(升级倍数 ≥ 5
6. 已完成的召回任务 → 生成 follow_up_visit48h 保留期)
7. 记录当小时的任务快照

数据落库

  • 所有任务写入 biz.coach_taskscreated_at 用模拟时钟值)
  • 历史记录写入 biz.coach_task_history
  • 转移日志写入 biz.coach_task_transfer_log

期望输出

  1. 每天的任务数量变化(按类型分组)
  2. 一个月后各类型任务的最终分布
  3. COMANAGE 升级触发次数和时间点
  4. POOL 转移触发次数和时间点
  5. 回访任务的生成数量和完成率
  6. 每个助教的任务负载分布

2.3 输出报告

脚本输出

  • 控制台:每天一行摘要(日期 | 新增 | 完成 | 升级 | 转移 | 总 active
  • CSV 文件:export/backtest/task_simulation_daily.csv(每天快照)
  • JSON 文件:export/backtest/task_simulation_summary.json(最终统计)

3. 技术约束

  • 指数回测和任务模拟都在测试库执行(test_etl_feiqiu / test_zqyy_app
  • 模拟脚本放 scripts/ops/,遵循现有脚本规范
  • 环境变量从根 .env 加载(load_dotenv
  • 指数回测需要 ETL 库连接(PG_DSN),任务模拟需要业务库连接(APP_DB_DSN
  • 模拟前清空 coach_tasks / coach_task_history / coach_task_transfer_log

4. 实施顺序

  1. Phase 1aRelationIndexTaskRS/OS/MS/MLas_of_date 支持
  2. Phase 1bWinbackIndexTaskWBIas_of_date 支持
  3. Phase 1cNewconvIndexTaskNCIas_of_date 支持
  4. Phase 1dSpendingPowerIndexTaskSPIas_of_date 支持
  5. Phase 1e编写批量回测脚本 backtest_indexes.py
  6. Phase 2编写任务模拟脚本 simulate_task_engine.py

5. 依赖

  • P17助教客户归属与任务生成引擎已完成
  • OS 分级分配改动(本轮已完成)
  • DWS_TASK_ENGINE ETL 任务(本轮已完成)
  • DWD 层服务记录数据(已有)

6. 关键文件参考

  • 指数任务:apps/etl/connectors/feiqiu/tasks/dws/index/
  • 任务生成器:apps/backend/app/services/task_generator.py
  • 召回检测器:apps/backend/app/services/recall_detector.py
  • FDW 查询:apps/backend/app/services/fdw_queries.py
  • 参数配置:biz.cfg_task_generator_params16 条参数)