"""
牛熊自适应策略 — 日内级别全币种扫描 (15m / 30m / 1h)

用法：
    source .venv/bin/activate && python example/regime_intraday.py
"""

import asyncio
import sys
import time
from datetime import datetime, 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 import BacktestConfig
from engine.data import DataService
from engine.example.regime_all import RegimeEmaStrategy, RegimeEmaConfig
from engine.example.long_short import LongShortEngine

SYMBOLS = ["BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT"]
INTERVALS = ["15m", "30m", "1h"]

# 沿用 4h 级别优化参数（日内级别可能需单独调参）
PARAMS = {
    "BTCUSDT": (10, 50),
    "ETHUSDT": (10, 75),
    "BNBUSDT": (20, 50),
    "SOLUSDT": (30, 50),
}


async def get_actual_range(ds: DataService, symbol: str, interval: str):
    """获取币种指定周期的实际数据范围"""
    start, end = await ds.fetch_symbol_date_range(symbol, interval)
    return start, end


async def main():
    ds = DataService(config.db)
    await ds.connect()

    print()
    print("═" * 130)
    print("  牛熊自适应策略 — 日内级别全币种扫描 | 牛市只多/熊市只空/震荡空仓")
    print("═" * 130)

    total_start = time.time()
    results: list[dict] = []

    for interval in INTERVALS:
        print(f"\n  ■ {interval} 级别")
        print(f"  {'币种':<10} {'数据范围':<22} {'总收益%':>8} {'年化%':>8} {'夏普':>7} {'回撤%':>8} {'交易':>6} {'多头P&L':>11} {'空头P&L':>11} {'耗时s':>7}")
        print("  " + "─" * 125)

        for symbol in SYMBOLS:
            fast, slow = PARAMS[symbol]
            sc = RegimeEmaConfig(symbol=symbol, fast=fast, slow=slow)

            try:
                act_start, act_end = await get_actual_range(ds, symbol, interval)
                range_str = f"{act_start.date()}~{act_end.date()}"
            except Exception:
                # 数据不存在，跳过
                print(f"  {symbol:<10} {'无数据':<22}")
                continue

            bt = BacktestConfig(
                symbol=symbol, interval=interval,
                start_time=act_start, end_time=act_end,
                initial_capital=10_000.0,
            )
            engine = LongShortEngine(bt, db_config=config.db)

            t0 = time.time()
            try:
                r = await engine.run(RegimeEmaStrategy, sc)
                elapsed = time.time() - t0
            except Exception as ex:
                print(f"  {symbol:<10} {range_str:<22} {'错误: ' + str(ex)[:30]}")
                continue

            m = r.metrics
            long_t = [t for t in r.trades if t.pnl is not None and t.side == "SELL"]
            short_t = [t for t in r.trades if t.pnl is not None and t.side == "BUY"]
            long_pnl = sum(t.pnl for t in long_t) if long_t else 0
            short_pnl = sum(t.pnl for t in short_t) if short_t else 0

            print(f"  {symbol:<10} {range_str:<22} {m.total_return_pct:>7.1f}% {m.annual_return_pct:>7.1f}% {m.sharpe_ratio:>7.2f} {m.max_drawdown_pct:>7.1f}% {m.total_trades:>6} {long_pnl:>+10.0f} {short_pnl:>+10.0f} {elapsed:>6.1f}s")

            results.append({
                "interval": interval, "symbol": symbol,
                "return": m.total_return_pct, "annual": m.annual_return_pct,
                "sharpe": m.sharpe_ratio, "dd": m.max_drawdown_pct,
                "trades": m.total_trades, "win_rate": m.win_rate,
                "profit_factor": m.profit_factor,
                "long_pnl": long_pnl, "short_pnl": short_pnl,
                "elapsed": elapsed,
            })

    await ds.close()

    # ── 汇总排名 ──
    total_elapsed = time.time() - total_start
    print(f"\n  ■ 最佳组合 (按夏普排名)")
    print(f"  {'排名':<5} {'级别':<6} {'币种':<10} {'总收益%':>8} {'夏普':>7} {'回撤%':>8} {'交易':>6} {'胜率%':>7} {'盈亏比':>7}")
    print("  " + "─" * 75)

    sorted_results = sorted(results, key=lambda x: x["sharpe"], reverse=True)
    for i, r in enumerate(sorted_results):
        medal = ["🥇", "🥈", "🥉"][i] if i < 3 else f"{i+1:>2}."
        print(f"  {medal:<5} {r['interval']:<6} {r['symbol']:<10} {r['return']:>7.1f}% {r['sharpe']:>7.2f} {r['dd']:>7.1f}% {r['trades']:>6} {r['win_rate']*100:>6.1f}% {r['profit_factor']:>7.2f}")

    print(f"\n  总耗时: {total_elapsed:.1f}s")
    print("═" * 130)


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