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
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useRef, useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useSearchParams } from 'react-router-dom'
import { Link, useSearchParams } from 'react-router-dom'
import {
AlertTriangle,
CheckCircle2,
@@ -303,6 +303,7 @@ export function MiningWorkbench() {
enabled: validDateRange,
staleTime: 30_000,
})
const regimeLatestQuery = useQuery({ queryKey: QK.regimeLatest, queryFn: api.regimeLatest, staleTime: 60_000 })
const configQuery = useQuery({ queryKey: QK.miningConfig, queryFn: api.miningConfig })
useEffect(() => {
@@ -454,6 +455,18 @@ export function MiningWorkbench() {
)
return
}
if (regimeLatestQuery.isPending || regimeLatestQuery.isFetching) {
toast('正在核验市场环境数据,请稍候', 'error')
return
}
if (regimeLatestQuery.isError || !regimeLatestQuery.data) {
toast('无法核验市场环境数据,请检查数据状态后重试', 'error')
return
}
if (!regimeLatestQuery.data.row) {
toast('尚未计算市场环境数据:挖掘含市场环境分组评估,请先在数据页完成市场环境计算', 'error')
return
}
const commissionBps = parseBoundedNumber(draft.commissionBps, '佣金', 0, 500)
const stampTaxBps = parseBoundedNumber(draft.stampTaxBps, '印花税', 0, 500)
const slippageBps = parseBoundedNumber(draft.slippageBps, '滑点', 0, 1000)
@@ -567,6 +580,12 @@ export function MiningWorkbench() {
)}
</section>
{regimeLatestQuery.data && !regimeLatestQuery.data.row && (
<Link to="/data" className="block rounded-btn border border-warning/40 bg-warning/5 px-2 py-1.5 text-[9px] leading-4 text-warning transition-colors hover:border-warning/70">
<span className="underline underline-offset-2"> </span>
</Link>
)}
<section className="border-t border-border pt-3">
<div className="mb-2 flex items-center justify-between">
<span className="flex items-center gap-1.5 text-[10px] font-semibold text-secondary"><FlaskConical className="h-3 w-3" /></span>