"""
check_overlaps.py
=================
Checks whether the backtest takes OVERLAPPING positions within the same pair —
which the live system CANNOT do (one position per pair at a time).

For each pair, walk trades in entry order. Flag any trade whose entry is before
the previous (same-pair) trade's exit. Those are trades live would have SKIPPED.

If overlaps exist, the backtest overstates frequency/returns and mis-models
floating DD vs what you can actually execute — and v4/governor results need
re-running on a one-position-per-pair-filtered set.
"""
import csv, sys
from pathlib import Path
from datetime import datetime, timedelta

def resolve_base():
    for b in [Path(r"C:\Users\Administrator\OneDrive\fx_macro_intraday"),
              Path(r"C:\Users\paul_\OneDrive\fx_macro_intraday")]:
        if b.exists(): return b
    sys.exit("base not found")
BASE=resolve_base()
EU_HOLD_H=52; UJ_HOLD_H=24

def parse_dt(s):
    s=(s or "").strip()
    for f in ("%Y-%m-%d %H:%M:%S","%Y-%m-%d %H:%M","%d/%m/%Y %H:%M"):
        try: return datetime.strptime(s[:19], f)
        except ValueError: continue
    return None

def check(path, has_exit, label, hold_h):
    rows=[]
    with open(path, newline="", encoding="utf-8-sig") as f:
        for r in csv.DictReader(f):
            e=parse_dt(r.get("entry_time"))
            if e is None: continue
            if has_exit:
                x=parse_dt(r.get("exit_time")) or (e+timedelta(hours=hold_h))
            else:
                x=e+timedelta(hours=hold_h)   # UJ: approx exit
            rows.append((e,x))
    rows.sort(key=lambda t:t[0])
    overlaps=0; max_concurrent=1; examples=[]
    last_exit=None
    for (e,x) in rows:
        if last_exit is not None and e < last_exit:
            overlaps+=1
            if len(examples)<5:
                examples.append((e,last_exit))
        # advance last_exit to the later of current exit (chain)
        last_exit = x if last_exit is None else max(last_exit, x) if e<last_exit else x
    print(f"\n{label}: {len(rows)} trades")
    print(f"  Same-pair overlapping entries (live would SKIP these): {overlaps}")
    if has_exit:
        print(f"  (exit_time is REAL)")
    else:
        print(f"  (exit_time APPROXIMATED as entry+{hold_h}h — overlap count is approximate)")
    for (e,le) in examples:
        print(f"    overlap: entry {e} while prior still open until {le}")
    return overlaps, len(rows)

print("="*68)
print("ONE-POSITION-PER-PAIR CHECK")
print("="*68)
eu_o, eu_n = check(BASE/"data"/"processed"/"trades"/"trades_real_costs.csv",
                   True, "EURUSD", EU_HOLD_H)
uj_o, uj_n = check(BASE/"data"/"processed"/"usdjpy_trades_real_costs.csv",
                   False, "USDJPY", UJ_HOLD_H)
print("\n" + "="*68)
print(f"EU overlaps: {eu_o}/{eu_n} ({100*eu_o/eu_n:.1f}%)")
print(f"UJ overlaps: {uj_o}/{uj_n} ({100*uj_o/uj_n:.1f}%)")
if eu_o>0 or uj_o>0:
    print("\n>>> Backtest TAKES trades live cannot (overlapping same-pair).")
    print(">>> v4/governor should be re-run on a one-position-per-pair filtered set.")
else:
    print("\n>>> No same-pair overlaps. Backtest already respects the constraint.")
    print(">>> v4 numbers stand as-is.")
print("="*68)
