fix(mining): 市场环境数据缺失时挖掘启动即失败并前置提示

用户在未计算市场环境的数据目录跑挖掘: 搜索阶段的 regime 评估被
evaluator 软捕获成 error 字符串, 整轮嵌套搜索照常跑完后, artifacts
阶段的 _regime_date_count 硬抛 ValueError, 计算全部浪费且只在最后
给出指引。

- mining_runtime: require_regime 时在因子面板就绪后立即用与
  artifacts 相同的 fold 口径预构建一次 regime mask (required 区间取
  全部外层 fold 测试窗并集), 数据为空/覆盖不完整即刻带指引消息终止
- MiningWorkbench: 启动前查询 /api/regime/latest, 未计算时侧栏显示
  警告横幅(直达数据页)并在开始时 toast 阻止, 避免产生必败的运行记录
- 测试: 缺数据 fail-fast / 覆盖充足通过 / fold 窗口内缺口报错 三例
This commit is contained in:
shy3130
2026-08-26 12:55:38 +08:00
parent 196af2fa06
commit de51929a44
3 changed files with 129 additions and 2 deletions
+30
View File
@@ -522,6 +522,10 @@ def run_mining_runtime(
"factors": len(request.factor_names),
})
if request.require_regime:
emit({"phase": "panel", "label": "校验市场环境数据", "done": 0, "total": 1})
_validate_regime_availability(panel, request, data_dir)
_raise_if_cancelled(cancel_check)
start_phase()
matrix_started = time.perf_counter()
@@ -1309,6 +1313,32 @@ def _fold_row(
}
def _validate_regime_availability(
panel: pl.DataFrame,
request: RuntimeRequest,
data_dir: Path,
) -> None:
"""搜索开始前 fail-fast 校验市场环境数据。
环境分组评估 (strong/range/weak) 依赖 T-1 市场环境序列; 数据为空或覆盖不足时,
若拖到 artifacts 阶段才在 _regime_date_count 中抛错, 整轮嵌套搜索的计算全部浪费。
这里用与 artifacts 相同的 fold 口径 (panel 标签) 预先构建一次 mask:
required 区间取所有外层 fold 测试窗的并集, 覆盖后续每个 fold 单独调用的要求,
任何 ValueError (数据为空 / 覆盖不完整) 立即带指引消息终止运行。
"""
labels = _date_labels(panel)
nested = generate_nested_folds(labels, request.mining_request.validation)
if not nested:
return
StrategyBacktestService._build_regime_mask(
labels,
_REGIME_FILTERS["strong"],
data_dir,
required_start=date.fromisoformat(nested[0].outer.test_start),
required_end=date.fromisoformat(nested[-1].outer.test_end),
)
def _regime_date_count(
panel: pl.DataFrame,
validation_fold,