#!/usr/bin/env python3
"""
ALPHA HUNTER v5 - FIXED equity tracking
"""

import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')

RESULTS_DIR = "/home/node/.openclaw/workspace/crypto-wallet/backtest"
INITIAL_CAPITAL = 10_000
COMMISSION = 0.001

print("=" * 70)
print("🧙‍♂️ ALPHA HUNTER v5 - FIXED EQUITY")
print("=" * 70)

df = pd.read_csv(f"{RESULTS_DIR}/btc_ohlcv_2024_2025.csv", parse_dates=["timestamp"], index_col="timestamp")
print(f"📊 {len(df)} candles")

# FEATURES
df["body"] = df["close"] - df["open"]
df["buy_vol"] = np.where(df["body"] > 0, df["volume"] * 0.7, df["volume"] * 0.3)
df["sell_vol"] = df["volume"] - df["buy_vol"]
df["delta"] = df["buy_vol"] - df["sell_vol"]
df["delta_ma"] = df["delta"].rolling(20).mean()
df["delta_div"] = df["delta"] - df["delta_ma"]
df["delta_std"] = df["delta_div"].rolling(50).std()

df["vol_ma"] = df["volume"].rolling(20).mean()
df["vol_z"] = (df["volume"] - df["vol_ma"]) / df["volume"].rolling(50).std()

df["mom_1h"] = df["close"].pct_change(1)
df["mom_4h"] = df["close"].pct_change(4)
df["mom_24h"] = df["close"].pct_change(24)

df["funding"] = df["mom_24h"] * 10
df["funding_abs"] = np.abs(df["funding"])

df["atr"] = (df["high"] - df["low"]).rolling(14).mean()
df["atr_ratio"] = df["atr"] / df["close"]
df["squeeze"] = (df["atr_ratio"] < df["atr_ratio"].rolling(100).quantile(0.15)).astype(int)
df["vol_spike"] = (df["volume"] > df["vol_ma"] * 2).astype(int)
df["liq_sq"] = (df["squeeze"] & df["vol_spike"]).astype(int)

df["vpin"] = np.abs(df["delta"]) / df["vol_ma"].rolling(50).mean()
df["vpin_ma"] = df["vpin"].rolling(20).mean()

df["bull_all"] = ((df["mom_1h"] > 0) & (df["mom_4h"] > 0) & (df["mom_24h"] > 0)).astype(int)
df["bear_all"] = ((df["mom_1h"] < 0) & (df["mom_4h"] < 0) & (df["mom_24h"] < 0)).astype(int)

df["up_bar"] = (df["close"] > df["open"]).astype(int)
df["acc"] = df["up_bar"] * df["volume"] / df["vol_ma"]

df["vol_regime"] = df["atr_ratio"].rolling(24).mean()
df["low_vol"] = (df["vol_regime"] < df["vol_regime"].quantile(0.25)).astype(int)
df["high_vol"] = (df["vol_regime"] > df["vol_regime"].quantile(0.75)).astype(int)

print("✅ Features ready")

# BACKTEST (with proper equity tracking)
def backtest(df, name, long_cond_fn, short_cond_fn, max_h=36, sl=0.02, tp=0.04):
    df_w = df.dropna().copy().reset_index()
    N = len(df_w)
    
    capital = INITIAL_CAPITAL
    position = 0  # 0=flat, 1=long, -1=short
    entry_price = 0
    entry_idx = 0
    trades = []
    
    prices = df_w["close"].values
    
    # Equity at each bar (mark-to-market)
    equity = np.full(N, INITIAL_CAPITAL)
    trade_active = False
    
    for i in range(1, N):
        price = prices[i]
        
        # Update equity if in position (mark-to-market)
        if position != 0:
            if position == 1:
                mtm = (price - entry_price) / entry_price
            else:
                mtm = (entry_price - price) / entry_price
            equity[i] = capital * (1 + mtm)
        else:
            equity[i] = capital
        
        # Check signal
        signal = 0
        if long_cond_fn(df_w, i): signal = 1
        elif short_cond_fn(df_w, i): signal = -1
        
        # Entry
        if position == 0 and signal == 1:
            position = 1
            entry_price = price
            entry_idx = i
        elif position == 0 and signal == -1:
            position = -1
            entry_price = price
            entry_idx = i
        
        # Exit checks
        if position != 0:
            held = i - entry_idx
            if position == 1:
                pnl = (price - entry_price) / entry_price
            else:
                pnl = (entry_price - price) / entry_price
            
            if held >= max_h or pnl <= -sl or pnl >= tp:
                capital *= (1 + pnl - COMMISSION)
                trades.append({"type": "LONG" if position == 1 else "SHORT", "pnl": pnl, "held": held})
                position = 0
    
    # Close final position
    if position != 0:
        price = prices[-1]
        if position == 1:
            pnl = (price - entry_price) / entry_price
        else:
            pnl = (entry_price - price) / entry_price
        capital *= (1 + pnl - COMMISSION)
    
    equity[-1] = capital
    
    # Metrics
    returns = np.diff(equity) / equity[:-1]
    returns = returns[~np.isnan(returns) & ~np.isinf(returns)]
    
    sharpe = 0
    if returns.std() > 0:
        sharpe = returns.mean() / returns.std() * np.sqrt(365 * 24)
    
    max_dd = 0
    running_max = np.maximum.accumulate(equity)
    drawdown = (equity - running_max) / running_max
    max_dd = np.min(drawdown) * 100
    
    winners = sum(1 for t in trades if t["pnl"] > 0)
    
    return {
        "strategy": name,
        "return": round((capital - INITIAL_CAPITAL) / INITIAL_CAPITAL * 100, 1),
        "sharpe": round(sharpe, 2),
        "trades": len(trades),
        "win_rate": round(winners / len(trades) * 100, 0) if trades else 0,
        "max_dd": round(max_dd, 1),
        "equity": equity.tolist()
    }

results = []

# STRATEGY 1: Funding Timing
print("Funding Timing...")
for h in [24, 36, 48]:
    for sl in [0.015, 0.02, 0.025]:
        for tp in [0.03, 0.04, 0.05]:
            def lc(d, i): return d.iloc[i]["funding_abs"] < 0.002 and d.iloc[i]["mom_1h"] > 0
            def sc(d, i): return d.iloc[i]["funding_abs"] < 0.002 and d.iloc[i]["mom_1h"] < 0
            r = backtest(df, f"Funding_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# STRATEGY 2: Squeeze
print("Squeeze...")
for h in [24, 36, 48]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            def lc(d, i): return d.iloc[i]["liq_sq"] == 1 and d.iloc[i]["bull_all"] == 1
            def sc(d, i): return d.iloc[i]["liq_sq"] == 1 and d.iloc[i]["bear_all"] == 1
            r = backtest(df, f"Squeeze_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# STRATEGY 3: VPIN
print("VPIN...")
for h in [24, 36]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            def lc(d, i): return d.iloc[i]["vpin"] > d.iloc[i]["vpin_ma"] * 1.5 and d.iloc[i]["mom_4h"] > 0.002
            def sc(d, i): return d.iloc[i]["vpin"] > d.iloc[i]["vpin_ma"] * 1.5 and d.iloc[i]["mom_4h"] < -0.002
            r = backtest(df, f"VPIN_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# STRATEGY 4: Regime
print("Regime...")
for h in [24, 36, 48]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            def lc(d, i): return d.iloc[i]["low_vol"] == 1 and d.iloc[i]["mom_1h"] > 0 and d.iloc[i]["delta_div"] > 0
            def sc(d, i): return d.iloc[i]["high_vol"] == 1 and d.iloc[i]["mom_1h"] < 0 and d.iloc[i]["delta_div"] < 0
            r = backtest(df, f"Regime_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# STRATEGY 5: Delta+Trend
print("Delta+Trend...")
for h in [36, 48]:
    for sl in [0.02, 0.025, 0.03]:
        for tp in [0.04, 0.05]:
            def lc(d, i):
                q = d["delta_div"].iloc[max(0,i-500):i].quantile(0.9) if i > 500 else d["delta_div"].quantile(0.9)
                return d.iloc[i]["delta_div"] > q and d.iloc[i]["mom_4h"] > 0.002
            def sc(d, i):
                q = d["delta_div"].iloc[max(0,i-500):i].quantile(0.1) if i > 500 else d["delta_div"].quantile(0.1)
                return d.iloc[i]["delta_div"] < q and d.iloc[i]["mom_4h"] < -0.002
            r = backtest(df, f"DeltaTrend_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# STRATEGY 6: Accumulation
print("Accumulation...")
for h in [36, 48, 60]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            def lc(d, i): return d.iloc[i]["acc"] > 1.5 and d.iloc[i]["delta_div"] > 0 and d.iloc[i]["funding_abs"] < 0.003
            def sc(d, i): return d.iloc[i]["acc"] < 0.5 and d.iloc[i]["delta_div"] < 0 and d.iloc[i]["funding_abs"] > 0.005
            r = backtest(df, f"Accum_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# STRATEGY 7: Triple Combo
print("Triple Combo...")
for h in [24, 36, 48]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            def lc(d, i):
                row = d.iloc[i]
                score = int(row["funding_abs"] < 0.003) + int(row["delta_div"] > row["delta_std"] * 1.5) + int(row["liq_sq"] == 1) + int(row["mom_4h"] > 0)
                return score >= 3
            def sc(d, i):
                row = d.iloc[i]
                score = int(row["funding_abs"] < 0.003) + int(row["delta_div"] < -row["delta_std"] * 1.5) + int(row["liq_sq"] == 1) + int(row["mom_4h"] < 0)
                return score >= 3
            r = backtest(df, f"Triple_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# STRATEGY 8: VolMom
print("VolMom...")
for h in [24, 36]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            def lc(d, i): return d.iloc[i]["vol_z"] > 2 and d.iloc[i]["mom_4h"] > 0.003
            def sc(d, i): return d.iloc[i]["vol_z"] > 2 and d.iloc[i]["mom_4h"] < -0.003
            r = backtest(df, f"VolMom_T{h}_SL{sl}_TP{tp}", lc, sc, h, sl, tp)
            results.append(r)

# ─── RESULTS ────────────────────────────────────────────────────────────────

print("\n" + "=" * 70)
print("🏆 TOP 25 STRATEGIES (by Sharpe)")
print("=" * 70)

sorted_results = sorted(results, key=lambda x: x["sharpe"], reverse=True)

for i, r in enumerate(sorted_results[:25], 1):
    emoji = "🎯" if r["sharpe"] > 2 else "📊" if r["sharpe"] > 0 else "❌"
    print(f"  {emoji} {i:2d}. {r['strategy']:35s} | Sharpe: {r['sharpe']:+.2f} | Return: {r['return']:+.1f}% | Trades: {r['trades']:3d} | Win: {r['win_rate']:.0f}% | DD: {r['max_dd']:.1f}%")

best = sorted_results[0]
print(f"\n🥇 BEST: {best['strategy']}")
print(f"   Sharpe: {best['sharpe']} | Return: {best['return']}% | Trades: {best['trades']} | Win: {best['win_rate']}%")

# Save
results_df = pd.DataFrame([{k: v for k, v in r.items() if k != 'equity'} for r in sorted_results])
results_df.to_csv(f"{RESULTS_DIR}/alpha_hunter_results.csv", index=False)

# Save best equity curve
best_eq_df = pd.DataFrame({"timestamp": df.dropna().reset_index()["timestamp"][:len(best["equity"])], "equity": best["equity"]})
best_eq_df.to_csv(f"{RESULTS_DIR}/alpha_hunter_best_equity.csv", index=False)

print(f"\n✅ Saved to {RESULTS_DIR}/alpha_hunter_results.csv")
