"""方案I逐笔展示"""
import pandas as pd, numpy as np

d = pd.read_parquet("/root/quant_pipeline/data/btc_daily.parquet")
daily = d.copy()
daily["week_label"] = daily.index.isocalendar().week.astype(str) + "_" + daily.index.year.astype(str)
weekly = daily.groupby("week_label").agg({"o":"first","h":"max","l":"min","c":"last","v":"sum"}).reset_index()
weekly["year"] = weekly["week_label"].str.split("_").str[1].astype(int)
weekly["week_num"] = weekly["week_label"].str.split("_").str[0].astype(int)
weekly = weekly.sort_values(["year","week_num"]).reset_index(drop=True)
last_days = daily.groupby("week_label").apply(lambda x: x.index[-1])
weekly["date"] = weekly["week_label"].map(last_days)
C = weekly["c"].values.astype(float)
dates = weekly["date"].values

delta = pd.Series(C).diff()
gain = delta.clip(lower=0).rolling(14).mean()
loss = (-delta.clip(upper=0)).rolling(14).mean()
rsi = (100 - 100/(1+gain/(loss+1e-9))).values
sma20 = pd.Series(C).rolling(20).mean().values
ret_8w = C / np.roll(C, 8) - 1
sig = (rsi > 20) & (rsi < 35) & (ret_8w < -0.1) & (C < sma20)
sig_idx = np.where(sig)[0]

d_close = d["c"].values
d_high = d["h"].values
d_low = d["l"].values
d_ema20 = pd.Series(d_close).ewm(span=20, adjust=False).mean().values

# 方案I: EMA20过滤 + SL=8% + 尾随止盈 ×5x
trades = []
for i in sig_idx:
    entry_price = C[i]
    pos = max(0, np.searchsorted(d.index.values, np.datetime64(dates[i]), side='right') - 1)
    
    # EMA20过滤
    ok = False
    actual_pos = pos
    for offset in range(0, 5):
        ci = pos + offset
        if ci >= len(d): break
        if d_close[ci] > d_ema20[ci]:
            ok = True
            actual_pos = ci
            break
    if not ok:
        continue
    
    entry_used = entry_price
    sl_price = entry_used * 0.92  # 8%
    highest = entry_used
    
    hit_sl = hit_tp = False
    exit_price = entry_used
    exit_idx = actual_pos
    
    for j in range(actual_pos + 1, min(actual_pos + 121, len(d))):
        bars = j - actual_pos
        dh, dl = d_high[j], d_low[j]
        
        highest = max(highest, dh)
        trail = highest * 0.88  # 12% trailing from peak
        
        if dl <= trail:
            exit_price = trail
            hit_sl = True
            exit_idx = j
            break
        elif dl <= sl_price:
            exit_price = sl_price
            hit_sl = True
            exit_idx = j
            break
        elif bars >= 60:
            exit_price = d_close[j]
            exit_idx = j
            break
    else:
        exit_price = d_close[min(actual_pos + 60, len(d)-1)]
        exit_idx = min(actual_pos + 60, len(d)-1)
    
    ret = (exit_price / entry_used - 1) * 5  # 5x
    fee = (entry_used + exit_price) / entry_used * 0.0005 * 5
    net = round((ret - fee) * 100, 2)
    
    trades.append({
        "entry": pd.Timestamp(dates[i]).date(),
        "exit": d.index[exit_idx].date(),
        "entry_px": entry_used,
        "exit_px": exit_price,
        "rsi": rsi[i],
        "bars": exit_idx - actual_pos,
        "hit_sl": hit_sl,
        "net": net,
    })

df = pd.DataFrame(trades)
if len(df) > 0:
    wins = (df["net"] > 0).sum()
    cum = (1 + df["net"] / 100).prod()
    
    print(f"📊 方案I (EMA20过滤 + SL=8%尾随 ×5x)")
    print(f"   {len(df)}笔交易, {wins}/{len(df)}胜 ({wins/len(df)*100:.0f}%), 复利{cum:.2f}x, 平均{df['net'].mean():+.2f}%")
    print(f"   最好{df['net'].max():+.2f}% 最差{df['net'].min():+.2f}%")
    print(f"\n{'入场日期':<14} {'出场日期':<14} {'入场价':>8} {'出场价':>8} {'RSI':>5} {'持仓':>4} {'收益':>8}")
    print("-" * 62)
    for _, t in df.iterrows():
        tag = "⚠️" if t["hit_sl"] else "✅"
        print(f"{str(t['entry']):<14} {str(t['exit']):<14} {t['entry_px']:>8.0f} {t['exit_px']:>8.0f} {t['rsi']:>5.1f} {t['bars']:>3d}d {tag} {t['net']:>+7.2f}%")
    
    # 年度统计
    df["year"] = df["entry"].astype(str).str[:4]
    print(f"\n📊 年度:")
    for yr, grp in df.groupby("year"):
        yw = (grp["net"] > 0).sum()
        yr_cum = (1 + grp["net"] / 100).prod()
        print(f"  {yr}: {len(grp)}笔 {yw}/{len(grp)}胜 平均{grp['net'].mean():+.1f}% 年复利{yr_cum:.2f}x")
