feat: instrument model
This commit is contained in:
@@ -1639,6 +1639,22 @@ def simulate_timeline(
|
||||
vals_struct = evaluate_graph(gj_struct, inputs_struct)
|
||||
static_structural = round(float(vals_struct.get(output_id, 0.0)), 1)
|
||||
|
||||
# Unités par nœud input_manual — pour corriger les valeurs brutes de ff_calendar
|
||||
# (NFP: raw=228000 → attendu=228 K; PMI: raw=54.7 → attendu=4.7 pts écart/50)
|
||||
macro_node_units: dict[str, str] = {
|
||||
n["id"]: n.get("unit", "")
|
||||
for n in graph_def.get("nodes", [])
|
||||
if n.get("node_type") == "input_manual"
|
||||
}
|
||||
|
||||
def _unit_correct(v: float, unit: str) -> float:
|
||||
"""Convertit les valeurs brutes ff_calendar en valeur attendue par le nœud."""
|
||||
if unit == "K" and abs(v) >= 1_000:
|
||||
return round(v / 1_000, 1)
|
||||
if unit == "pts" and v > 10:
|
||||
return round(v - 50.0, 1)
|
||||
return v
|
||||
|
||||
# ── Auto-anchor : offset pour que la synthétique parte du prix réel à date_from ──
|
||||
# Calculé une seule fois sur le prix réel à date_from (ou le plus proche disponible).
|
||||
# Cet offset compense l'écart de calibration sans changer la dynamique du modèle.
|
||||
@@ -1660,6 +1676,7 @@ def simulate_timeline(
|
||||
# Valeur la plus proche avant date_from
|
||||
v = next((tl[d] for d in sorted(tl) if d <= str(date_from)), next(iter(tl.values()), None))
|
||||
if v is not None:
|
||||
v = _unit_correct(v, macro_node_units.get(node_id, ""))
|
||||
anchor_overrides[node_id] = {"value": v, "note": "anchor", "set_at": ""}
|
||||
gj_a = _graph_json_for_eval(graph_def, {})
|
||||
in_a = _build_inputs(graph_def, anchor_overrides, {}, saturation=True)
|
||||
@@ -1677,7 +1694,7 @@ def simulate_timeline(
|
||||
for node_id, tl in macro_node_timelines.items():
|
||||
v0 = tl.get(str(date_from))
|
||||
if v0 is not None:
|
||||
macro_last[node_id] = v0
|
||||
macro_last[node_id] = _unit_correct(v0, macro_node_units.get(node_id, ""))
|
||||
|
||||
# Catégories d'events gérées par les nœuds input_event du graphe
|
||||
# Les catégories sans nœud correspondant sont appliquées comme choc direct sur l'output.
|
||||
@@ -1733,6 +1750,7 @@ def simulate_timeline(
|
||||
for node_id, tl in macro_node_timelines.items():
|
||||
v = tl.get(cur_str)
|
||||
if v is not None:
|
||||
v = _unit_correct(v, macro_node_units.get(node_id, ""))
|
||||
macro_last[node_id] = v
|
||||
else:
|
||||
v = macro_last.get(node_id) # gap-fill (weekend)
|
||||
|
||||
Reference in New Issue
Block a user