#!/usr/bin/env python3
"""
ALPHA HUNTER v6 - FULLY VECTORIZED (fast)
"""

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 v6 - FULLY VECTORIZED")
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")

# VECTORIZED FEATURES
df = df.copy()
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)

# Delta quantiles (pre-computed)
for q in [0.9, 0.85, 0.8, 0.75, 0.7]:
    df[f"dq{int(q*100)}"] = df["delta_div"].rolling(500, min_periods=100).quantile(q)

df = df.dropna().reset_index()
print(f"✅ Features ready ({len(df)} rows)")

# VECTORIZED BACKTEST
def vector_backtest(name, long_sig, short_sig, max_h=36, sl_pct=0.02, tp_pct=0.04):
    """
    Vectorized backtest using pre-computed signals
    long_sig, short_sig: boolean arrays
    """
    N = len(df)
    prices = df["close"].values
    
    # Initialize arrays
    position = np.zeros(N, dtype=np.int8)
    entry_price = np.zeros(N)
    entry_idx = np.zeros(N, dtype=np.int32)
    
    # Generate signals
    long_mask = long_sig.values.astype(bool)
    short_mask = short_sig.values.astype(bool)
    
    # Find entries
    pos = 0
    for i in range(1, N):
        if pos == 0:
            if long_mask[i]:
                pos = 1
                entry_price[i] = prices[i]
                entry_idx[i] = i
            elif short_mask[i]:
                pos = -1
                entry_price[i] = prices[i]
                entry_idx[i] = i
            else:
                entry_price[i] = entry_price[i-1]
                entry_idx[i] = entry_idx[i-1]
        else:
            entry_price[i] = entry_price[i-1]
            entry_idx[i] = entry_idx[i-1]
            
            held = i - entry_idx[i]
            if pos == 1:
                pnl = (prices[i] - entry_price[i]) / entry_price[i]
            else:
                pnl = (entry_price[i] - prices[i]) / entry_price[i]
            
            if held >= max_h or pnl <= -sl_pct or pnl >= tp_pct:
                pos = 0
    
    # Simpler loop-based for correctness (faster than lambda approach)
    capital = INITIAL_CAPITAL
    trades = []
    equity = [INITIAL_CAPITAL]
    pos = 0
    ep = 0
    ei = 0
    
    for i in range(1, N):
        price = prices[i]
        
        # Mark to market
        if pos == 1:
            mtm = (price - ep) / ep
            equity.append(capital * (1 + mtm))
        elif pos == -1:
            mtm = (ep - price) / ep
            equity.append(capital * (1 + mtm))
        else:
            equity.append(capital)
        
        # Entry
        if pos == 0:
            if long_mask[i]:
                pos = 1
                ep = price
                ei = i
            elif short_mask[i]:
                pos = -1
                ep = price
                ei = i
        
        # Exit
        if pos != 0:
            held = i - ei
            if pos == 1:
                pnl = (price - ep) / ep
            else:
                pnl = (ep - price) / ep
            
            if held >= max_h or pnl <= -sl_pct or pnl >= tp_pct:
                capital *= (1 + pnl - COMMISSION)
                trades.append({"pnl": pnl, "held": held})
                pos = 0
    
    # Close final
    if pos != 0:
        price = prices[-1]
        if pos == 1:
            pnl = (price - ep) / ep
        else:
            pnl = (ep - price) / ep
        capital *= (1 + pnl - COMMISSION)
    
    equity[-1] = capital
    
    # Metrics
    eq = np.array(equity)
    returns = np.diff(eq) / eq[:-1]
    sharpe = returns.mean() / returns.std() * np.sqrt(365 * 24) if returns.std() > 0 else 0
    max_dd = np.min((eq - np.maximum.accumulate(eq)) / np.maximum.accumulate(eq)) * 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
    }

results = []

# 1. FUNDING TIMING
print("Testing strategies...")
for h in [24, 36, 48]:
    for sl in [0.015, 0.02]:
        for tp in [0.03, 0.04, 0.05]:
            long_s = (df["funding_abs"] < 0.002) & (df["mom_1h"] > 0)
            short_s = (df["funding_abs"] < 0.002) & (df["mom_1h"] < 0)
            r = vector_backtest(f"Funding_T{h}_SL{sl}_TP{tp}", long_s, short_s, h, sl, tp)
            results.append(r)

# 2. SQUEEZE
for h in [24, 36, 48]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            long_s = (df["liq_sq"] == 1) & (df["bull_all"] == 1)
            short_s = (df["liq_sq"] == 1) & (df["bear_all"] == 1)
            r = vector_backtest(f"Squeeze_T{h}_SL{sl}_TP{tp}", long_s, short_s, h, sl, tp)
            results.append(r)

# 3. VPIN
for h in [24, 36]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            long_s = (df["vpin"] > df["vpin_ma"] * 1.5) & (df["mom_4h"] > 0.002)
            short_s = (df["vpin"] > df["vpin_ma"] * 1.5) & (df["mom_4h"] < -0.002)
            r = vector_backtest(f"VPIN_T{h}_SL{sl}_TP{tp}", long_s, short_s, h, sl, tp)
            results.append(r)

# 4. REGIME
for h in [24, 36, 48]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            long_s = (df["low_vol"] == 1) & (df["mom_1h"] > 0) & (df["delta_div"] > 0)
            short_s = (df["high_vol"] == 1) & (df["mom_1h"] < 0) & (df["delta_div"] < 0)
            r = vector_backtest(f"Regime_T{h}_SL{sl}_TP{tp}", long_s, short_s, h, sl, tp)
            results.append(r)

# 5. VOL+MOM
for h in [24, 36]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            long_s = (df["vol_z"] > 2) & (df["mom_4h"] > 0.003)
            short_s = (df["vol_z"] > 2) & (df["mom_4h"] < -0.003)
            r = vector_backtest(f"VolMom_T{h}_SL{sl}_TP{tp}", long_s, short_s, h, sl, tp)
            results.append(r)

# 6. ACCUMULATION
for h in [36, 48, 60]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            long_s = (df["acc"] > 1.5) & (df["delta_div"] > 0) & (df["funding_abs"] < 0.003)
            short_s = (df["acc"] < 0.5) & (df["delta_div"] < 0) & (df["funding_abs"] > 0.005)
            r = vector_backtest(f"Accum_T{h}_SL{sl}_TP{tp}", long_s, short_s, h, sl, tp)
            results.append(r)

# 7. TRIPLE COMBO
for h in [24, 36, 48]:
    for sl in [0.02, 0.025]:
        for tp in [0.04, 0.05]:
            score_long = ((df["funding_abs"] < 0.003).astype(int) + 
                         (df["delta_div"] > df["delta_std"] * 1.5).astype(int) +
                         (df["liq_sq"] == 1).astype(int) +
                         (df["mom_4h"] > 0).astype(int))
            score_short = ((df["funding_abs"] < 0.003).astype(int) + 
                          (df["delta_div"] < -df["delta_std"] * 1.5).astype(int) +
                          (df["liq_sq"] == 1).astype(int) +
                          (df["mom_4h"] < 0).astype(int))
            long_s = score_long >= 3
            short_s = score_short >= 3
            r = vector_backtest(f"Triple_T{h}_SL{sl}_TP{tp}", long_s, short_s, 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)

best_eq = pd.DataFrame({"equity": best["equity"]})
best_eq.to_csv(f"{RESULTS_DIR}/alpha_hunter_best_equity.csv", index=False)

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