"""XS06b — Correlation-to-market diversifier.

Score = -rolling_corr(asset_ret, market_ret, 60)
Long the assets LEAST correlated to the equal-weight market (the "divergers"),
short the most-correlated ones. win=60 days.

Idea: if cross-sectional momentum (XS01) selects by recent past return, this
selects by structural independence from the pack — a fundamentally different
axis. The two should be weakly correlated.
"""
import sys
sys.path.insert(0, "/opt/docker/PythagorasGoal/scripts/research/xsec")
import xslib as xs
import numpy as np
import pandas as pd


def score_corr_diversifier(P, win=60):
    """Score = -rolling_corr(asset_ret, market_ret, win). Causal."""
    n, A = P.ret.shape
    mkt = xs.market_ret(P.ret)  # (n,) equal-weight market

    out = np.full((n, A), np.nan)
    mkt_s = pd.Series(mkt)

    for a in range(A):
        asset_s = pd.Series(P.ret[:, a])
        # rolling correlation — pandas rolling corr is causal
        corr = asset_s.rolling(win, min_periods=max(10, win // 2)).corr(mkt_s)
        # score = NEGATIVE correlation: higher => less correlated => long
        out[:, a] = -corr.values

    return out


# ---------------------------------------------------------------------------
# Grid: 5 study_xs calls max
#   - vary universe (all vs majors)
#   - vary H (rebalance freq)
#   - vary long_short
# ---------------------------------------------------------------------------

print("=" * 70)
print("XS06b — Correlation-to-market diversifier (score = -roll_corr_60)")
print("=" * 70)

best = None
best_earns = False
best_ho = -999

configs = [
    # (label_suffix, universe, H, k, long_short)
    ("all_H10_k5_ls",   "all",     10, 5, True),
    ("maj_H10_k5_ls",   "majors",  10, 5, True),
    ("all_H5_k5_ls",    "all",      5, 5, True),
    ("all_H10_k5_lo",   "all",     10, 5, False),
    ("all_H20_k5_ls",   "all",     20, 5, True),
]

results = []
for (suffix, universe, H, k, ls) in configs:
    name = f"XS06b_{suffix}"
    print(f"\n--- {name} ---")
    rep = xs.study_xs(
        name,
        lambda P: score_corr_diversifier(P, win=60),
        universe=universe,
        H=H,
        k=k,
        long_short=ls,
        target_vol=0.20,
    )
    print(xs.fmt(rep))
    print("JSON:", xs.as_json(rep))
    results.append(rep)

    # track best: earns_slot first, then hold-out sharpe
    earns = rep.get("earns_slot", False)
    ho_sh = rep.get("holdout", {}).get("sharpe", -999)
    if (earns and not best_earns) or (earns == best_earns and ho_sh > best_ho):
        best = rep
        best_earns = earns
        best_ho = ho_sh

print("\n" + "=" * 70)
print("BEST CONFIG:")
print(xs.fmt(best))
print("JSON:", xs.as_json(best))
