You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
2.4 KiB
Python

"""Honest G2 check: recompute relief on V49.91's ACTUAL negative-PnL days only.
Advisor flagged that "worst-20%" of V49's days inflates by including zero-PnL
no-trade days, making the metric partly tautological.
Compares:
- V50 avg daily PnL (all days)
- V50 avg daily PnL on V49's actual loss days (v49_pnl < 0)
- V50 avg daily PnL on V49's actual no-trade days (v49_pnl == 0)
Real anti-correlation = V50 does BETTER on V49 loss days than V50's overall avg.
Just "fills the gap" = V50 does similar on V49 zero days.
"""
from __future__ import annotations
import json
import sys
def main() -> int:
if len(sys.argv) < 3:
print("Usage: honest_g2_check.py V49_PATH V50_PATH")
return 1
with open(sys.argv[1]) as f:
v49 = {r["date"]: float(r["daily_pnl"]) for r in json.load(f)["daily_summary"]}
with open(sys.argv[2]) as f:
v50 = {r["date"]: float(r["day_pnl"]) for r in json.load(f)["daily_results"]}
common = sorted(set(v49) & set(v50))
def stats(label: str, dates: list[str]) -> None:
if not dates:
print(f" {label}: 0 days")
return
v49_vals = [v49[d] for d in dates]
v50_vals = [v50[d] for d in dates]
avg49 = sum(v49_vals) / len(dates)
avg50 = sum(v50_vals) / len(dates)
sum50 = sum(v50_vals)
print(f" {label:36s}: n={len(dates):3d} V49 avg=${avg49:>+7.2f} V50 avg=${avg50:>+7.2f} V50 sum=${sum50:>+7.0f}")
for slice_label, slice_dates in [
("FULL", common),
("TRAIN (2025-H2)", [d for d in common if d <= "2025-12-31"]),
("TEST (2026 YTD)", [d for d in common if d >= "2026-01-01"]),
]:
print(f"\n=== {slice_label} ({len(slice_dates)} days) ===")
stats("All days", slice_dates)
stats("V49 actual loss days (v49<0)", [d for d in slice_dates if v49[d] < 0])
stats("V49 zero-PnL no-trade days", [d for d in slice_dates if v49[d] == 0])
stats("V49 win days (v49>0)", [d for d in slice_dates if v49[d] > 0])
print("\n=== Interpretation ===")
print("If V50 avg on V49-loss-days > V50 avg on all days → real anti-correlation")
print("If V50 avg on V49-loss-days ≈ V50 avg on all days → independent (fills the gap)")
print("If V50 avg on V49-loss-days < V50 avg on all days → mildly correlated (regime alignment)")
return 0
if __name__ == "__main__":
raise SystemExit(main())