#!/usr/bin/env python3
"""
ALPHA HUNTER ENGINE - Exotic Strategies v2
Target: Sharpe > 2
"""

import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
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 ENGINE v2 - Hunting Edge Where Others Don't Look")
print("=" * 70)

# ─── LOAD DATA ────────────────────────────────────────────────────────────────
df = pd.read_csv(f"{RESULTS_DIR}/btc_ohlcv_2024_2025.csv", parse_dates=["timestamp"], index_col="timestamp")
print(f"📊 Loaded {len(df)} candles: {df.index[0]} → {df.index[-1]}")

# ─── FEATURE ENGINEERING ─────────────────────────────────────────────────────

def compute_features(df):
    """Compute all exotic features from OHLCV"""
    df = df.copy()
    
    # ===== ORDERBOOK ANALYSIS =====
    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_avg"] = df["volume"].rolling(20).mean()
    df["vol_zscore"] = (df["volume"] - df["vol_avg"]) / df["volume"].rolling(50).std()
    
    df["vpin_raw"] = np.abs(df["delta"]) / df["volume"].rolling(50).mean()
    df["vpin_ma"] = df["vpin_raw"].rolling(20).mean()
    
    # ===== MICROSTRUCTURE =====
    df["momentum_1h"] = df["close"].pct_change(1)
    df["momentum_4h"] = df["close"].pct_change(4)
    df["momentum_24h"] = df["close"].pct_change(24)
    df["funding_proxy"] = df["momentum_24h"] * 10
    df["funding_near_zero"] = (np.abs(df["funding_proxy"]) < 0.002).astype(int)
    
    df["atr"] = (df["high"] - df["low"]).rolling(14).mean()
    df["atr_ratio"] = df["atr"] / df["close"]
    df["atr_q20"] = df["atr_ratio"].rolling(100).quantile(0.2)
    df["vol_squeeze"] = (df["atr_ratio"] < df["atr_q20"]).astype(int)
    df["vol_spike"] = (df["volume"] > df["vol_avg"] * 2).astype(int)
    df["liq_cluster"] = (df["vol_squeeze"] & df["vol_spike"]).astype(int)
    
    df["basis_proxy"] = df["momentum_1h"].rolling(6).std()
    df["basis_q90"] = df["basis_proxy"].rolling(50).quantile(0.9)
    df["basis_signal"] = (df["basis_proxy"] > df["basis_q90"]).astype(int)
    
    # ===== ON-CHAIN (Simulated) =====
    df["up_day"] = (df["close"] > df["open"]).astype(int)
    df["accum_score"] = df["up_day"] * df["volume"] / df["vol_avg"]
    df["exchange_flow"] = (df["accum_score"] > 1.5).astype(int)
    
    df["optimism"] = df["momentum_4h"].clip(0, 0.05) / 0.05
    df["ls_proxy"] = df["optimism"].rolling(10).mean()
    df["extreme_bull"] = (df["ls_proxy"] > 0.9).astype(int)
    
    df["local_top"] = (df["close"] >= df["close"].rolling(48).max()).astype(int)
    df["local_bot"] = (df["close"] <= df["close"].rolling(48).min()).astype(int)
    df["funding_top"] = df["local_top"].rolling(6).sum()
    
    # ===== MULTI-TIMEFRAME =====
    df["mtm_bull"] = ((df["momentum_1h"] > 0) & (df["momentum_4h"] > 0) & (df["momentum_24h"] > 0)).astype(int)
    df["mtm_bear"] = ((df["momentum_1h"] < 0) & (df["momentum_4h"] < 0) & (df["momentum_24h"] < 0)).astype(int)
    
    return df

df = compute_features(df)
print("✅ Features computed")

# ─── BACKTESTER ──────────────────────────────────────────────────────────────

def backtest_signal(df, strategy_name, entry_logic):
    df_work = df.dropna().copy().reset_index()
    
    capital = INITIAL_CAPITAL
    position = 0
    entry_price = 0
    entry_idx = 0
    trades = []
    equity = [INITIAL_CAPITAL]
    
    for i in range(1, len(df_work)):
        signal = entry_logic(df_work, i)
        price = df_work.iloc[i]["close"]
        
        # 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:
            pnl_pct = (price - entry_price) / entry_price if position == 1 else (entry_price - price) / entry_price
            time_held = i - entry_idx
            
            # Exit conditions
            if time_held >= 48 or pnl_pct < -0.025 or pnl_pct > 0.05:
                capital *= (1 + pnl_pct - COMMISSION)
                trades.append({
                    "type": "LONG" if position == 1 else "SHORT",
                    "entry": entry_price,
                    "exit": price,
                    "pnl_pct": round(pnl_pct * 100, 2),
                    "duration": time_held
                })
                position = 0
                entry_price = 0
        
        equity.append(capital)
    
    # Close open position
    if position != 0:
        price = df_work.iloc[-1]["close"]
        pnl_pct = (price - entry_price) / entry_price if position == 1 else (entry_price - price) / entry_price
        capital *= (1 + pnl_pct - COMMISSION)
        trades[-1].update({"exit": price, "pnl_pct": round(pnl_pct * 100, 2)})
    
    equity[-1] = capital
    
    # Metrics
    equity_s = pd.Series(equity)
    returns = equity_s.pct_change().dropna()
    total_return = (capital - INITIAL_CAPITAL) / INITIAL_CAPITAL * 100
    winning = [t for t in trades if t["pnl_pct"] > 0]
    losing = [t for t in trades if t["pnl_pct"] <= 0]
    win_rate = len(winning) / len(trades) * 100 if trades else 0
    sharpe = returns.mean() / returns.std() * np.sqrt(365 * 24) if returns.std() > 0 else 0
    max_dd = ((equity_s - equity_s.cummax()) / equity_s.cummax()).min() * 100
    
    return {
        "strategy": strategy_name,
        "return_pct": round(total_return, 2),
        "final_capital": round(capital, 2),
        "trades": len(trades),
        "win_rate": round(win_rate, 1),
        "sharpe": round(sharpe, 2),
        "max_dd": round(max_dd, 2),
        "winners": len(winning),
        "losers": len(losing),
        "equity": equity
    }

# ─── STRATEGIES ──────────────────────────────────────────────────────────────

print("\n" + "=" * 70)
print("📈 STRATEGY 1: ORDERBOOK ANALYSIS")
print("=" * 70)

def wall_entry(df, i):
    row = df.iloc[i]
    vol_prox = abs(row["close"] - df["close"].iloc[max(0,i-48):i].mean()) / df["close"].iloc[max(0,i-48):i].std() if i > 48 else 1
    if vol_prox < 0.5 and row["delta_div"] > 0 and row["buy_vol"] > row["sell_vol"]:
        return 1
    if vol_prox < 0.5 and row["delta_div"] < 0 and row["sell_vol"] > row["buy_vol"]:
        return -1
    return 0

result_wall = backtest_signal(df, "Wall Detection", wall_entry)
print(f"  Wall Detection: Sharpe={result_wall['sharpe']}, Return={result_wall['return_pct']}%, Trades={result_wall['trades']}")

def delta_entry(df, i):
    row = df.iloc[i]
    lookback = 500
    start = max(0, i - lookback)
    q_high = df["delta_div"].iloc[start:i].quantile(0.9) if i > lookback else df["delta_div"].quantile(0.9)
    q_low = df["delta_div"].iloc[start:i].quantile(0.1) if i > lookback else df["delta_div"].quantile(0.1)
    if row["delta_div"] > q_high and row["momentum_4h"] > 0:
        return 1
    if row["delta_div"] < q_low and row["momentum_4h"] < 0:
        return -1
    return 0

result_delta = backtest_signal(df, "Delta Divergence", delta_entry)
print(f"  Delta Divergence: Sharpe={result_delta['sharpe']}, Return={result_delta['return_pct']}%, Trades={result_delta['trades']}")

def vpin_entry(df, i):
    row = df.iloc[i]
    if row["vpin_raw"] > row["vpin_ma"] * 1.5 and row["momentum_1h"] > 0.001:
        return 1
    if row["vpin_raw"] > row["vpin_ma"] * 1.5 and row["momentum_1h"] < -0.001:
        return -1
    return 0

result_vpin = backtest_signal(df, "VPIN Spike", vpin_entry)
print(f"  VPIN Spike: Sharpe={result_vpin['sharpe']}, Return={result_vpin['return_pct']}%, Trades={result_vpin['trades']}")

print("\n" + "=" * 70)
print("📈 STRATEGY 2: MICROSTRUCTURE")
print("=" * 70)

def funding_entry(df, i):
    row = df.iloc[i]
    if row["funding_near_zero"] == 1 and row["momentum_1h"] > 0:
        return 1
    if row["funding_near_zero"] == 1 and row["momentum_1h"] < 0:
        return -1
    return 0

result_funding = backtest_signal(df, "Funding Rate Timing", funding_entry)
print(f"  Funding Timing: Sharpe={result_funding['sharpe']}, Return={result_funding['return_pct']}%, Trades={result_funding['trades']}")

def liq_entry(df, i):
    row = df.iloc[i]
    if row["liq_cluster"] == 1:
        if row["momentum_4h"] > 0: return 1
        if row["momentum_4h"] < 0: return -1
    return 0

result_liq = backtest_signal(df, "Liquidation Cluster", liq_entry)
print(f"  Liquidation Cluster: Sharpe={result_liq['sharpe']}, Return={result_liq['return_pct']}%, Trades={result_liq['trades']}")

def basis_entry(df, i):
    row = df.iloc[i]
    if row["basis_signal"] == 1:
        if row["momentum_1h"] > 0: return 1
        if row["momentum_1h"] < 0: return -1
    return 0

result_basis = backtest_signal(df, "Spot-Futures Basis", basis_entry)
print(f"  Spot-Futures Basis: Sharpe={result_basis['sharpe']}, Return={result_basis['return_pct']}%, Trades={result_basis['trades']}")

print("\n" + "=" * 70)
print("📈 STRATEGY 3: ON-CHAIN SIMULATED")
print("=" * 70)

def flow_entry(df, i):
    row = df.iloc[i]
    if row["exchange_flow"] == 1 and row["momentum_4h"] > 0:
        return 1
    return 0

result_flow = backtest_signal(df, "Exchange Flow", flow_entry)
print(f"  Exchange Flow: Sharpe={result_flow['sharpe']}, Return={result_flow['return_pct']}%, Trades={result_flow['trades']}")

def ls_extreme_entry(df, i):
    row = df.iloc[i]
    if row["extreme_bull"] == 1:
        return -1  # Contrarian
    return 0

result_ls = backtest_signal(df, "L/S Extreme (Contrarian)", ls_extreme_entry)
print(f"  L/S Extreme: Sharpe={result_ls['sharpe']}, Return={result_ls['return_pct']}%, Trades={result_ls['trades']}")

def funding_top_entry(df, i):
    row = df.iloc[i]
    if row["funding_top"] >= 2:
        return -1
    return 0

result_ft = backtest_signal(df, "Funding Top", funding_top_entry)
print(f"  Funding Top: Sharpe={result_ft['sharpe']}, Return={result_ft['return_pct']}%, Trades={result_ft['trades']}")

print("\n" + "=" * 70)
print("📈 STRATEGY 4: EXOTIC COMBINATIONS")
print("=" * 70)

def triple_entry(df, i):
    row = df.iloc[i]
    longs, shorts = 0, 0
    if row["vol_zscore"] > 1:
        if row["momentum_4h"] > 0: longs += 1
        else: shorts += 1
    if row["funding_near_zero"] == 1:
        if row["momentum_1h"] > 0: longs += 1
        else: shorts += 1
    if row["delta_div"] > row["delta_std"] * 2:
        longs += 1
    elif row["delta_div"] < -row["delta_std"] * 2:
        shorts += 1
    if longs >= 2: return 1
    if shorts >= 2: return -1
    return 0

result_triple = backtest_signal(df, "Triple Combo (V+F+D)", triple_entry)
print(f"  Triple Combo: Sharpe={result_triple['sharpe']}, Return={result_triple['return_pct']}%, Trades={result_triple['trades']}")

def mtf_entry(df, i):
    row = df.iloc[i]
    if row["mtm_bull"] == 1: return 1
    if row["mtm_bear"] == 1: return -1
    return 0

result_mtf = backtest_signal(df, "Multi-TF Momentum", mtf_entry)
print(f"  Multi-TF Momentum: Sharpe={result_mtf['sharpe']}, Return={result_mtf['return_pct']}%, Trades={result_mtf['trades']}")

def squeeze_entry(df, i):
    row = df.iloc[i]
    if row["liq_cluster"] == 1:
        if row["mtm_bull"] == 1: return 1
        if row["mtm_bear"] == 1: return -1
    return 0

result_squeeze = backtest_signal(df, "Squeeze Explosion", squeeze_entry)
print(f"  Squeeze Explosion: Sharpe={result_squeeze['sharpe']}, Return={result_squeeze['return_pct']}%, Trades={result_squeeze['trades']}")

print("\n" + "=" * 70)
print("📈 STRATEGY 5: ADVANCED COMBINATIONS")
print("=" * 70)

def squeeze_rev_entry(df, i):
    row = df.iloc[i]
    prev = df.iloc[i-1]
    if prev["liq_cluster"] == 1:
        if row["delta_div"] > 0 and row["momentum_1h"] > 0:
            return 1
    return 0

result_squeeze_rev = backtest_signal(df, "Squeeze Reversion", squeeze_rev_entry)
print(f"  Squeeze Reversion: Sharpe={result_squeeze_rev['sharpe']}, Return={result_squeeze_rev['return_pct']}%, Trades={result_squeeze_rev['trades']}")

def accum_entry(df, i):
    row = df.iloc[i]
    score = 0
    if row["exchange_flow"] == 1: score += 1
    if row["delta_div"] > 0: score += 1
    if row["funding_near_zero"] == 1: score += 1
    if row["mtm_bull"] == 1: score += 1
    if score >= 3: return 1
    return 0

result_accum = backtest_signal(df, "Accumulation Play", accum_entry)
print(f"  Accumulation Play: Sharpe={result_accum['sharpe']}, Return={result_accum['return_pct']}%, Trades={result_accum['trades']}")

def vpin_basis_entry(df, i):
    row = df.iloc[i]
    if row["vpin_raw"] > row["vpin_ma"] * 1.5 and row["basis_signal"] == 1:
        if row["momentum_4h"] > 0: return 1
        if row["momentum_4h"] < 0: return -1
    return 0

result_vb = backtest_signal(df, "VPIN+Basis Breakout", vpin_basis_entry)
print(f"  VPIN+Basis: Sharpe={result_vb['sharpe']}, Return={result_vb['return_pct']}%, Trades={result_vb['trades']}")

def delta_funding_entry(df, i):
    row = df.iloc[i]
    lookback = 500
    start = max(0, i - lookback)
    q_high = df["delta_div"].iloc[start:i].quantile(0.95) if i > lookback else df["delta_div"].quantile(0.95)
    q_low = df["delta_div"].iloc[start:i].quantile(0.05) if i > lookback else df["delta_div"].quantile(0.05)
    if row["funding_near_zero"] == 1:
        if row["delta_div"] > q_high: return 1
        if row["delta_div"] < q_low: return -1
    return 0

result_df = backtest_signal(df, "Delta+Funding Neutral", delta_funding_entry)
print(f"  Delta+Funding: Sharpe={result_df['sharpe']}, Return={result_df['return_pct']}%, Trades={result_df['trades']}")

print("\n" + "=" * 70)
print("🎯 OPTIMIZED STRATEGIES")
print("=" * 70)

def delta_trend_entry(df, i):
    row = df.iloc[i]
    lookback = 500
    start = max(0, i - lookback)
    q_high = df["delta_div"].iloc[start:i].quantile(0.9) if i > lookback else df["delta_div"].quantile(0.9)
    q_low = df["delta_div"].iloc[start:i].quantile(0.1) if i > lookback else df["delta_div"].quantile(0.1)
    if row["delta_div"] > q_high and row["momentum_4h"] > 0.002:
        return 1
    if row["delta_div"] < q_low and row["momentum_4h"] < -0.002:
        return -1
    return 0

result_dt = backtest_signal(df, "Delta+Trend Filter", delta_trend_entry)
print(f"  Delta+Trend: Sharpe={result_dt['sharpe']}, Return={result_dt['return_pct']}%, Trades={result_dt['trades']}")

def mtf_squeeze_entry(df, i):
    row = df.iloc[i]
    if row["liq_cluster"] == 1:
        if row["mtm_bull"] == 1: return 1
        if row["mtm_bear"] == 1: return -1
    return 0

result_ms = backtest_signal(df, "MTF+Squeeze Confirm", mtf_squeeze_entry)
print(f"  MTF+Squeeze: Sharpe={result_ms['sharpe']}, Return={result_ms['return_pct']}%, Trades={result_ms['trades']}")

# ─── NEW: CROSS-EXCHANGE CORRELATION STRATEGY ─────────────────────────────────

def correlation_entry(df, i):
    """Trade when BTC breaks correlation with ETH or market"""
    row = df.iloc[i]
    # Simulated correlation break - momentum 4h vs 24h divergence
    mom_diff = row["momentum_4h"] - row["momentum_24h"]
    if abs(mom_diff) > 0.01 and row["vol_zscore"] > 1:
        if row["momentum_4h"] > 0: return 1
        if row["momentum_4h"] < 0: return -1
    return 0

result_corr = backtest_signal(df, "Correlation Break", correlation_entry)
print(f"  Correlation Break: Sharpe={result_corr['sharpe']}, Return={result_corr['return_pct']}%, Trades={result_corr['trades']}")

# ─── AGGRESSIVE VARIANTS ─────────────────────────────────────────────────────

def aggro_entry(df, i):
    """Aggressive: squeeze + extreme delta + momentum"""
    row = df.iloc[i]
    if row["liq_cluster"] == 1:
        lookback = 500
        start = max(0, i - lookback)
        q_high = df["delta_div"].iloc[start:i].quantile(0.85) if i > lookback else df["delta_div"].quantile(0.85)
        q_low = df["delta_div"].iloc[start:i].quantile(0.15) if i > lookback else df["delta_div"].quantile(0.15)
        if row["delta_div"] > q_high and row["momentum_4h"] > 0: return 1
        if row["delta_div"] < q_low and row["momentum_4h"] < 0: return -1
    return 0

result_aggro = backtest_signal(df, "Aggro Squeeze+Delta", aggro_entry)
print(f"  Aggro Squeeze+Delta: Sharpe={result_aggro['sharpe']}, Return={result_aggro['return_pct']}%, Trades={result_aggro['trades']}")

# ─── SUMMARY ────────────────────────────────────────────────────────────────

all_results = [
    result_wall, result_delta, result_vpin,
    result_funding, result_liq, result_basis,
    result_flow, result_ls, result_ft,
    result_triple, result_mtf, result_squeeze,
    result_squeeze_rev, result_accum, result_vb, result_df,
    result_dt, result_ms, result_corr, result_aggro
]

print("\n" + "=" * 70)
print("🏆 FINAL RANKING - ALL STRATEGIES")
print("=" * 70)

sorted_results = sorted(all_results, key=lambda x: x["sharpe"], reverse=True)
for i, r in enumerate(sorted_results, 1):
    emoji = "🎯" if r["sharpe"] > 2 else "📊" if r["sharpe"] > 0 else "❌"
    print(f"  {emoji} {i:2d}. {r['strategy']:30s} | Sharpe: {r['sharpe']:+.2f} | Return: {r['return_pct']:+.1f}% | Trades: {r['trades']:3d} | Win: {r['win_rate']:.0f}%")

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

# ─── PLOT ─────────────────────────────────────────────────────────────────────

print("\n📊 Generating charts...")
top4 = sorted_results[:4]

fig, axes = plt.subplots(2, 2, figsize=(16, 12))
fig.suptitle("ALPHA HUNTER v2 - Top 4 Strategies | BTC/USDT 2024-2025", fontsize=14, fontweight='bold')

colors = ["#2ecc71", "#3498db", "#e74c3c", "#9b59b6"]

for idx, r in enumerate(top4):
    ax = axes[idx // 2, idx % 2]
    ax.plot(r["equity"], color=colors[idx], linewidth=1.5)
    ax.set_title(f"{r['strategy']}\nSharpe: {r['sharpe']} | Return: {r['return_pct']}%", fontweight='bold')
    ax.set_ylabel("Capital ($)")
    ax.grid(True, alpha=0.3)
    ax.axhline(INITIAL_CAPITAL, color='gray', linestyle='--', alpha=0.5)

plt.tight_layout()
plt.savefig(f"{RESULTS_DIR}/alpha_hunter_results.png", dpi=150, bbox_inches='tight')
print(f"💾 Chart saved: {RESULTS_DIR}/alpha_hunter_results.png")
plt.close()

# ─── 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)

print("\n✅ ALPHA HUNTING v2 COMPLETE!")
print(f"   Results: {RESULTS_DIR}/alpha_hunter_results.csv")
print(f"   Best: {best['strategy']} (Sharpe: {best['sharpe']})")
