"""
东方财富融资融券数据采集模块
提供从东方财富网站采集融资融券数据并存储到数据库的功能
功能包括：
1. 采集融资融券数据
2. 存储数据到数据库
3. 定时自动更新数据
"""

import requests
import pandas as pd
import datetime
import logging
import time
import os
import sys
from pathlib import Path
from sqlalchemy import create_engine, text

# 添加项目根目录到Python路径
current_file = Path(__file__)
project_root = current_file.parent.parent.parent
sys.path.append(str(project_root))

from src.valuation_analysis.config import DB_URL, LOG_FILE

# 获取项目根目录
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 确保日志目录存在
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler(LOG_FILE),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger("eastmoney_rzrq_collector")


class EastmoneyRzrqCollector:
    """东方财富融资融券数据采集器类"""
    
    def __init__(self, db_url: str = DB_URL):
        """
        初始化东方财富融资融券数据采集器
        
        Args:
            db_url: 数据库连接URL
        """
        self.engine = create_engine(
            db_url,
            pool_size=5,
            max_overflow=10,
            pool_recycle=3600
        )
        self.base_url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
            "Accept": "application/json, text/plain, */*",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
            "Origin": "https://data.eastmoney.com",
            "Referer": "https://data.eastmoney.com/",
        }
        logger.info("东方财富融资融券数据采集器初始化完成")
    
    def _parse_date(self, date_str: str) -> datetime.date:
        """将日期字符串解析为日期对象"""
        if not date_str:
            return None
        try:
            return datetime.datetime.strptime(date_str.split()[0], "%Y-%m-%d").date()
        except ValueError:
            logger.error(f"日期解析失败: {date_str}")
            return None
    
    def _ensure_table_exists(self) -> bool:
        """
        确保数据表存在，如果不存在则创建
        
        Returns:
            是否成功确保表存在
        """
        try:
            create_table_query = text("""
            CREATE TABLE IF NOT EXISTS eastmoney_rzrq_data (
                trade_date DATE PRIMARY KEY,
                index_value DECIMAL(10,4) COMMENT '指数',
                change_percent DECIMAL(10,4) COMMENT '涨跌幅',
                float_market_value DECIMAL(20,2) COMMENT '流通市值',
                change_percent_3d DECIMAL(10,4) COMMENT '3日涨跌幅',
                change_percent_5d DECIMAL(10,4) COMMENT '5日涨跌幅',
                change_percent_10d DECIMAL(10,4) COMMENT '10日涨跌幅',
                financing_balance DECIMAL(20,2) COMMENT '融资余额',
                financing_balance_ratio DECIMAL(10,4) COMMENT '融资余额占比',
                financing_buy_amount DECIMAL(20,2) COMMENT '融资买入额',
                financing_buy_amount_3d DECIMAL(20,2) COMMENT '3日融资买入额',
                financing_buy_amount_5d DECIMAL(20,2) COMMENT '5日融资买入额',
                financing_buy_amount_10d DECIMAL(20,2) COMMENT '10日融资买入额',
                financing_repay_amount DECIMAL(20,2) COMMENT '融资偿还额',
                financing_repay_amount_3d DECIMAL(20,2) COMMENT '3日融资偿还额',
                financing_repay_amount_5d DECIMAL(20,2) COMMENT '5日融资偿还额',
                financing_repay_amount_10d DECIMAL(20,2) COMMENT '10日融资偿还额',
                financing_net_amount DECIMAL(20,2) COMMENT '融资净额',
                financing_net_amount_3d DECIMAL(20,2) COMMENT '3日融资净额',
                financing_net_amount_5d DECIMAL(20,2) COMMENT '5日融资净额',
                financing_net_amount_10d DECIMAL(20,2) COMMENT '10日融资净额',
                securities_balance DECIMAL(20,2) COMMENT '融券余额',
                securities_volume DECIMAL(20,2) COMMENT '融券余量',
                securities_repay_volume DECIMAL(20,2) COMMENT '融券偿还量',
                securities_repay_volume_3d DECIMAL(20,2) COMMENT '3日融券偿还量',
                securities_repay_volume_5d DECIMAL(20,2) COMMENT '5日融券偿还量',
                securities_repay_volume_10d DECIMAL(20,2) COMMENT '10日融券偿还量',
                securities_sell_volume DECIMAL(20,2) COMMENT '融券卖出量',
                securities_sell_volume_3d DECIMAL(20,2) COMMENT '3日融券卖出量',
                securities_sell_volume_5d DECIMAL(20,2) COMMENT '5日融券卖出量',
                securities_sell_volume_10d DECIMAL(20,2) COMMENT '10日融券卖出量',
                securities_net_volume DECIMAL(20,2) COMMENT '融券净量',
                securities_net_volume_3d DECIMAL(20,2) COMMENT '3日融券净量',
                securities_net_volume_5d DECIMAL(20,2) COMMENT '5日融券净量',
                securities_net_volume_10d DECIMAL(20,2) COMMENT '10日融券净量',
                total_rzrq_balance DECIMAL(20,2) COMMENT '融资融券余额',
                total_rzrq_balance_cz DECIMAL(20,2) COMMENT '融资融券余额差值',
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='东方财富融资融券数据表';
            """)
            
            with self.engine.connect() as conn:
                conn.execute(create_table_query)
                conn.commit()
                
            logger.info("东方财富融资融券数据表创建成功")
            return True
            
        except Exception as e:
            logger.error(f"确保数据表存在失败: {e}")
            return False
    
    def fetch_data(self, page: int = 1, page_size: int = 50) -> pd.DataFrame:
        """
        获取指定页码的融资融券数据
        
        Args:
            page: 页码
            page_size: 每页数据量
            
        Returns:
            包含融资融券数据的DataFrame
        """
        try:
            params = {
                "reportName": "RPTA_RZRQ_LSHJ",
                "columns": "ALL",
                "source": "WEB",
                "sortColumns": "dim_date",
                "sortTypes": "-1",
                "pageNumber": page,
                "pageSize": page_size
            }
            
            logger.info(f"开始获取第 {page} 页数据")
            
            response = requests.get(self.base_url, params=params, headers=self.headers)
            if response.status_code != 200:
                logger.error(f"获取第 {page} 页数据失败: HTTP {response.status_code}")
                return pd.DataFrame()
            
            data = response.json()
            if not data.get("success"):
                logger.error(f"获取数据失败: {data.get('message', '未知错误')}")
                return pd.DataFrame()
            
            # 提取数据列表
            items = data.get("result", {}).get("data", [])
            if not items:
                logger.warning(f"第 {page} 页未找到有效数据")
                return pd.DataFrame()
            
            # 转换为DataFrame
            df = pd.DataFrame(items)
            
            # 重命名列
            column_mapping = {
                "DIM_DATE": "trade_date",
                "NEW": "index_value",
                "ZDF": "change_percent",
                "LTSZ": "float_market_value",
                "ZDF3D": "change_percent_3d",
                "ZDF5D": "change_percent_5d",
                "ZDF10D": "change_percent_10d",
                "RZYE": "financing_balance",
                "RZYEZB": "financing_balance_ratio",
                "RZMRE": "financing_buy_amount",
                "RZMRE3D": "financing_buy_amount_3d",
                "RZMRE5D": "financing_buy_amount_5d",
                "RZMRE10D": "financing_buy_amount_10d",
                "RZCHE": "financing_repay_amount",
                "RZCHE3D": "financing_repay_amount_3d",
                "RZCHE5D": "financing_repay_amount_5d",
                "RZCHE10D": "financing_repay_amount_10d",
                "RZJME": "financing_net_amount",
                "RZJME3D": "financing_net_amount_3d",
                "RZJME5D": "financing_net_amount_5d",
                "RZJME10D": "financing_net_amount_10d",
                "RQYE": "securities_balance",
                "RQYL": "securities_volume",
                "RQCHL": "securities_repay_volume",
                "RQCHL3D": "securities_repay_volume_3d",
                "RQCHL5D": "securities_repay_volume_5d",
                "RQCHL10D": "securities_repay_volume_10d",
                "RQMCL": "securities_sell_volume",
                "RQMCL3D": "securities_sell_volume_3d",
                "RQMCL5D": "securities_sell_volume_5d",
                "RQMCL10D": "securities_sell_volume_10d",
                "RQJMG": "securities_net_volume",
                "RQJMG3D": "securities_net_volume_3d",
                "RQJMG5D": "securities_net_volume_5d",
                "RQJMG10D": "securities_net_volume_10d",
                "RZRQYE": "total_rzrq_balance",
                "RZRQYECZ": "total_rzrq_balance_cz"
            }
            
            df = df.rename(columns=column_mapping)
            
            # 转换日期格式
            df['trade_date'] = df['trade_date'].apply(self._parse_date)
            
            logger.info(f"第 {page} 页数据获取成功，包含 {len(df)} 条记录")
            return df
            
        except Exception as e:
            logger.error(f"获取第 {page} 页数据失败: {e}")
            return pd.DataFrame()
    
    def fetch_all_data(self, max_pages: int = 368) -> pd.DataFrame:
        """
        获取所有页的融资融券数据
        
        Args:
            max_pages: 最大页数
            
        Returns:
            包含所有融资融券数据的DataFrame
        """
        all_data = []
        
        for page in range(1, max_pages + 1):
            page_data = self.fetch_data(page)
            if page_data.empty:
                logger.info(f"第 {page} 页数据为空，停止采集")
                break
            all_data.append(page_data)
            # 添加延迟，避免请求过于频繁
            time.sleep(1)
        
        if all_data:
            combined_df = pd.concat(all_data, ignore_index=True)
            logger.info(f"数据采集完成，共采集 {len(combined_df)} 条记录")
            return combined_df
        else:
            logger.warning("未获取到任何有效数据")
            return pd.DataFrame()
    
    def save_to_database(self, data: pd.DataFrame) -> bool:
        """
        将数据保存到数据库
        
        Args:
            data: 要保存的数据DataFrame
            
        Returns:
            是否成功保存数据
        """
        if data.empty:
            logger.warning("没有数据需要保存")
            return False
        
        try:
            # 确保数据表存在
            if not self._ensure_table_exists():
                return False
            # 将nan值转换为None（在SQL中会变成NULL）
            data = data.replace({pd.NA: None, pd.NaT: None})
            data = data.where(pd.notnull(data), None)
            
            # 添加数据或更新已有数据
            inserted_count = 0
            updated_count = 0
            
            with self.engine.connect() as conn:
                for _, row in data.iterrows():
                    # 将Series转换为dict，并处理nan值
                    row_dict = {k: (None if pd.isna(v) else v) for k, v in row.items()}
                    
                    # 检查该日期的数据是否已存在
                    check_query = text("""
                    SELECT COUNT(*) FROM eastmoney_rzrq_data WHERE trade_date = :trade_date
                    """)
                    result = conn.execute(check_query, {"trade_date": row_dict['trade_date']}).scalar()
                    
                    if result > 0:  # 数据已存在，执行更新
                        update_query = text("""
                        UPDATE eastmoney_rzrq_data SET
                            index_value = :index_value,
                            change_percent = :change_percent,
                            float_market_value = :float_market_value,
                            change_percent_3d = :change_percent_3d,
                            change_percent_5d = :change_percent_5d,
                            change_percent_10d = :change_percent_10d,
                            financing_balance = :financing_balance,
                            financing_balance_ratio = :financing_balance_ratio,
                            financing_buy_amount = :financing_buy_amount,
                            financing_buy_amount_3d = :financing_buy_amount_3d,
                            financing_buy_amount_5d = :financing_buy_amount_5d,
                            financing_buy_amount_10d = :financing_buy_amount_10d,
                            financing_repay_amount = :financing_repay_amount,
                            financing_repay_amount_3d = :financing_repay_amount_3d,
                            financing_repay_amount_5d = :financing_repay_amount_5d,
                            financing_repay_amount_10d = :financing_repay_amount_10d,
                            financing_net_amount = :financing_net_amount,
                            financing_net_amount_3d = :financing_net_amount_3d,
                            financing_net_amount_5d = :financing_net_amount_5d,
                            financing_net_amount_10d = :financing_net_amount_10d,
                            securities_balance = :securities_balance,
                            securities_volume = :securities_volume,
                            securities_repay_volume = :securities_repay_volume,
                            securities_repay_volume_3d = :securities_repay_volume_3d,
                            securities_repay_volume_5d = :securities_repay_volume_5d,
                            securities_repay_volume_10d = :securities_repay_volume_10d,
                            securities_sell_volume = :securities_sell_volume,
                            securities_sell_volume_3d = :securities_sell_volume_3d,
                            securities_sell_volume_5d = :securities_sell_volume_5d,
                            securities_sell_volume_10d = :securities_sell_volume_10d,
                            securities_net_volume = :securities_net_volume,
                            securities_net_volume_3d = :securities_net_volume_3d,
                            securities_net_volume_5d = :securities_net_volume_5d,
                            securities_net_volume_10d = :securities_net_volume_10d,
                            total_rzrq_balance = :total_rzrq_balance,
                            total_rzrq_balance_cz = :total_rzrq_balance_cz
                        WHERE trade_date = :trade_date
                        """)
                        conn.execute(update_query, row_dict)
                        updated_count += 1
                    else:  # 数据不存在，执行插入
                        insert_query = text("""
                        INSERT INTO eastmoney_rzrq_data (
                            trade_date, index_value, change_percent, float_market_value,
                            change_percent_3d, change_percent_5d, change_percent_10d,
                            financing_balance, financing_balance_ratio,
                            financing_buy_amount, financing_buy_amount_3d, financing_buy_amount_5d, financing_buy_amount_10d,
                            financing_repay_amount, financing_repay_amount_3d, financing_repay_amount_5d, financing_repay_amount_10d,
                            financing_net_amount, financing_net_amount_3d, financing_net_amount_5d, financing_net_amount_10d,
                            securities_balance, securities_volume,
                            securities_repay_volume, securities_repay_volume_3d, securities_repay_volume_5d, securities_repay_volume_10d,
                            securities_sell_volume, securities_sell_volume_3d, securities_sell_volume_5d, securities_sell_volume_10d,
                            securities_net_volume, securities_net_volume_3d, securities_net_volume_5d, securities_net_volume_10d,
                            total_rzrq_balance, total_rzrq_balance_cz
                        ) VALUES (
                            :trade_date, :index_value, :change_percent, :float_market_value,
                            :change_percent_3d, :change_percent_5d, :change_percent_10d,
                            :financing_balance, :financing_balance_ratio,
                            :financing_buy_amount, :financing_buy_amount_3d, :financing_buy_amount_5d, :financing_buy_amount_10d,
                            :financing_repay_amount, :financing_repay_amount_3d, :financing_repay_amount_5d, :financing_repay_amount_10d,
                            :financing_net_amount, :financing_net_amount_3d, :financing_net_amount_5d, :financing_net_amount_10d,
                            :securities_balance, :securities_volume,
                            :securities_repay_volume, :securities_repay_volume_3d, :securities_repay_volume_5d, :securities_repay_volume_10d,
                            :securities_sell_volume, :securities_sell_volume_3d, :securities_sell_volume_5d, :securities_sell_volume_10d,
                            :securities_net_volume, :securities_net_volume_3d, :securities_net_volume_5d, :securities_net_volume_10d,
                            :total_rzrq_balance, :total_rzrq_balance_cz
                        )
                        """)
                        conn.execute(insert_query, row_dict)
                        inserted_count += 1
                
                conn.commit()
            
            logger.info(f"数据保存成功：新增 {inserted_count} 条记录，更新 {updated_count} 条记录")
            return True
            
        except Exception as e:
            logger.error(f"保存数据到数据库失败: {e}")
            return False
    
    def update_latest_data(self) -> bool:
        """
        更新最新一天的融资融券数据
        
        Returns:
            是否成功更新最新数据
        """
        try:
            logger.info("开始更新最新一天的融资融券数据")
            
            # 获取第一页数据
            df = self.fetch_data(1)
            if df.empty:
                logger.warning("未获取到最新数据")
                return False
            
            # 只保留第一行（最新一天的数据）
            latest_data = df.iloc[:1]
            
            # 保存数据到数据库
            result = self.save_to_database(latest_data)
            
            if result:
                logger.info(f"最新数据（{latest_data.iloc[0]['trade_date']}）更新成功")
            else:
                logger.warning("最新数据更新失败")
                
            return result
            
        except Exception as e:
            logger.error(f"更新最新数据失败: {e}")
            return False
    
    def initial_data_collection(self) -> bool:
        """
        每日更新任务采集融资融券数据
        
        Returns:
            是否成功采集所有数据
        """
        try:
            logger.info("开始获取最新融资融券数据...")
            df = self.fetch_data(page=1)
            
            if not df.empty:
                # 确保数据表存在
                if not self._ensure_table_exists():
                    return False
                
                # 处理第一页的所有数据
                success_count = 0
                total_count = len(df)
                
                with self.engine.connect() as conn:
                    for _, row in df.iterrows():
                        # 将Series转换为dict，并处理nan值
                        row_dict = {k: (None if pd.isna(v) else v) for k, v in row.items()}
                        
                        # 检查该日期的数据是否已存在
                        check_query = text("""
                        SELECT COUNT(*) FROM eastmoney_rzrq_data WHERE trade_date = :trade_date
                        """)
                        result = conn.execute(check_query, {"trade_date": row_dict['trade_date']}).scalar()
                        
                        if result > 0:  # 数据已存在，执行更新
                            update_query = text("""
                            UPDATE eastmoney_rzrq_data SET
                                index_value = :index_value,
                                change_percent = :change_percent,
                                float_market_value = :float_market_value,
                                change_percent_3d = :change_percent_3d,
                                change_percent_5d = :change_percent_5d,
                                change_percent_10d = :change_percent_10d,
                                financing_balance = :financing_balance,
                                financing_balance_ratio = :financing_balance_ratio,
                                financing_buy_amount = :financing_buy_amount,
                                financing_buy_amount_3d = :financing_buy_amount_3d,
                                financing_buy_amount_5d = :financing_buy_amount_5d,
                                financing_buy_amount_10d = :financing_buy_amount_10d,
                                financing_repay_amount = :financing_repay_amount,
                                financing_repay_amount_3d = :financing_repay_amount_3d,
                                financing_repay_amount_5d = :financing_repay_amount_5d,
                                financing_repay_amount_10d = :financing_repay_amount_10d,
                                financing_net_amount = :financing_net_amount,
                                financing_net_amount_3d = :financing_net_amount_3d,
                                financing_net_amount_5d = :financing_net_amount_5d,
                                financing_net_amount_10d = :financing_net_amount_10d,
                                securities_balance = :securities_balance,
                                securities_volume = :securities_volume,
                                securities_repay_volume = :securities_repay_volume,
                                securities_repay_volume_3d = :securities_repay_volume_3d,
                                securities_repay_volume_5d = :securities_repay_volume_5d,
                                securities_repay_volume_10d = :securities_repay_volume_10d,
                                securities_sell_volume = :securities_sell_volume,
                                securities_sell_volume_3d = :securities_sell_volume_3d,
                                securities_sell_volume_5d = :securities_sell_volume_5d,
                                securities_sell_volume_10d = :securities_sell_volume_10d,
                                securities_net_volume = :securities_net_volume,
                                securities_net_volume_3d = :securities_net_volume_3d,
                                securities_net_volume_5d = :securities_net_volume_5d,
                                securities_net_volume_10d = :securities_net_volume_10d,
                                total_rzrq_balance = :total_rzrq_balance,
                                total_rzrq_balance_cz = :total_rzrq_balance_cz
                            WHERE trade_date = :trade_date
                            """)
                            conn.execute(update_query, row_dict)
                            logger.info(f"更新数据成功，日期：{row_dict['trade_date']}")
                        else:  # 数据不存在，执行插入
                            insert_query = text("""
                            INSERT INTO eastmoney_rzrq_data (
                                trade_date, index_value, change_percent, float_market_value,
                                change_percent_3d, change_percent_5d, change_percent_10d,
                                financing_balance, financing_balance_ratio,
                                financing_buy_amount, financing_buy_amount_3d, financing_buy_amount_5d, financing_buy_amount_10d,
                                financing_repay_amount, financing_repay_amount_3d, financing_repay_amount_5d, financing_repay_amount_10d,
                                financing_net_amount, financing_net_amount_3d, financing_net_amount_5d, financing_net_amount_10d,
                                securities_balance, securities_volume,
                                securities_repay_volume, securities_repay_volume_3d, securities_repay_volume_5d, securities_repay_volume_10d,
                                securities_sell_volume, securities_sell_volume_3d, securities_sell_volume_5d, securities_sell_volume_10d,
                                securities_net_volume, securities_net_volume_3d, securities_net_volume_5d, securities_net_volume_10d,
                                total_rzrq_balance, total_rzrq_balance_cz
                            ) VALUES (
                                :trade_date, :index_value, :change_percent, :float_market_value,
                                :change_percent_3d, :change_percent_5d, :change_percent_10d,
                                :financing_balance, :financing_balance_ratio,
                                :financing_buy_amount, :financing_buy_amount_3d, :financing_buy_amount_5d, :financing_buy_amount_10d,
                                :financing_repay_amount, :financing_repay_amount_3d, :financing_repay_amount_5d, :financing_repay_amount_10d,
                                :financing_net_amount, :financing_net_amount_3d, :financing_net_amount_5d, :financing_net_amount_10d,
                                :securities_balance, :securities_volume,
                                :securities_repay_volume, :securities_repay_volume_3d, :securities_repay_volume_5d, :securities_repay_volume_10d,
                                :securities_sell_volume, :securities_sell_volume_3d, :securities_sell_volume_5d, :securities_sell_volume_10d,
                                :securities_net_volume, :securities_net_volume_3d, :securities_net_volume_5d, :securities_net_volume_10d,
                                :total_rzrq_balance, :total_rzrq_balance_cz
                            )
                            """)
                            conn.execute(insert_query, row_dict)
                            logger.info(f"插入新数据成功，日期：{row_dict['trade_date']}")
                        
                        success_count += 1
                    
                    conn.commit()
                
                logger.info(f"数据处理完成：成功处理 {success_count}/{total_count} 条记录")
                return success_count > 0
            else:
                logger.warning("未获取到最新数据")
                return False
            
        except Exception as e:
            logger.error(f"每日更新任务采集失败: {e}")
            return False
    
    def get_chart_data(self, limit_days: int = 30) -> dict:
        """
        获取融资融券数据用于图表展示
        
        Args:
            limit_days: 获取最近多少天的数据，默认30天
            
        Returns:
            dict: 包含图表所需数据的字典
        """
        try:
            logger.info(f"获取最近 {limit_days} 天融资融券数据用于图表展示")
            
            # 构建SQL查询
            query = text("""
            SELECT 
                trade_date,
                financing_balance,
                financing_buy_amount,
                securities_balance,
                total_rzrq_balance
            FROM eastmoney_rzrq_data
            ORDER BY trade_date DESC
            LIMIT :limit_days
            """)
            
            # 执行查询
            with self.engine.connect() as conn:
                result = conn.execute(query, {"limit_days": limit_days}).fetchall()
                
            if not result:
                logger.warning("未找到融资融券数据")
                return {"success": False, "message": "未找到融资融券数据"}
            
            # 将结果转换为列表并倒序，使日期按升序排列
            rows = []
            for row in result:
                # 将每行结果转换为字典
                row_dict = {
                    'trade_date': row.trade_date,
                    'financing_balance': row.financing_balance,
                    'financing_buy_amount': row.financing_buy_amount, 
                    'securities_balance': row.securities_balance,
                    'total_rzrq_balance': row.total_rzrq_balance
                }
                rows.append(row_dict)
            
            # 反转列表使日期按升序排列
            rows.reverse()
            
            # 准备数据
            dates = []
            total_rzrq_balance = []  # 融资融券余额合计
            total_financing_buy = []  # 融资买入额合计
            total_financing_balance = []  # 融资余额合计
            financing_repayment = []  # 融资偿还
            securities_balance = []  # 融券余额
            
            prev_financing_balance = None  # 上一日融资余额
            
            for i, row in enumerate(rows):
                dates.append(row['trade_date'].strftime('%Y-%m-%d'))
                # 将金额从元转换为亿元（除以1亿）
                total_rzrq_balance.append(round(float(row['total_rzrq_balance']) / 100000000, 2))
                total_financing_buy.append(round(float(row['financing_buy_amount']) / 100000000, 2))
                total_financing_balance.append(round(float(row['financing_balance']) / 100000000, 2))
                securities_balance.append(round(float(row['securities_balance']) / 100000000, 2))
                
                # 计算融资偿还 = 融资买入额 + 前一日融资余额 - 当日融资余额
                if i > 0 and prev_financing_balance is not None:
                    # 注意：这里不需要再除以1亿，因为前面的数据已经是亿元单位
                    repayment = float(row['financing_buy_amount']) / 100000000 + prev_financing_balance - float(row['financing_balance']) / 100000000
                    financing_repayment.append(round(repayment, 2))
                else:
                    financing_repayment.append(None)  # 第一天无法计算
                
                prev_financing_balance = float(row['financing_balance']) / 100000000  # 转换为亿元单位
            
            # 计算市场风险分析指标
            risk_indicators = self.analyze_market_risk(
                dates=dates,
                total_rzrq_balance=total_rzrq_balance,
                total_financing_balance=total_financing_balance,
                total_financing_buy=total_financing_buy,
                securities_balance=securities_balance
            )
            
            # 构建返回数据
            chart_data = {
                "success": True,
                "dates": dates,
                "series": [
                    {
                        "name": "融资融券余额合计",
                        "data": total_rzrq_balance,
                        "unit": "亿元"
                    },
                    {
                        "name": "融资买入额合计",
                        "data": total_financing_buy,
                        "unit": "亿元"
                    },
                    {
                        "name": "融资余额合计",
                        "data": total_financing_balance,
                        "unit": "亿元"
                    },
                    {
                        "name": "融资偿还",
                        "data": financing_repayment,
                        "unit": "亿元"
                    },
                    {
                        "name": "融券余额",
                        "data": securities_balance,
                        "unit": "亿元"
                    }
                ],
                "risk_indicators": risk_indicators
            }
            
            # 添加更新时间
            chart_data["last_update"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            
            logger.info(f"成功获取 {len(dates)} 天的融资融券图表数据")
            return chart_data
            
        except Exception as e:
            logger.error(f"获取融资融券图表数据失败: {e}")
            return {"success": False, "message": f"获取数据失败: {str(e)}"}
            
    def analyze_market_risk(self, dates, total_rzrq_balance, total_financing_balance, total_financing_buy, securities_balance):
        """
        分析融资融券数据，计算市场风险指标
        
        Args:
            dates: 日期列表
            total_rzrq_balance: 融资融券余额合计列表
            total_financing_balance: 融资余额合计列表
            total_financing_buy: 融资买入额合计列表
            securities_balance: 融券余额列表
            
        Returns:
            dict: 包含风险指标的字典
        """
        try:
            # 确保数据长度足够
            if len(dates) < 5:
                return {"warning": "数据量不足，无法进行完整分析"}
                
            risk_indicators = {}
            
            # 1. 计算融资融券余额趋势 - 近期变化率
            recent_days = 5  # 分析最近5天的变化
            if len(total_rzrq_balance) >= recent_days:
                latest_balance = total_rzrq_balance[-1]
                prev_balance = total_rzrq_balance[-recent_days]
                
                if prev_balance > 0:
                    balance_change_rate = (latest_balance - prev_balance) / prev_balance * 100
                    balance_change_direction = "上升" if balance_change_rate > 0 else "下降"
                    
                    risk_indicators["recent_balance_change"] = {
                        "rate": round(balance_change_rate, 2),
                        "direction": balance_change_direction,
                        "days": recent_days,
                        "start_date": dates[-recent_days],
                        "end_date": dates[-1],
                        "start_value": round(prev_balance, 2),
                        "end_value": round(latest_balance, 2)
                    }
                    
                    # 风险评级 - 融资融券余额变化
                    if balance_change_rate > 10:
                        balance_risk_level = "高"
                        balance_risk_desc = f"近{recent_days}天融资融券余额快速上升{abs(round(balance_change_rate, 2))}%，市场杠杆水平快速提升，风险较高"
                    elif balance_change_rate > 5:
                        balance_risk_level = "中"
                        balance_risk_desc = f"近{recent_days}天融资融券余额上升{abs(round(balance_change_rate, 2))}%，市场杠杆水平有所提升"
                    elif balance_change_rate < -10:
                        balance_risk_level = "高"
                        balance_risk_desc = f"近{recent_days}天融资融券余额快速下降{abs(round(balance_change_rate, 2))}%，市场杠杆水平快速下降，可能伴随抛压"
                    elif balance_change_rate < -5:
                        balance_risk_level = "中"
                        balance_risk_desc = f"近{recent_days}天融资融券余额下降{abs(round(balance_change_rate, 2))}%，市场杠杆水平有所下降"
                    else:
                        balance_risk_level = "低"
                        balance_risk_desc = f"近{recent_days}天融资融券余额变化{round(balance_change_rate, 2)}%，市场杠杆水平相对稳定"
                        
                    risk_indicators["balance_risk"] = {
                        "level": balance_risk_level,
                        "description": balance_risk_desc
                    }
            
            # 2. 计算融资偿还比例 - 衡量资金偿还压力
            # 融资偿还比例 = 当日融资偿还 / 当日融资买入
            recent_days_repay = min(5, len(total_financing_buy) - 1)  # 考虑数据长度
            if recent_days_repay > 0:
                # 计算近几天的平均偿还买入比
                repay_buy_ratios = []
                for i in range(1, recent_days_repay + 1):
                    if total_financing_buy[-i] > 0:
                        # 融资偿还 = 当日融资买入额 + 前一日融资余额 - 当日融资余额
                        if i < len(total_financing_balance) and i+1 < len(total_financing_balance):
                            repayment = total_financing_buy[-i] + total_financing_balance[-(i+1)] - total_financing_balance[-i]
                            ratio = repayment / total_financing_buy[-i]
                            repay_buy_ratios.append(ratio)
                
                if repay_buy_ratios:
                    avg_repay_buy_ratio = sum(repay_buy_ratios) / len(repay_buy_ratios)
                    
                    risk_indicators["repay_buy_ratio"] = {
                        "value": round(avg_repay_buy_ratio, 2),
                        "days": recent_days_repay
                    }
                    
                    # 风险评级 - 偿还率
                    if avg_repay_buy_ratio > 1.2:
                        repay_risk_level = "高"
                        repay_risk_desc = f"近期融资偿还与买入比率为{round(avg_repay_buy_ratio, 2)}，偿还明显大于买入，市场存在较强的抛压"
                    elif avg_repay_buy_ratio > 1.05:
                        repay_risk_level = "中"
                        repay_risk_desc = f"近期融资偿还与买入比率为{round(avg_repay_buy_ratio, 2)}，偿还略大于买入，市场抛压增加"
                    elif avg_repay_buy_ratio < 0.8:
                        repay_risk_level = "中"
                        repay_risk_desc = f"近期融资偿还与买入比率为{round(avg_repay_buy_ratio, 2)}，买入明显大于偿还，杠杆快速提升"
                    else:
                        repay_risk_level = "低"
                        repay_risk_desc = f"近期融资偿还与买入比率为{round(avg_repay_buy_ratio, 2)}，买入与偿还较为平衡"
                        
                    risk_indicators["repay_risk"] = {
                        "level": repay_risk_level,
                        "description": repay_risk_desc
                    }
            
            # 3. 融券余额变化 - 分析空头力量
            if len(securities_balance) >= recent_days:
                latest_securities = securities_balance[-1]
                prev_securities = securities_balance[-recent_days]
                
                if prev_securities > 0:
                    securities_change_rate = (latest_securities - prev_securities) / prev_securities * 100
                    securities_change_direction = "上升" if securities_change_rate > 0 else "下降"
                    
                    risk_indicators["securities_balance_change"] = {
                        "rate": round(securities_change_rate, 2),
                        "direction": securities_change_direction,
                        "days": recent_days,
                        "start_value": round(prev_securities, 2),
                        "end_value": round(latest_securities, 2)
                    }
                    
                    # 风险评级 - 融券余额变化
                    if securities_change_rate > 15:
                        securities_risk_level = "高"
                        securities_risk_desc = f"近{recent_days}天融券余额快速上升{abs(round(securities_change_rate, 2))}%，空头力量显著增强"
                    elif securities_change_rate > 8:
                        securities_risk_level = "中"
                        securities_risk_desc = f"近{recent_days}天融券余额上升{abs(round(securities_change_rate, 2))}%，空头力量有所增强"
                    elif securities_change_rate < -15:
                        securities_risk_level = "低"
                        securities_risk_desc = f"近{recent_days}天融券余额快速下降{abs(round(securities_change_rate, 2))}%，空头力量显著减弱"
                    elif securities_change_rate < -8:
                        securities_risk_level = "低"
                        securities_risk_desc = f"近{recent_days}天融券余额下降{abs(round(securities_change_rate, 2))}%，空头力量有所减弱"
                    else:
                        securities_risk_level = "正常"
                        securities_risk_desc = f"近{recent_days}天融券余额变化{round(securities_change_rate, 2)}%，空头力量相对稳定"
                        
                    risk_indicators["securities_risk"] = {
                        "level": securities_risk_level,
                        "description": securities_risk_desc
                    }
            
            # 4. 融资占比 - 融资余额占融资融券余额的比例
            if total_rzrq_balance[-1] > 0:
                financing_ratio = total_financing_balance[-1] / total_rzrq_balance[-1]
                risk_indicators["financing_ratio"] = round(financing_ratio * 100, 2)
                
                # 融资占比的历史百分位数计算
                if len(total_rzrq_balance) > 20:  # 至少需要20天数据计算有意义的百分位数
                    historical_ratios = []
                    for i in range(len(total_rzrq_balance)):
                        if total_rzrq_balance[i] > 0:
                            ratio = total_financing_balance[i] / total_rzrq_balance[i]
                            historical_ratios.append(ratio)
                    
                    if historical_ratios:
                        # 计算融资占比的百分位数
                        sorted_ratios = sorted(historical_ratios)
                        percentile_rank = sorted_ratios.index(financing_ratio) / len(sorted_ratios) * 100 if financing_ratio in sorted_ratios else 0
                        
                        # 如果不在列表中，找到最接近的位置
                        if percentile_rank == 0:
                            for i, ratio in enumerate(sorted_ratios):
                                if ratio > financing_ratio:
                                    percentile_rank = i / len(sorted_ratios) * 100
                                    break
                            if percentile_rank == 0 and financing_ratio > sorted_ratios[-1]:
                                percentile_rank = 100
                                
                        risk_indicators["financing_ratio_percentile"] = round(percentile_rank, 2)
            
            # 5. 综合风险评估
            risk_levels = []
            if "balance_risk" in risk_indicators:
                risk_levels.append(risk_indicators["balance_risk"]["level"])
            if "repay_risk" in risk_indicators:
                risk_levels.append(risk_indicators["repay_risk"]["level"])
            if "securities_risk" in risk_indicators:
                risk_levels.append(risk_indicators["securities_risk"]["level"])
                
            # 计算综合风险等级
            high_count = risk_levels.count("高")
            medium_count = risk_levels.count("中")
            
            if high_count >= 2:
                overall_risk = "高"
                overall_desc = "多个指标显示市场风险较高，融资融券数据反映市场杠杆或波动风险增加"
            elif high_count == 1 or medium_count >= 2:
                overall_risk = "中"
                overall_desc = "部分指标显示市场风险增加，建议关注融资融券数据变化"
            else:
                overall_risk = "低"
                overall_desc = "融资融券数据显示市场风险较低，杠杆水平相对稳定"
                
            risk_indicators["overall_risk"] = {
                "level": overall_risk,
                "description": overall_desc
            }
            
            return risk_indicators
            
        except Exception as e:
            logger.error(f"分析市场风险指标失败: {e}")
            return {"error": f"分析失败: {str(e)}"}


def get_create_table_sql() -> str:
    """
    获取创建东方财富融资融券数据表的SQL语句
    
    Returns:
        创建表的SQL语句
    """
    return """
    CREATE TABLE IF NOT EXISTS eastmoney_rzrq_data (
        trade_date DATE PRIMARY KEY,
        index_value DECIMAL(10,4) COMMENT '指数',
        change_percent DECIMAL(10,4) COMMENT '涨跌幅',
        float_market_value DECIMAL(20,2) COMMENT '流通市值',
        change_percent_3d DECIMAL(10,4) COMMENT '3日涨跌幅',
        change_percent_5d DECIMAL(10,4) COMMENT '5日涨跌幅',
        change_percent_10d DECIMAL(10,4) COMMENT '10日涨跌幅',
        financing_balance DECIMAL(20,2) COMMENT '融资余额',
        financing_balance_ratio DECIMAL(10,4) COMMENT '融资余额占比',
        financing_buy_amount DECIMAL(20,2) COMMENT '融资买入额',
        financing_buy_amount_3d DECIMAL(20,2) COMMENT '3日融资买入额',
        financing_buy_amount_5d DECIMAL(20,2) COMMENT '5日融资买入额',
        financing_buy_amount_10d DECIMAL(20,2) COMMENT '10日融资买入额',
        financing_repay_amount DECIMAL(20,2) COMMENT '融资偿还额',
        financing_repay_amount_3d DECIMAL(20,2) COMMENT '3日融资偿还额',
        financing_repay_amount_5d DECIMAL(20,2) COMMENT '5日融资偿还额',
        financing_repay_amount_10d DECIMAL(20,2) COMMENT '10日融资偿还额',
        financing_net_amount DECIMAL(20,2) COMMENT '融资净额',
        financing_net_amount_3d DECIMAL(20,2) COMMENT '3日融资净额',
        financing_net_amount_5d DECIMAL(20,2) COMMENT '5日融资净额',
        financing_net_amount_10d DECIMAL(20,2) COMMENT '10日融资净额',
        securities_balance DECIMAL(20,2) COMMENT '融券余额',
        securities_volume DECIMAL(20,2) COMMENT '融券余量',
        securities_repay_volume DECIMAL(20,2) COMMENT '融券偿还量',
        securities_repay_volume_3d DECIMAL(20,2) COMMENT '3日融券偿还量',
        securities_repay_volume_5d DECIMAL(20,2) COMMENT '5日融券偿还量',
        securities_repay_volume_10d DECIMAL(20,2) COMMENT '10日融券偿还量',
        securities_sell_volume DECIMAL(20,2) COMMENT '融券卖出量',
        securities_sell_volume_3d DECIMAL(20,2) COMMENT '3日融券卖出量',
        securities_sell_volume_5d DECIMAL(20,2) COMMENT '5日融券卖出量',
        securities_sell_volume_10d DECIMAL(20,2) COMMENT '10日融券卖出量',
        securities_net_volume DECIMAL(20,2) COMMENT '融券净量',
        securities_net_volume_3d DECIMAL(20,2) COMMENT '3日融券净量',
        securities_net_volume_5d DECIMAL(20,2) COMMENT '5日融券净量',
        securities_net_volume_10d DECIMAL(20,2) COMMENT '10日融券净量',
        total_rzrq_balance DECIMAL(20,2) COMMENT '融资融券余额',
        total_rzrq_balance_cz DECIMAL(20,2) COMMENT '融资融券余额差值',
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='东方财富融资融券数据表';
    """


# 示例使用方式
if __name__ == "__main__":
    # 创建东方财富融资融券数据采集器
    collector = EastmoneyRzrqCollector()
    
    # 获取最新一页数据
    logger.info("开始获取最新融资融券数据...")
    df = collector.fetch_data(page=1)
    
    if not df.empty:
        # 保存数据到数据库
        if collector.save_to_database(df):
            logger.info(f"成功更新最新数据，日期：{df.iloc[0]['trade_date']}")
        else:
            logger.error("更新最新数据失败")
    else:
        logger.warning("未获取到最新数据")

    # 输出创建表的SQL语句
    # print("创建表的SQL语句：")
    # print(get_create_table_sql())
    #
    # # 首次全量采集数据
    # print("\n开始首次全量采集数据...")
    # collector.initial_data_collection()