diff --git a/backend/services/wavelet_engine.py b/backend/services/wavelet_engine.py index 66b957c..1fd2a07 100644 --- a/backend/services/wavelet_engine.py +++ b/backend/services/wavelet_engine.py @@ -616,14 +616,29 @@ def wavelet_reliability( # showed up (earliest match) — compared against avg_cycle_days below to check # whether "one cycle" is actually a well-calibrated horizon, or systematically # too long/short relative to how quickly a real reversal actually confirms. - actual_delay = (min(matches) - d_pos) if confirmed else None - tested.append({"date": d_date, "confirmed": confirmed, "actual_delay_days": actual_delay}) + actual_delay = None + height_diff = None + if confirmed: + confirm_idx = min(matches) + actual_delay = confirm_idx - d_pos + # Direction agreeing doesn't mean the peak/trough had the same amplitude — + # the live (causal) reading can be a real reversal but distorted in height by + # edge effects. Compare the band's own value at the original causal turning + # point against its value at the confirming point in the hindsight + # reconstruction (same units as the band, e.g. price terms). + height_diff = abs(band["series"][t] - h_series[confirm_idx]) + tested.append({ + "date": d_date, "confirmed": confirmed, + "actual_delay_days": actual_delay, "height_diff": height_diff, + }) n_tested = len(tested) n_confirmed = sum(1 for t in tested if t["confirmed"]) delays = [t["actual_delay_days"] for t in tested if t["actual_delay_days"] is not None] avg_actual_delay = round(sum(delays) / len(delays), 1) if delays else None calibration_gap = round(sum(abs(avg_cycle_days - d) for d in delays) / len(delays), 1) if delays else None + heights = [t["height_diff"] for t in tested if t["height_diff"] is not None] + avg_height_diff = round(sum(heights) / len(heights), 6) if heights else None bands_out.append({ "label": band["label"], "n_tested": n_tested, @@ -633,6 +648,7 @@ def wavelet_reliability( "confirm_horizon": confirm_horizon, "avg_actual_delay_days": avg_actual_delay, "calibration_gap_days": calibration_gap, + "avg_height_diff": avg_height_diff, "turns": tested, }) diff --git a/frontend/src/pages/InstrumentDashboard.tsx b/frontend/src/pages/InstrumentDashboard.tsx index b30b6cb..bc2c4d3 100644 --- a/frontend/src/pages/InstrumentDashboard.tsx +++ b/frontend/src/pages/InstrumentDashboard.tsx @@ -2389,6 +2389,7 @@ export default function InstrumentDashboard({ instrumentIdProp, isVisible }: { i