#!/usr/bin/env python3
"""
浪浪AI 量化交易系统 — 回测入口

用法:
    # 下载数据并运行回测
    python run_backtest.py --download --end-date 2026-03-31

    # 仅运行回测（使用已有数据）
    python run_backtest.py

    # 指定初始资金
    python run_backtest.py --capital 1000

    # 只回测特定币种
    python run_backtest.py --coins BTCUSDT ETHUSDT
"""

import argparse
import os
import sys

# 确保项目根目录在 path 中
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

import pandas as pd
from langlang_ai.config.coins import COINS, all_symbols
from langlang_ai.data.binance_downloader import download_klines, load_klines, DATA_DIR
from langlang_ai.backtest.engine import BacktestEngine


def main():
    parser = argparse.ArgumentParser(description="浪浪AI 回测引擎")
    parser.add_argument("--capital", type=float, default=1000,
                        help="初始资金 (default: 1000)")
    parser.add_argument("--download", action="store_true",
                        help="从Binance下载最新数据")
    parser.add_argument("--end-date", type=str, default=None,
                        help="回测结束日期 YYYY-MM-DD (default: 数据末尾)")
    parser.add_argument("--coins", nargs="+", default=None,
                        help="指定币种 (default: 全部12个)")
    parser.add_argument("--output", type=str, default="backtest_trades.csv",
                        help="交易记录输出文件 (default: backtest_trades.csv)")
    parser.add_argument("--verbose", action="store_true",
                        help="输出信号过滤诊断日志")
    parser.add_argument("--sim", action="store_true",
                        help="使用模拟数据（不需要下载）")
    args = parser.parse_args()

    # 确定交易币种
    symbols = args.coins if args.coins else all_symbols()
    print(f"交易币种: {', '.join(symbols)}")

    # 加载数据
    all_data = {}

    if args.sim:
        # 使用模拟数据
        print("\n使用模拟历史数据（基于BTC真实周期结构）...")
        from langlang_ai.tests.data_generator import generate_all_test_data
        all_data = generate_all_test_data()
        # 只保留指定币种
        if args.coins:
            all_data = {k: v for k, v in all_data.items() if k in symbols}
    else:
        # 下载数据
        if args.download:
            print("\n正在下载K线数据...")
            for symbol in symbols:
                cfg = COINS[symbol]
                download_klines(symbol, "1h", cfg.data_start, args.end_date)
            print("下载完成！\n")

        # 从本地加载
        print("加载K线数据...")
        for symbol in symbols:
            try:
                df = load_klines(symbol, "1h")
                if args.end_date:
                    end = pd.Timestamp(args.end_date, tz='UTC')
                    df = df[df['timestamp'] <= end]
                all_data[symbol] = df
                print(f"  {symbol}: {len(df)} 根1H K线 "
                      f"({df['timestamp'].min().date()} ~ {df['timestamp'].max().date()})")
            except FileNotFoundError:
                print(f"  {symbol}: 未找到数据文件，请先用 --download 或 --sim")
                continue

    if not all_data:
        print("\n错误: 没有可用数据")
        print("  用模拟数据: python run_backtest.py --sim")
        print("  下载真实数据: python run_backtest.py --download")
        sys.exit(1)

    # 运行回测
    engine = BacktestEngine(initial_capital=args.capital, verbose=args.verbose)
    trades = engine.run(all_data)

    # 输出报告
    engine.print_report()

    # 过滤诊断
    if args.verbose:
        engine.print_filter_summary()
        engine.save_filter_log(args.output.replace('.csv', '_filtered.csv'))

    # 保存交易记录和HTML报告
    if trades:
        engine.save_trades(args.output)

        from langlang_ai.backtest.report import generate_report_html
        report_path = args.output.replace('.csv', '_report.html')
        generate_report_html(trades, args.capital, report_path)


if __name__ == "__main__":
    main()
