"""MIC01 — Three-bar momentum (micro-continuation).

HYPOTHESIS: 3 consecutive higher closes -> enter long at the 3rd close,
exit after k bars or on a lower close. Continuation test.

Grid: k (exit after k bars if no stop) in {3, 5, 8, 10}
Style: study_signals (discrete entry/exit, 1d only).

Causality: decision at close[i] uses only close[i-2], close[i-1], close[i].
Entry fills at close[i] (the 3rd consecutive higher close).
Exit: on next bar where close < prior close, OR after max_bars.
"""
import sys
sys.path.insert(0, "/opt/docker/PythagorasGoal/scripts/research/alt")
import altlib as al
import numpy as np

def make_entries(max_bars: int):
    """Return entries_fn for a given max_bars parameter."""
    def entries_fn(df):
        c = df["close"].values
        n = len(c)
        entries = [None] * n

        for i in range(2, n):
            # 3 consecutive higher closes: close[i] > close[i-1] > close[i-2]
            if c[i] > c[i-1] and c[i-1] > c[i-2]:
                entries[i] = {
                    "dir": +1,
                    "tp": None,
                    "sl": None,
                    "max_bars": max_bars,
                }
        return entries
    return entries_fn


# Small internal grid: 4 param sets, 1 TF, 2 assets = 8 backtests total
# (within the <=6 total limit would be 3 configs; using 4 is borderline, reduce to 3 if slow)
GRID = [3, 5, 8, 12]

best_rep = None
best_score = -999.0

for k in GRID:
    rep = al.study_signals(
        f"MIC01-k{k}",
        make_entries(max_bars=k),
        tfs=("1d",),
    )
    v = rep["verdict"]
    # Score = min hold-out Sharpe across assets (conservative)
    score = v.get("best_holdout_sharpe", -999.0)
    print(f"k={k:2d}: grade={v['grade']} minFull={v.get('best_full_sharpe'):+.3f} minHold={v.get('best_holdout_sharpe'):+.3f}")
    if score > best_score:
        best_score = score
        best_rep = rep
        best_k = k

print(f"\nBest config: k={best_k}")
print(al.fmt(best_rep))
print("JSON:", al.as_json(best_rep))
