Spaces:
Running
Running
| # backend/main.py | |
| import argparse | |
| import sys | |
| import pandas as pd | |
| import datetime | |
| import os | |
| # 确保 backend 目录在 sys.path 中 | |
| sys.path.append(os.path.dirname(os.path.abspath(__file__))) | |
| from app.config import INITIAL_CASH, MAX_POSITION_SIZE_PCT, WATCHLIST | |
| from app.data_manager import fetch_and_prepare_data | |
| from app.patterns import analyze_patterns | |
| from app.simulator import run_backtest_sim | |
| def run_simulation(ticker, period="5d", interval="1m", strategy_mode="dynamic", position_sizing_mode="atr"): | |
| """ | |
| 运行日内/日线回测模拟器: | |
| 1. 获取历史数据(分钟级或日线级) | |
| 2. 运行 K 线形态与数值特征引擎 | |
| 3. 调用通用回测模拟器,执行带 Regime Router 和高级风控的模拟 | |
| 4. 输出交易业绩及对账流水 | |
| """ | |
| print("=" * 70) | |
| print(f" QUANT.AI - BACKTEST SIMULATOR (通用回测模拟器)") | |
| print(f" 股票代码: {ticker} | 周期: {interval} | 区间: {period} | 模式: {strategy_mode} | 仓位管理: {position_sizing_mode}") | |
| print("=" * 70) | |
| # 1. 抓取与计算全部技术数据 | |
| try: | |
| df_raw = fetch_and_prepare_data(ticker, period=period, interval=interval) | |
| df = analyze_patterns(df_raw) | |
| except Exception as e: | |
| print(f"数据加载或计算失败: {str(e)}") | |
| sys.exit(1) | |
| print(f"数据加载成功:常规交易时段共 {len(df)} 根 K 线。") | |
| print("正在启动模拟引擎...\n") | |
| # 2. 准备回测配置参数 | |
| strategy_params = { | |
| "strategy_mode": strategy_mode, | |
| "stop_loss_pct": 0.015, | |
| "profit_target_pct": 0.030, | |
| "trailing_stop_mode": "atr", | |
| "trailing_stop_atr_mult": 2.0, | |
| "rsi_threshold_buy": 65.0 | |
| } | |
| risk_params = { | |
| "slippage_rate": 0.0003, | |
| "commission_per_share": 0.005, | |
| "min_commission_per_order": 1.0, | |
| "position_sizing_mode": position_sizing_mode, | |
| "risk_per_trade_pct": 0.01, | |
| "max_position_size_pct": MAX_POSITION_SIZE_PCT | |
| } | |
| is_intraday = interval in ["1m", "5m", "15m", "30m", "1h"] | |
| # 3. 运行回测模拟 | |
| res = run_backtest_sim(df, ticker, strategy_params, risk_params, is_intraday=is_intraday) | |
| # 4. 输出回测统计报告 | |
| print("\n" + "=" * 70) | |
| print(" QUANT.AI - BACKTEST REPORT (回测统计报告)") | |
| print("=" * 70) | |
| print(f" 初始资金: $ {INITIAL_CASH:,.2f}") | |
| print(f" 最终资产: $ {res['final_equity']:,.2f}") | |
| print(f" 累计盈亏: $ {res['net_pnl']:+,.2f} ({res['pnl_pct']:+.2f}%)") | |
| print(f" 最大资产回撤: {res['max_drawdown']*100:.2f}%") | |
| print(f" 总交易笔数: {res['total_trades']} 次 (共 {res['round_trips']} 个平仓交易对)") | |
| print(f" 策略胜率: {res['win_rate']:.2f}%") | |
| print(f" 佣金总支出: $ {res['commission']:,.2f}") | |
| print("-" * 70) | |
| # 统计市场状态 (Regime) 分布 | |
| regime_counts = df['Regime'].value_counts() | |
| print("【市场状态路由占比 (Market Regimes Dist)】:") | |
| for regime_name, count in regime_counts.items(): | |
| pct = (count / len(df)) * 100 | |
| print(f" - {regime_name:<16}: {count:>5} 根 K线 ({pct:.2f}%)") | |
| print("-" * 70) | |
| # 打印交易流水账 | |
| ledger = res["ledger"] | |
| if len(ledger) > 0: | |
| print("【交易流水明细 (Transaction Ledger)】:") | |
| for t in ledger: | |
| pnl_str = f" | 利润: {t['realized_pnl']:+,.2f}" if t['action'] == 'SELL' else "" | |
| print(f" {t['timestamp']} | {t['action']} {t['ticker']} | 股数: {t['shares']} | 成交价: ${t['execution_price']:.2f} (市价: ${t['market_price']:.2f}) | 手续费: ${t['commission']:.2f}{pnl_str}") | |
| else: | |
| print("【提示】: 回测期间没有触发任何交易信号。系统防仓防守空仓!") | |
| print("=" * 70) | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser(description="Quant.ai 量化交易回测模拟器") | |
| parser.add_argument("--ticker", type=str, default="TSLA", help="测试股票代码 (默认: TSLA)") | |
| parser.add_argument("--period", type=str, default="5d", help="回测区间,支持 1d, 5d, 1mo, 1y 等 (默认: 5d)") | |
| parser.add_argument("--interval", type=str, default="1m", help="K线周期,支持 1m, 5m, 15m, 1d 等 (默认: 1m)") | |
| parser.add_argument("--strategy", type=str, default="dynamic", choices=["dynamic", "consensus", "ema_cross", "breakout", "patterns"], help="策略模式 (默认: dynamic)") | |
| parser.add_argument("--sizing", type=str, default="atr", choices=["atr", "flat"], help="仓位算仓模式 (默认: atr)") | |
| args = parser.parse_args() | |
| # 校验股票是否在池中 | |
| ticker = args.ticker.upper() | |
| if ticker not in WATCHLIST: | |
| print(f"[WARNING] 警告:{ticker} 不在预设监控池 {WATCHLIST} 中,将抓取数据测试。") | |
| run_simulation(ticker, period=args.period, interval=args.interval, strategy_mode=args.strategy, position_sizing_mode=args.sizing) | |