"""
因子类型对比实验

测试 4 种动量因子的回测表现：
1. weighted_momentum: 加权线性回归动量 (当前默认)
2. vol_adjusted_momentum: 波动率调整动量 (Moskowitz TSMOM)
3. slope_r2: 斜率 × R² (未加权)
4. momentum: 简单收益率

运行方式:
    cd /Users/aszer/code/etf
    python3 rotation/experiments/factor_comparison.py
"""

import os
import sys
import json
import yaml
import copy
from pathlib import Path
from datetime import datetime

PROJECT_ROOT = Path(__file__).parent.parent.parent
sys.path.insert(0, str(PROJECT_ROOT))

from rotation.simple_rotation import SimpleRotationStrategy
from rotation.config_loader import FactorType

FACTOR_TYPES = [
    ("weighted_momentum", "加权线性回归动量 (年化收益×R²)"),
    ("vol_adjusted_momentum", "波动率调整动量 (Sharpe-like×R²)"),
    ("slope_r2", "斜率×R² (未加权归一化)"),
    ("momentum", "简单收益率 (last/first-1)"),
]


def load_config():
    """Load base config"""
    config_path = PROJECT_ROOT / "rotation" / "config_simple.yaml"
    with open(config_path, 'r', encoding='utf-8') as f:
        return yaml.safe_load(f)


def run_factor_experiment(factor_type: str):
    """Run backtest with a specific factor type"""
    print(f"\n{'='*60}")
    print(f"  Testing: {factor_type}")
    print(f"{'='*60}")
    
    # Modify config to use this factor type
    config_path = PROJECT_ROOT / "rotation" / "config_simple.yaml"
    with open(config_path, 'r', encoding='utf-8') as f:
        config = yaml.safe_load(f)
    
    original_type = config['factor']['type']
    config['factor']['type'] = factor_type
    
    # Write temporary config
    with open(config_path, 'w', encoding='utf-8') as f:
        yaml.dump(config, f, allow_unicode=True, default_flow_style=False)
    
    try:
        # Run strategy
        strategy = SimpleRotationStrategy()
        result = strategy.run()
        
        if result:
            metrics = result.get('metrics', {})
            return {
                'factor_type': factor_type,
                'annual_return': metrics.get('annual_return', 0),
                'total_return': metrics.get('total_return', 0),
                'sharpe_ratio': metrics.get('sharpe_ratio', 0),
                'max_drawdown': metrics.get('max_drawdown', 0),
                'win_rate': metrics.get('win_rate', 0),
                'rebalance_count': metrics.get('rebalance_count', 0),
                'calmar_ratio': metrics.get('calmar_ratio', 0),
            }
    finally:
        # Restore original config
        config['factor']['type'] = original_type
        with open(config_path, 'w', encoding='utf-8') as f:
            yaml.dump(config, f, allow_unicode=True, default_flow_style=False)
    
    return None


def main():
    if 'FLASK_API_URL' not in os.environ:
        os.environ['FLASK_API_URL'] = 'https://k3s.tokenpluse.xyz'
    
    print("="*60)
    print("  ETF轮动策略 - 因子类型对比实验")
    print("="*60)
    
    results = []
    
    for factor_type, description in FACTOR_TYPES:
        print(f"\n>>> {description}")
        result = run_factor_experiment(factor_type)
        if result:
            results.append(result)
            print(f"  ✓ {factor_type}: 年化={result['annual_return']:.2%}, "
                  f"夏普={result['sharpe_ratio']:.2f}, 回撤={result['max_drawdown']:.2%}")
        else:
            print(f"  ✗ {factor_type}: 运行失败")
    
    # Summary table
    print(f"\n{'='*60}")
    print("  对比结果汇总")
    print(f"{'='*60}")
    print(f"{'因子类型':<25} {'年化收益':>10} {'夏普比率':>8} {'最大回撤':>10} {'调仓次数':>8} {'胜率':>6}")
    print("-"*60)
    
    for r in results:
        print(f"{r['factor_type']:<25} "
              f"{r['annual_return']:>9.2%} "
              f"{r['sharpe_ratio']:>8.2f} "
              f"{r['max_drawdown']:>9.2%} "
              f"{r['rebalance_count']:>8d} "
              f"{r['win_rate']:>5.1%}")
    
    # Find best
    if results:
        best = max(results, key=lambda x: x['sharpe_ratio'])
        print(f"\n★ 最优因子 (按夏普): {best['factor_type']}")
        print(f"  年化收益: {best['annual_return']:.2%}")
        print(f"  夏普比率: {best['sharpe_ratio']:.2f}")
        print(f"  最大回撤: {best['max_drawdown']:.2%}")
    
    # Save results
    output_dir = PROJECT_ROOT / "rotation" / "experiments" / "output"
    output_dir.mkdir(exist_ok=True)
    output_path = output_dir / "factor_comparison_results.json"
    with open(output_path, 'w', encoding='utf-8') as f:
        json.dump({
            'timestamp': datetime.now().isoformat(),
            'results': results
        }, f, ensure_ascii=False, indent=2)
    print(f"\n结果已保存: {output_path}")


if __name__ == "__main__":
    main()
