#!/usr/bin/env python3
"""V1 vs V2 回测结果对比"""

import pandas as pd
import numpy as np
from datetime import datetime

print("=" * 80)
print("V1 vs V2 回测结果对比报告")
print("=" * 80)
print(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()

# V1 结果
print("【V1 回测结果】(原始框架)")
print("-" * 80)
v1_nav = pd.read_csv('results/v1_comparison_2020_2026_nav.csv')
v1_nav['cal_date'] = pd.to_datetime(v1_nav['cal_date'])
v1_nav = v1_nav.set_index('cal_date')

start_nav = v1_nav.iloc[0]['策略净值']
end_nav = v1_nav.iloc[-1]['策略净值']
total_days = len(v1_nav)
years = total_days / 252

total_return = (end_nav - start_nav) / start_nav * 100
annual_return = ((end_nav / start_nav) ** (1/years) - 1) * 100

# 计算最大回撤
cummax = v1_nav['策略净值'].cummax()
drawdown = (v1_nav['策略净值'] - cummax) / cummax
max_drawdown = drawdown.min() * 100

# 计算夏普比率
daily_returns = v1_nav['策略净值'].pct_change().dropna()
sharpe = daily_returns.mean() / daily_returns.std() * np.sqrt(252)

print(f"回测区间: {v1_nav.index[0].strftime('%Y-%m-%d')} ~ {v1_nav.index[-1].strftime('%Y-%m-%d')}")
print(f"交易天数: {total_days}")
print(f"起始净值: {start_nav:.4f}")
print(f"结束净值: {end_nav:.4f}")
print(f"总收益: {total_return:.2f}%")
print(f"年化收益: {annual_return:.2f}%")
print(f"最大回撤: {max_drawdown:.2f}%")
print(f"夏普比率: {sharpe:.2f}")
print()

# V2 结果
print("【V2 回测结果】(framework_v2)")
print("-" * 80)
v2_nav = pd.read_csv('framework_v2/results/simple_rotation_equity.csv')
v2_nav['date'] = pd.to_datetime(v2_nav['date'])
v2_nav = v2_nav.set_index('date')

# V2 的第二列名是 '0'（需要确认）
v2_equity_col = v2_nav.columns[0]  # 获取第一列
start_nav_v2 = v2_nav.iloc[0][v2_equity_col]
end_nav_v2 = v2_nav.iloc[-1][v2_equity_col]
total_days_v2 = len(v2_nav)
years_v2 = total_days_v2 / 252

total_return_v2 = (end_nav_v2 - start_nav_v2) / start_nav_v2 * 100
annual_return_v2 = ((end_nav_v2 / start_nav_v2) ** (1/years_v2) - 1) * 100

cummax_v2 = v2_nav[v2_equity_col].cummax()
drawdown_v2 = (v2_nav[v2_equity_col] - cummax_v2) / cummax_v2
max_drawdown_v2 = drawdown_v2.min() * 100

daily_returns_v2 = v2_nav[v2_equity_col].pct_change().dropna()
sharpe_v2 = daily_returns_v2.mean() / daily_returns_v2.std() * np.sqrt(252)

print(f"回测区间: {v2_nav.index[0].strftime('%Y-%m-%d')} ~ {v2_nav.index[-1].strftime('%Y-%m-%d')}")
print(f"交易天数: {total_days_v2}")
print(f"起始净值: {start_nav_v2:.4f}")
print(f"结束净值: {end_nav_v2:.4f}")
print(f"总收益: {total_return_v2:.2f}%")
print(f"年化收益: {annual_return_v2:.2f}%")
print(f"最大回撤: {max_drawdown_v2:.2f}%")
print(f"夏普比率: {sharpe_v2:.2f}")
print()

# 对比分析
print("=" * 80)
print("【对比分析】")
print("=" * 80)

print(f"{'指标':<15} {'V1':>15} {'V2':>15} {'差异':>15}")
print("-" * 80)

start_str = f"{v1_nav.index[0].strftime('%Y-%m')}~{v1_nav.index[-1].strftime('%Y-%m')}"
end_str = f"{v2_nav.index[0].strftime('%Y-%m')}~{v2_nav.index[-1].strftime('%Y-%m')}"
print(f"{'回测区间':<15} {start_str:>15} {end_str:>15} {'':>15}")
print(f"{'交易天数':<15} {total_days:>15} {total_days_v2:>15} {total_days_v2 - total_days:>+15}")
print(f"{'起始净值':<15} {start_nav:>15.4f} {start_nav_v2:>15.4f} {start_nav_v2 - start_nav:>+15.4f}")
print(f"{'结束净值':<15} {end_nav:>15.4f} {end_nav_v2:>15.4f} {end_nav_v2 - end_nav:>+15.4f}")
print(f"{'总收益':<15} {total_return:>14.2f}% {total_return_v2:>14.2f}% {total_return_v2 - total_return:>+14.2f}%")
print(f"{'年化收益':<15} {annual_return:>14.2f}% {annual_return_v2:>14.2f}% {annual_return_v2 - annual_return:>+14.2f}%")
print(f"{'最大回撤':<15} {max_drawdown:>14.2f}% {max_drawdown_v2:>14.2f}% {max_drawdown_v2 - max_drawdown:>+14.2f}%")
print(f"{'夏普比率':<15} {sharpe:>15.2f} {sharpe_v2:>15.2f} {sharpe_v2 - sharpe:>+15.2f}")
print()

# 收益差异分析
print("=" * 80)
print("【收益差异分析】")
print("=" * 80)
diff = total_return_v2 - total_return
if diff > 0:
    print(f"V2 比 V1 多赚 {diff:.2f}%")
    print(f"如果初始资金 100 万，V2 多赚 {1000000 * diff / 100:,.0f} 元")
else:
    print(f"V2 比 V1 少赚 {abs(diff):.2f}%")
    print(f"如果初始资金 100 万，V2 少赚 {1000000 * abs(diff) / 100:,.0f} 元")

print()

# 关键差异原因分析
print("=" * 80)
print("【关键差异原因分析】")
print("=" * 80)
print("""
✅ 已修复的问题：
1. ✓ 交易日过滤：V2 现在只保留 A 股交易日（1539 天）
2. ✓ 起始日期对齐：V2 从 2020-01-10 开始（与 V1 一致）

⚠️  仍然存在的核心差异（导致 V2 收益 +878%）：

1. 调仓逻辑差异（最关键）：
   - V1: 完整的调仓控制
     * rebalance_days: 1 (最低持仓1天)
     * rebalance_threshold: 0.0 (新组合需超过当前组合0%才调仓)
     * 实际效果：减少不必要的调仓
   - V2: 简化版（每日调仓，无阈值）
     * 每天都根据信号重新选股
     * 频繁调仓可能导致更高的收益（但也可能增加交易成本）

2. 交易成本：
   - V1: trade_cost: 0.001 (0.1%)
     * 每次调仓扣除 0.1% 成本
     * 404 次调仓 * 0.1% = 约 40.4% 的累计成本
   - V2: 未计入交易成本
     * 这是收益差异的重要来源

3. 溢价控制：
   - V1: 启用溢价过滤（premium_control.enabled: true）
     * 默认阈值: 10%
     * 过滤高溢价 ETF，避免买入亏损
     * 可能错过一些机会，但降低风险
   - V2: 未实现溢价控制
     * 可以买入任何 ETF，包括高溢价的

4. 动态阈值：
   - V1: bond_threshold 启用
     * 标的动量 < 短债动量 → 不持有
     * 更保守的策略，避免负动量资产
   - V2: 使用 fixed_value: 0.0
     * 只过滤负动量，不如 V1 严格

5. 数据获取方式：
   - V1: 使用 ETF 净值数据（etf_nav_data）
     * 更准确的实际交易价格
   - V2: 使用 trade_source 指定的 ETF/指数收盘价
     * 可能存在差异（特别是跨境 ETF）

6. 信号-交易分离实现：
   - V1: 通过 etf 字段映射
   - V2: 通过 signal_source/trade_source 显式字段
   - 理论上应该一致，但实现细节可能不同

📊 收益差异量化分析：
V2 收益 981.95% - V1 收益 103.29% = 878.66% 差异

可能来源：
1. 交易成本缺失：约 -40%（V1 有，V2 无）
2. 频繁调仓：可能 +200~300%（V2 每日调仓 vs V1 有阈值）
3. 溢价控制缺失：可能 +50~100%（V2 可买高溢价 ETF）
4. 动态阈值差异：可能 +100~200%（V2 更激进）
5. 其他实现细节：约 +200~300%

⚠️  结论：
V2 的超高收益主要来自：
1. 未计入交易成本（虚增约 40%）
2. 每日调仓 vs 有阈值的调仓（显著差异）
3. 缺少溢价控制和动态阈值（更激进）

要进行完全公平的对比，需要在 V2 中实现：
1. ✓ 交易成本计算
2. ✓ 调仓阈值控制
3. ✓ 溢价过滤
4. ✓ 动态短债阈值
""")

print("=" * 80)
