"""获取近一年Top3策略的详细交易记录"""
import asyncio, sys, json
from datetime import datetime, timedelta, timezone
from pathlib import Path

_project_root = Path(__file__).resolve().parent.parent.parent
if str(_project_root) not in sys.path:
    sys.path.insert(0, str(_project_root))

from engine.common.config import config
from engine.backtest.models import BacktestConfig
from engine.example.long_short import LongShortEngine
from engine.example.full_comparison import (
    VolBreakStrategy, VolBreakConfig,
    EmaCrossStrategy, EmaCrossConfig,
)
from engine.common.base import Signal

NOW = datetime.now(timezone.utc)
ONE_YEAR_AGO = NOW - timedelta(days=365)
INITIAL = 10_000.0

TASKS = [
    ("ATR波动率突破  ETHUSDT 4h", VolBreakConfig, VolBreakStrategy,
     "ETHUSDT", "4h", lambda s: VolBreakConfig(symbol=s, atr_period=14, squeeze_period=20, squeeze_ratio=0.7, atr_stop=2.0)),
    ("EMA双均线多空   ETHUSDT 1d", EmaCrossConfig, EmaCrossStrategy,
     "ETHUSDT", "1d", lambda s: EmaCrossConfig(symbol=s, fast=10, slow=50, atr_stop=2.5)),
    ("EMA双均线多空   BTCUSDT 1d", EmaCrossConfig, EmaCrossStrategy,
     "BTCUSDT", "1d", lambda s: EmaCrossConfig(symbol=s, fast=10, slow=50, atr_stop=2.5)),
]


def fmt_ts(ts_ms):
    return datetime.fromtimestamp(ts_ms / 1000, tz=timezone.utc).strftime("%Y-%m-%d %H:%M")


async def run_one(label, config_cls, strategy_cls, symbol, interval, mkcfg):
    sc = mkcfg(symbol)
    bt = BacktestConfig(symbol=symbol, interval=interval,
                        start_time=ONE_YEAR_AGO, end_time=NOW,
                        initial_capital=INITIAL, warmup_bars=150)
    engine = LongShortEngine(bt, db_config=config.db)
    r = await engine.run(strategy_cls, sc)
    return label, r


async def main():
    results = []
    for task in TASKS:
        label, r = await run_one(*task)
        results.append((label, r))

    for label, r in results:
        m = r.metrics
        trades = r.trades

        # 配对交易
        paired = []
        pending = None
        for t in trades:
            if t.side == "BUY" and t.pnl is None:
                pending = {"entry_ts": t.timestamp, "entry_price": t.price, "entry_reason": t.reason}
            elif t.side == "SELL" and pending and t.pnl is not None:
                paired.append({**pending, "exit_ts": t.timestamp, "exit_price": t.price,
                               "exit_reason": t.reason, "pnl": t.pnl})
                pending = None
            elif t.side == "SELL" and t.pnl is None:
                pending = {"entry_ts": t.timestamp, "entry_price": t.price, "entry_reason": t.reason, "short": True}
            elif t.side == "BUY" and pending and t.pnl is not None and pending.get("short"):
                paired.append({**pending, "exit_ts": t.timestamp, "exit_price": t.price,
                               "exit_reason": t.reason, "pnl": t.pnl})
                pending = None

        cfg = r.config
        print(f"\n═══ {label} ═══")
        print(f"  本金 {INITIAL:,.0f} → 终值 {m.final_equity:,.0f}  |  {m.total_return_pct:+.1f}%  |  年化 {m.annual_return_pct:+.1f}%")
        print(f"  夏普 {m.sharpe_ratio:.2f}  |  回撤 {m.max_drawdown_pct:.1f}%  |  胜率 {m.win_rate*100:.1f}%  |  盈亏比 {m.profit_factor:.2f}  |  {m.total_trades}笔")
        print(f"  日期 {cfg.start_time.date()} ~ {cfg.end_time.date()}")
        print()
        print(f"  {'#':>3} {'入场时间':<19} {'入场价':>10} {'入场原因':<25} {'出场时间':<19} {'出场价':>10} {'出场原因':<25} {'盈亏':>10}")
        print("  " + "─" * 130)

        total_pnl = 0
        for i, p in enumerate(paired):
            total_pnl += p["pnl"]
            side = "做空" if p.get("short") else "做多"
            print(f"  {i+1:>3} {fmt_ts(p['entry_ts']):<19} {p['entry_price']:>10.4f} {p['entry_reason']:<25} {fmt_ts(p['exit_ts']):<19} {p['exit_price']:>10.4f} {p['exit_reason']:<25} {p['pnl']:>+10.2f}")

        print("  " + "─" * 130)
        wins = sum(1 for p in paired if p["pnl"] > 0)
        print(f"  合计 {len(paired)} 笔  |  盈利 {wins} 笔  |  总盈亏 {total_pnl:+,.2f} USDT")
        print()


if __name__ == "__main__":
    asyncio.run(main())
