"""周线顶底狙击回测（完整数据2017-2024）"""
import pandas as pd, numpy as np

d = pd.read_parquet("/root/quant_pipeline/data/btc_daily.parquet")
w = pd.read_parquet("/root/quant_pipeline/data/btc_weekly.parquet")

O,H,L,C,V = w["o"].values,w["h"].values,w["l"].values,w["c"].values,w["v"].values
O1,C1 = np.roll(O,1),np.roll(C,1)
n = len(w)
idx = w.index

print(f"周线: {n}根  {idx[0].date()} ~ {idx[-1].date()}")

# ── 周线指标 ──
ema20 = pd.Series(C).ewm(span=20, adjust=False).mean().values
sma20 = pd.Series(C).rolling(20).mean().values
sma50 = pd.Series(C).rolling(50).mean().values

# RSI(14)
delta = pd.Series(C).diff()
gain = delta.clip(lower=0).rolling(14).mean()
loss = (-delta.clip(upper=0)).rolling(14).mean()
rs = gain / (loss + 1e-9)
rsi = (100 - 100/(1+rs)).values

# 周线吞没
engulf_bull = (C1 < O1) & (C > O) & (O <= C1) & (C >= O1)
engulf_bear = (C1 > O1) & (C < O) & (O >= C1) & (C <= O1)

# ── 底部信号 ──
bottom = (rsi < 30) & (C < sma20)
# 底部+吞没确认
bottom_confirm = bottom & engulf_bull

# ── 顶部信号 ──
top = (rsi > 75) & (C > sma20)
top_confirm = top & engulf_bear

print(f"\n底部信号（RSI<30 + 低于20周线）:")
print(f"  共{bottom.sum()}次")

print(f"\n顶部信号（RSI>75 + 高于20周线）:")
print(f"  共{top.sum()}次")

print(f"\n{'='*60}")
print("🔥 底部狙击：入场后收益")
print(f"{'='*60}")

for weeks_out in [4, 8, 12, 24]:
    fwd = np.roll(C, -weeks_out) / C - 1
    sig_idx = np.where(bottom)[0]
    valid = [i for i in sig_idx if i + weeks_out < n]
    if len(valid) < 3: continue
    rets = [fwd[i] for i in valid]
    wr = sum(1 for r in rets if r > 0) / len(rets)
    avg = np.mean(rets)
    best = max(rets)
    worst = min(rets)
    print(f"  {weeks_out}周后: {len(valid)}次 胜率{wr:.0%} 平均{avg:.0%} 最好{best:.0%} 最差{worst:.0%}")

    # 标出每笔详情
    if weeks_out == 12:
        print(f"  详情:")
        for i in valid[:10]:
            print(f"    {idx[i].date()}: 入场{C[i]:.0f}  RSI={rsi[i]:.0f}  12周后{fwd[i]:+.0%}")

print(f"\n{'='*60}")
print("🔥 顶部狙击（做空）：入场后收益")
print(f"{'='*60}")

for weeks_out in [4, 8, 12]:
    fwd = np.roll(C, -weeks_out) / C - 1
    sig_idx = np.where(top)[0]
    valid = [i for i in sig_idx if i + weeks_out < n]
    if len(valid) < 3: continue
    # 做空看跌
    rets = [-fwd[i] for i in valid]
    wr = sum(1 for r in rets if r > 0) / len(rets)
    avg = np.mean(rets)
    best = max(rets)
    worst = min(rets)
    print(f"  {weeks_out}周后: {len(valid)}次 胜率{wr:.0%} 平均{avg:.0%} 最好{best:.0%} 最差{worst:.0%}")

# 用吞没过滤后
print(f"\n{'='*60}")
print(f"📊 底部+吞没确认（更高精度）")
print(f"{'='*60}")

for weeks_out in [4, 8, 12]:
    fwd = np.roll(C, -weeks_out) / C - 1
    sig_idx = np.where(bottom_confirm)[0]
    valid = [i for i in sig_idx if i + weeks_out < n]
    if len(valid) < 2: continue
    rets = [fwd[i] for i in valid]
    wr = sum(1 for r in rets if r > 0) / len(rets)
    avg = np.mean(rets)
    print(f"  {weeks_out}周后: {len(valid)}次 胜率{wr:.0%} 平均{avg:.0%}")

# 看历次真实牛熊底部
print(f"\n{'='*60}")
print(f"📋 历次重要底部信号")
print(f"{'='*60}")
sig_idx = np.where(bottom)[0]
fwd_12 = np.roll(C, -12) / C - 1
for i in sig_idx:
    if i + 12 >= n: continue
    print(f"  {idx[i].date()}: 价格${C[i]:.0f}  RSI={rsi[i]:.0f}  20周均线${sma20[i]:.0f}  12周后{fwd_12[i]:+.0%}")