fix: compute surprise_pct from actual/expected when NULL for auto-analysis scoring
Events with surprise_pct=NULL (bootstrap or older events) got inputs={} → evaluate_graph
returned {} → prediction_json='{}' → all scores showed 'En attente'.
Three-step fallback in _run_auto_analysis:
1. Use event.surprise_pct if set (existing behaviour)
2. Compute from actual_value / expected_value stored in market_events
3. Look up most recent ff_calendar release by currency + date
Frontend diagnostic now shows surprise_pct per event and exposes actual/expected
in the refresh result panel to make the source visible.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1028,7 +1028,7 @@ function ExplanationScore({
|
||||
// For each linked event, compute the comprehension score and collect scored ones
|
||||
const scored: number[] = []
|
||||
const totalLinked: number[] = []
|
||||
const debugRows: {id?: number; name: string; pred: string; actual: string; score: number | null; reason: string}[] = []
|
||||
const debugRows: {id?: number; name: string; pred: string; actual: string; score: number | null; reason: string; surprisePct?: number | null}[] = []
|
||||
|
||||
for (const ev of events) {
|
||||
if (!ev.template_id) continue
|
||||
@@ -1062,6 +1062,7 @@ function ExplanationScore({
|
||||
pred: hasPred ? '✓' : '✗',
|
||||
actual: hasActual ? '✓' : '✗',
|
||||
score: null, reason,
|
||||
surprisePct: ev.surprise_pct ?? null,
|
||||
})
|
||||
|
||||
const s = comprehensionScore(ev, tmpl, inst)
|
||||
@@ -1136,9 +1137,12 @@ function ExplanationScore({
|
||||
<div key={i} className="flex gap-2 py-0.5 border-b border-slate-800/40 last:border-0">
|
||||
<span className={clsx('shrink-0 w-4', r.pred === '✓' ? 'text-emerald-600' : 'text-red-600')}>{r.pred}</span>
|
||||
<span className={clsx('shrink-0 w-4', r.actual === '✓' ? 'text-emerald-600' : 'text-red-600')}>{r.actual}</span>
|
||||
<span className="text-slate-400 w-36 shrink-0 truncate" title={r.name}>{r.name}</span>
|
||||
<span className="text-slate-400 w-32 shrink-0 truncate" title={r.name}>{r.name}</span>
|
||||
<span className={clsx('flex-1', r.reason === 'ok' ? 'text-emerald-600' : 'text-amber-600')}>{r.reason}</span>
|
||||
{r.score != null && <span className="text-violet-400">{r.score}%</span>}
|
||||
{r.surprisePct != null
|
||||
? <span className="text-cyan-600 shrink-0">{r.surprisePct > 0 ? '+' : ''}{r.surprisePct.toFixed(1)}%</span>
|
||||
: <span className="text-red-800 shrink-0">surp?</span>}
|
||||
{r.score != null && <span className="text-violet-400 shrink-0">{r.score}%</span>}
|
||||
</div>
|
||||
))}
|
||||
{debugInfo && (
|
||||
@@ -1149,8 +1153,12 @@ function ExplanationScore({
|
||||
}
|
||||
{debugInfo.details?.map((d: any, i: number) => (
|
||||
<div key={i} className="mt-0.5">
|
||||
#{d.event_id} {(d.event_name ?? '').slice(0, 25)} → <span className={d.result === 'ok' ? 'text-emerald-600' : 'text-red-500'}>{d.result}</span>
|
||||
{d.surprise_pct != null && <span className="text-slate-500 ml-1">surp:{d.surprise_pct}</span>}
|
||||
#{d.event_id} {(d.event_name ?? '').slice(0, 22)} → <span className={d.result === 'ok' ? 'text-emerald-600' : 'text-red-500'}>{d.result}</span>
|
||||
{d.surprise_pct != null
|
||||
? <span className="text-cyan-700 ml-1">surp:{Number(d.surprise_pct).toFixed(1)}%</span>
|
||||
: d.actual_value != null
|
||||
? <span className="text-amber-700 ml-1">act:{d.actual_value} exp:{d.expected_value ?? '?'}</span>
|
||||
: <span className="text-red-800 ml-1">surp=null</span>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user