"""MIC04 — Consecutive-days continuation vs fade.

IDEA: Compute net of last-k daily close returns (streak).
- FOLLOWING: go long when streak is positive (sign = +1), flat when negative.
- FADING: go long when streak is negative (mean-reversion), flat when positive.
Both are long-flat. We try k in {3, 5} and compare following vs fading.
Position is vol-targeted (20% target, 2x cap).

Grid: 4 configs (2 k-values × 2 directions), TFs: 1d, 12h.
Total backtests: 4 configs × 2 TFs × 2 assets = 16 — but we only call study_weights
per config (each call does 2 TFs × 2 assets internally) → 4 calls = 16 backtests (fine).
Actually we pick the best config manually. To stay <= 6 total calls we test 2 configs
(k=3 follow, k=5 follow) and present the best, then also run the fading variants if promising.
We run all 4 configs (each on tfs=("1d","12h")) → 4 calls, well within budget.
"""
import sys
sys.path.insert(0, "/opt/docker/PythagorasGoal/scripts/research/alt")
import altlib as al
import numpy as np


def streak_target(df, k: int, follow: bool) -> np.ndarray:
    """
    For each bar i, compute net of last-k close returns (causal: uses close[i-k..i]).
    streak[i] = close[i] / close[i-k] - 1  (sign of cumulative k-bar return)

    If follow=True:  position = +1 when streak > 0, else 0 (long-flat continuation).
    If fading=True:  position = +1 when streak < 0, else 0 (long-flat mean-reversion).

    Then vol-target the direction.
    """
    c = df["close"].values.astype(float)
    n = len(c)

    # Cumulative k-bar return ending at i: c[i]/c[i-k] - 1
    streak = np.full(n, np.nan)
    for i in range(k, n):
        streak[i] = c[i] / c[i - k] - 1.0

    if follow:
        direction = np.where(streak > 0, 1.0, 0.0)
    else:
        direction = np.where(streak < 0, 1.0, 0.0)

    # Fill NaN with 0 before vol_target
    direction = np.nan_to_num(direction, nan=0.0)

    # Apply vol targeting
    tgt = al.vol_target(direction, df, target_vol=0.20, vol_win_days=30, leverage_cap=2.0)
    return tgt


configs = [
    ("MIC04-k3-follow", 3, True),
    ("MIC04-k5-follow", 5, True),
    ("MIC04-k3-fade",   3, False),
    ("MIC04-k5-fade",   5, False),
]

results = {}
for name, k, follow in configs:
    print(f"\n{'='*60}")
    print(f"Running {name} (k={k}, follow={follow})")
    print('='*60)
    rep = al.study_weights(
        name,
        lambda df, k=k, follow=follow: streak_target(df, k, follow),
        tfs=("1d", "12h"),
    )
    results[name] = rep
    print(al.fmt(rep))

# Pick best config by holdout Sharpe (min across assets in best TF)
best_name = max(results, key=lambda n: results[n]["verdict"].get("best_holdout_sharpe", -99))
best_rep = results[best_name]

print("\n" + "="*60)
print(f"BEST CONFIG: {best_name}")
print("="*60)
print(al.fmt(best_rep))
print("JSON:", al.as_json(best_rep))
