"""隐秘枢轴 v3：等待价格触达关键位 → 3K确认进场
更像原版逻辑：等价格走到关键区，看反应再进
"""
import pandas as pd, numpy as np

df_raw = pd.read_parquet("data/btc_multidim.parquet")
df_raw.columns = [c.lower() for c in df_raw.columns]
d = df_raw.copy()

O, H, L, C, V = d["open"].values, d["high"].values, d["low"].values, d["close"].values, d["volume"].values
n = len(d)

# ── 日级关键位 ──
daily = d.resample("1D").agg({"high":"max","low":"min"}).dropna()
daily["prev_high"] = daily["high"].shift(1)
daily["prev_low"] = daily["low"].shift(1)
daily["swing_high"] = daily["high"].rolling(10).max().shift(1)
daily["swing_low"] = daily["low"].rolling(10).min().shift(1)

d["prev_high"] = daily["prev_high"].reindex(d.index, method="ffill").values
d["prev_low"] = daily["prev_low"].reindex(d.index, method="ffill").values
d["swing_high"] = daily["swing_high"].reindex(d.index, method="ffill").values
d["swing_low"] = daily["swing_low"].reindex(d.index, method="ffill").values

FEE = 0.001
MB = 48  # 最大12小时

signals = []

for i in range(5, n - 5):
    prev_high = d["prev_high"].iloc[i]
    prev_low = d["prev_low"].iloc[i]
    swing_high = d["swing_high"].iloc[i]
    swing_low = d["swing_low"].iloc[i]
    
    if pd.isna(prev_high) or pd.isna(swing_high):
        continue
    
    # ── 检测"价格在支撑位附近" ──
    near_prev_low = abs(L[i] - prev_low) / prev_low < 0.003
    near_swing_low = abs(L[i] - swing_low) / swing_low < 0.003
    
    if near_prev_low or near_swing_low:
        # 检查当前及后面2根K线是否形成"拒绝下跌"形态
        # 重点：收盘价不创新低，且第2根K线高低点被第3根突破
        if L[i+1] >= L[i]*0.998 and L[i+2] >= L[i]*0.998:
            # 拒绝信号出现了，等第3根突破第2根高点
            if C[i+2] > H[i+1]:
                sup = prev_low if near_prev_low else swing_low
                res = min(prev_high, swing_high)  # 近一些的阻力
                tp = (res / C[i+2] - 1)
                if tp > 0.005 and tp < 0.05:
                    signals.append({
                        "i": i+2, "dir": 1, "entry": C[i+2],
                        "sup": sup, "res": res,
                        "tp_pct": tp, "sl_pct": 0.01,
                        "type": "sup:" + ("prev_low" if near_prev_low else "swing_low")
                    })
    
    # ── 检测"价格在阻力位附近" ──
    near_prev_high = abs(H[i] - prev_high) / prev_high < 0.003
    near_swing_high = abs(H[i] - swing_high) / swing_high < 0.003
    
    if near_prev_high or near_swing_high:
        if H[i+1] <= H[i]*1.002 and H[i+2] <= H[i]*1.002:
            if C[i+2] < L[i+1]:
                res = prev_high if near_prev_high else swing_high
                sup = max(prev_low, swing_low)
                tp = (1 - C[i+2] / sup)
                if tp > 0.005 and tp < 0.05:
                    signals.append({
                        "i": i+2, "dir": -1, "entry": C[i+2],
                        "sup": sup, "res": res,
                        "tp_pct": tp, "sl_pct": 0.01,
                        "type": "res:" + ("prev_high" if near_prev_high else "swing_high")
                    })

print(f"信号总数: {len(signals)}")
if signals:
    longs = sum(1 for s in signals if s["dir"] == 1)
    shorts = len(signals) - longs
    print(f"做多: {longs}  做空: {shorts}")

# ── 回测 ──
split_pos = int(n * 0.67)
results = {"in": [], "out": []}

for sig in signals:
    i = sig["i"]
    if i + MB >= n: continue
    period = "in" if i < split_pos else "out"
    entry = sig["entry"]
    dirc = sig["dir"]
    sl_pct = sig["sl_pct"]
    tp_pct = sig["tp_pct"]
    closed = False
    
    for j in range(1, MB + 1):
        if i + j >= n: break
        ret = (C[i+j] / entry - 1) * dirc
        if ret >= tp_pct:
            results[period].append(tp_pct - FEE)
            closed = True; break
        if ret <= -sl_pct:
            results[period].append(-sl_pct - FEE)
            closed = True; break
    if not closed:
        final_ret = (C[min(i+MB, n-1)] / entry - 1) * dirc
        results[period].append(final_ret - FEE)

print(f"\n{'='*60}")
print("隐秘枢轴 v3：触达关键位 → 三K确认")
print(f"{'='*60}")
print(f"SL=1%  动态TP(到对面关键位)  最大持仓{MB*15//60}h")
print(f"数据: BTC 15min {n}根K线")

for nm, key in [("样本内", "in"), ("样本外", "out")]:
    tr = results[key]
    if len(tr) < 3: print(f"\n{nm}: 仅{len(tr)}笔"); continue
    wr = sum(1 for r in tr if r > 0) / len(tr)
    cum = np.prod([1 + r for r in tr])
    avg = np.mean(tr) * 100
    running = 1.0; peak = 1.0; mdd = 0
    for r in tr:
        running *= (1 + r); peak = max(peak, running)
        mdd = min(mdd, (running - peak) / peak)
    sharpe = np.mean(tr) / (np.std(tr) + 1e-9) * np.sqrt(365*96/MB) if np.std(tr) > 0 else 0
    print(f"\n{nm}: {len(tr)}笔 wr={wr:.1%} cum={cum:.3f} avg={avg:+.2f}% "
          f"MDD={mdd:.1%} Sharpe={sharpe:.2f}")

print(f"\n{'='*60}")
print("跟烛龙v1.2（1H周期）对比：")
print("  原版: 48笔  胜率56%  累计1.769 周盈60%")
print("  隐秘枢轴: 待统计")