feat: market event
This commit is contained in:
@@ -885,19 +885,33 @@ def analyze_event(body: AnalyzeRequest):
|
|||||||
# Évaluation du graphe
|
# Évaluation du graphe
|
||||||
node_values = evaluate_graph(graph, inputs, body.coef_overrides or {})
|
node_values = evaluate_graph(graph, inputs, body.coef_overrides or {})
|
||||||
|
|
||||||
# Lag effectif : max des lag_min/lag_days sur toutes les arêtes menant à un market_asset
|
# Lag effectif : max sur toutes les arêtes du graphe
|
||||||
edges = graph.get("edges", [])
|
# (filtre output_ids optionnel mais peu fiable si types de nœuds non standards)
|
||||||
nodes_map = {n["id"]: n for n in graph.get("nodes", [])}
|
edges = graph.get("edges", [])
|
||||||
|
nodes_map = {n["id"]: n for n in graph.get("nodes", [])}
|
||||||
output_ids = {n["id"] for n in graph.get("nodes", []) if n.get("type") in ("market_asset", "output")}
|
output_ids = {n["id"] for n in graph.get("nodes", []) if n.get("type") in ("market_asset", "output")}
|
||||||
|
|
||||||
|
edges_to_output = [e for e in edges if e.get("to") in output_ids]
|
||||||
|
edges_for_lag = edges_to_output if edges_to_output else edges # fallback : toutes arêtes
|
||||||
|
|
||||||
effective_lag = max(
|
effective_lag = max(
|
||||||
(e.get("lag_min", 0) or 0 for e in edges if e.get("to") in output_ids),
|
(e.get("lag_min", 0) or 0 for e in edges_for_lag),
|
||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
effective_lag_days = max(
|
effective_lag_days = max(
|
||||||
(e.get("lag_days", 0) or 0 for e in edges if e.get("to") in output_ids),
|
(e.get("lag_days", 0) or 0 for e in edges_for_lag),
|
||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Diagnostic : combien d'arêtes portent un lag_days > 0
|
||||||
|
edges_with_lag_days = sum(1 for e in edges if (e.get("lag_days") or 0) > 0)
|
||||||
|
lag_debug = {
|
||||||
|
"output_ids": list(output_ids),
|
||||||
|
"edges_to_output": len(edges_to_output),
|
||||||
|
"edges_with_lag_days": edges_with_lag_days,
|
||||||
|
"used_all_edges": not edges_to_output,
|
||||||
|
}
|
||||||
|
|
||||||
# Instruments : utiliser tous ceux du template si aucun spécifié
|
# Instruments : utiliser tous ceux du template si aucun spécifié
|
||||||
if body.instrument:
|
if body.instrument:
|
||||||
instruments = list({body.instrument} | set(tmpl.get("instruments", [body.instrument])))
|
instruments = list({body.instrument} | set(tmpl.get("instruments", [body.instrument])))
|
||||||
@@ -944,6 +958,7 @@ def analyze_event(body: AnalyzeRequest):
|
|||||||
"prices_mode": prices.get("mode", "none"),
|
"prices_mode": prices.get("mode", "none"),
|
||||||
"effective_lag_min": effective_lag,
|
"effective_lag_min": effective_lag,
|
||||||
"effective_lag_days": effective_lag_days,
|
"effective_lag_days": effective_lag_days,
|
||||||
|
"lag_debug": lag_debug,
|
||||||
"analyzed_at": analyzed_at,
|
"analyzed_at": analyzed_at,
|
||||||
"graph_json": graph, # structure complète pour visualisation frontend
|
"graph_json": graph, # structure complète pour visualisation frontend
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,6 +402,7 @@ function EventDetail({
|
|||||||
pricesMode?: string
|
pricesMode?: string
|
||||||
lagMin?: number
|
lagMin?: number
|
||||||
lagDays?: number
|
lagDays?: number
|
||||||
|
lagDebug?: { output_ids: string[]; edges_to_output: number; edges_with_lag_days: number; used_all_edges: boolean }
|
||||||
} | null>(null)
|
} | null>(null)
|
||||||
const [graphData, setGraphData] = useState<GraphData | null>(null)
|
const [graphData, setGraphData] = useState<GraphData | null>(null)
|
||||||
|
|
||||||
@@ -557,6 +558,7 @@ function EventDetail({
|
|||||||
pricesMode: d.prices_mode,
|
pricesMode: d.prices_mode,
|
||||||
lagMin: d.effective_lag_min,
|
lagMin: d.effective_lag_min,
|
||||||
lagDays: d.effective_lag_days,
|
lagDays: d.effective_lag_days,
|
||||||
|
lagDebug: d.lag_debug,
|
||||||
})
|
})
|
||||||
if (d.graph_json?.nodes?.length) setGraphData(d.graph_json)
|
if (d.graph_json?.nodes?.length) setGraphData(d.graph_json)
|
||||||
await loadAnalyses()
|
await loadAnalyses()
|
||||||
@@ -878,6 +880,7 @@ function EventDetail({
|
|||||||
const lagMin = anResult.lagMin ?? 0
|
const lagMin = anResult.lagMin ?? 0
|
||||||
const lagDays = anResult.lagDays ?? 0
|
const lagDays = anResult.lagDays ?? 0
|
||||||
const driftEntries = Object.entries(anResult.drift ?? {})
|
const driftEntries = Object.entries(anResult.drift ?? {})
|
||||||
|
const dbg = anResult.lagDebug
|
||||||
return (
|
return (
|
||||||
<div className="bg-slate-900/70 border border-slate-700/40 rounded px-3 py-2 space-y-1.5 text-[10px] font-mono">
|
<div className="bg-slate-900/70 border border-slate-700/40 rounded px-3 py-2 space-y-1.5 text-[10px] font-mono">
|
||||||
<div className="flex items-center gap-2 flex-wrap">
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
@@ -895,6 +898,15 @@ function EventDetail({
|
|||||||
{mode !== 'intraday_5m' && lagDays === 0 && (
|
{mode !== 'intraday_5m' && lagDays === 0 && (
|
||||||
<span className="text-slate-600 italic">lag J = 0 (jour J)</span>
|
<span className="text-slate-600 italic">lag J = 0 (jour J)</span>
|
||||||
)}
|
)}
|
||||||
|
{dbg && dbg.used_all_edges && (
|
||||||
|
<span className="text-yellow-500/80 italic">⚠ fallback edges (output_ids vides)</span>
|
||||||
|
)}
|
||||||
|
{dbg && (
|
||||||
|
<span className="text-slate-600">
|
||||||
|
edges→out: <span className="text-slate-400">{dbg.edges_to_output}</span>
|
||||||
|
{' '}| edges lag_j: <span className="text-slate-400">{dbg.edges_with_lag_days}</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{driftEntries.map(([inst, d]) => (
|
{driftEntries.map(([inst, d]) => (
|
||||||
<div key={inst} className="flex items-center gap-2 flex-wrap border-t border-slate-800/60 pt-1.5">
|
<div key={inst} className="flex items-center gap-2 flex-wrap border-t border-slate-800/60 pt-1.5">
|
||||||
|
|||||||
Reference in New Issue
Block a user