#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
生成30分钟级别市场状态识别图表
"""

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from datetime import datetime
import warnings
warnings.filterwarnings('ignore')

print("="*70)
print("生成30分钟市场状态识别图表")
print("="*70)

# 读取30分钟结果数据
df = pd.read_csv('cyb50_30min_regime_result.csv', index_col='datetime', parse_dates=True)

print(f"\n数据范围: {df.index[0]} ~ {df.index[-1]}")
print(f"数据条数: {len(df)}个30分钟周期")

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

# 状态名称和颜色
state_names = ['震荡', '趋势', '反转']
colors = ['#2196F3', '#4CAF50', '#FF5722']  # 蓝、绿、橙

# 创建图表
fig, axes = plt.subplots(3, 1, figsize=(20, 14))

# 图1: 价格走势 + 状态标记
ax1 = axes[0]
ax1.plot(df.index, df['close'], 'k-', alpha=0.3, linewidth=0.5, label='收盘价')

for i, (name, color) in enumerate(zip(state_names, colors)):
    mask = df['state'] == i
    if mask.any():
        ax1.scatter(df.index[mask], df['close'][mask],
                   c=color, label=name, alpha=0.6, s=20)

ax1.set_ylabel('价格', fontsize=12)
ax1.set_title('CYB50 30分钟市场状态识别 (2024-2026)', fontsize=14, fontweight='bold')
ax1.legend(loc='upper left', fontsize=10)
ax1.grid(True, alpha=0.3)

# 格式化x轴日期
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax1.xaxis.set_major_locator(mdates.MonthLocator(interval=2))

# 图2: 状态概率时间序列
ax2 = axes[1]
ax2.fill_between(df.index, 0, df['prob_ranging'],
                 alpha=0.5, label='震荡', color=colors[0])
ax2.fill_between(df.index, df['prob_ranging'],
                 df['prob_ranging'] + df['prob_trend'],
                 alpha=0.5, label='趋势', color=colors[1])
ax2.fill_between(df.index,
                 df['prob_ranging'] + df['prob_trend'], 1,
                 alpha=0.5, label='反转', color=colors[2])

ax2.set_ylabel('概率', fontsize=12)
ax2.set_title('30分钟状态概率时间序列', fontsize=12)
ax2.legend(loc='upper left', fontsize=10)
ax2.grid(True, alpha=0.3)
ax2.set_ylim(0, 1)
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax2.xaxis.set_major_locator(mdates.MonthLocator(interval=2))

# 图3: 状态分布统计
ax3 = axes[2]
state_counts = df['state'].value_counts().sort_index()
bars = ax3.bar(range(3), state_counts.values, color=colors, alpha=0.7)
ax3.set_xticks(range(3))
ax3.set_xticklabels(state_names)
ax3.set_ylabel('周期数', fontsize=12)
ax3.set_title('30分钟状态分布统计', fontsize=12)

# 添加数值标签
for i, (bar, count) in enumerate(zip(bars, state_counts.values)):
    pct = count / len(df) * 100
    ax3.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 20,
             f'{count}\n({pct:.1f}%)',
             ha='center', va='bottom', fontsize=11, fontweight='bold')

plt.tight_layout()
plt.savefig('cyb50_30min_regime_chart.png', dpi=150, bbox_inches='tight')
print("\n[OK] 图表已保存: cyb50_30min_regime_chart.png")

# 生成详细报告
print("\n" + "="*70)
print("30分钟级别详细识别结果")
print("="*70)

# 按月份统计
print("\n【月度统计 - 最近6个月】")
print(f"{'月份':<12} {'总周期':<8} {'震荡':<8} {'趋势':<8} {'反转':<8} {'主要状态':<10}")
print("-"*70)

recent_months = df[df.index >= '2024-09-01'].copy()
for year_month in sorted(recent_months.index.to_period('M').unique()):
    mask = recent_months.index.to_period('M') == year_month
    month_data = recent_months[mask]
    total = len(month_data)
    ranging = (month_data['state'] == 0).sum()
    trend = (month_data['state'] == 1).sum()
    reversal = (month_data['state'] == 2).sum()

    main_state = state_names[month_data['state'].mode()[0]]

    print(f"{str(year_month):<12} {total:<8} {ranging:<8} {trend:<8} {reversal:<8} {main_state:<10}")

# 最近一周详细数据
print("\n【最近一周详细数据】")
print(f"{'日期时间':<20} {'收盘价':<10} {'状态':<8} {'震荡%':<8} {'趋势%':<8} {'反转%':<8}")
print("-"*70)

last_week = df.tail(40)  # 约5个交易日
for idx, row in last_week.iterrows():
    state = state_names[int(row['state'])]
    print(f"{str(idx):<20} {row['close']:<10.2f} {state:<8} "
          f"{row['prob_ranging']:<8.1%} {row['prob_trend']:<8.1%} {row['prob_reversal']:<8.1%}")

print("\n" + "="*70)
print("[OK] 报告生成完成!")
print("="*70)
