#!/usr/bin/env python3
"""
获取159930 ETF最新10天的收盘价、净值并计算溢价率
"""

import os
import pandas as pd
import tushare as ts
from datetime import datetime, timedelta

# 设置Tushare token
def get_tushare_token():
    # 首先尝试从环境变量获取
    token = os.environ.get("TUSHARE_TOKEN")
    if token:
        return token
    
    # 尝试从.env文件获取
    try:
        from dotenv import load_dotenv
        load_dotenv()
        token = os.environ.get("TUSHARE_TOKEN")
        if token:
            return token
    except ImportError:
        pass
    
    # 手动读取.env文件
    env_path = os.path.join(os.path.dirname(__file__), '.env')
    if os.path.exists(env_path):
        with open(env_path, 'r') as f:
            for line in f:
                if line.startswith('TUSHARE_TOKEN='):
                    token = line.strip().split('=', 1)[1].strip().strip('"').strip("'")
                    if token:
                        return token
    
    raise ValueError("请设置 TUSHARE_TOKEN 环境变量或在.env文件中配置")


def fetch_etf_data(etf_code: str, days: int = 10):
    """
    获取ETF最新N天的价格、净值数据
    
    Args:
        etf_code: ETF代码，如 "159930.SZ"
        days: 获取天数
    
    Returns:
        DataFrame: 包含日期、收盘价、净值、溢价率
    """
    pro = ts.pro_api(get_tushare_token())
    
    # 计算日期范围（多取几天确保有足够数据）
    end_date = datetime.now()
    start_date = end_date - timedelta(days=days + 5)
    
    start_str = start_date.strftime('%Y%m%d')
    end_str = end_date.strftime('%Y%m%d')
    
    # 转换代码格式
    ts_code = etf_code.replace(".SS", ".SH")
    
    print(f"获取 {etf_code} 数据...")
    print(f"日期范围: {start_str} ~ {end_str}")
    
    # 1. 获取ETF价格数据（fund_daily接口）
    print("\n1. 获取ETF价格数据...")
    try:
        price_df = pro.fund_daily(
            ts_code=ts_code,
            start_date=start_str,
            end_date=end_str
        )
        if price_df is not None and len(price_df) > 0:
            price_df = price_df.sort_values('trade_date')
            print(f"   获取到 {len(price_df)} 条价格数据")
            print(f"   最新日期: {price_df['trade_date'].max()}")
        else:
            print("   未获取到价格数据")
            price_df = None
    except Exception as e:
        print(f"   获取价格数据失败: {e}")
        price_df = None
    
    # 2. 获取ETF净值数据（fund_nav接口）
    print("\n2. 获取ETF净值数据...")
    try:
        # 净值通常滞后，多取一天
        nav_end_date = end_date + timedelta(days=1)
        nav_end_str = nav_end_date.strftime('%Y%m%d')
        
        nav_df = pro.fund_nav(
            ts_code=ts_code,
            start_date=start_str,
            end_date=nav_end_str
        )
        if nav_df is not None and len(nav_df) > 0:
            nav_df = nav_df.sort_values('nav_date')
            print(f"   获取到 {len(nav_df)} 条净值数据")
            print(f"   最新日期: {nav_df['nav_date'].max()}")
        else:
            print("   未获取到净值数据")
            nav_df = None
    except Exception as e:
        print(f"   获取净值数据失败: {e}")
        nav_df = None
    
    # 3. 合并数据并计算溢价率
    print("\n3. 合并数据并计算溢价率...")
    
    if price_df is None:
        print("错误: 没有价格数据")
        return None
    
    # 准备价格数据
    price_df['date'] = pd.to_datetime(price_df['trade_date'])
    price_df = price_df.set_index('date')
    price_series = price_df['close']
    
    # 准备净值数据
    if nav_df is not None:
        nav_df['date'] = pd.to_datetime(nav_df['nav_date'])
        nav_df = nav_df.set_index('date')
        nav_series = nav_df['unit_nav']
    else:
        nav_series = pd.Series()
    
    # 创建结果DataFrame
    result = pd.DataFrame({
        '收盘价': price_series
    })
    
    # 对齐净值数据（按日期）
    result = result.join(nav_series.rename('净值'), how='left')
    
    # 计算溢价率
    result['溢价率'] = (result['收盘价'] - result['净值']) / result['净值'] * 100
    
    # 取最新N天
    result = result.tail(days)
    
    # 格式化输出
    result['收盘价'] = result['收盘价'].round(3)
    result['净值'] = result['净值'].round(3)
    result['溢价率'] = result['溢价率'].round(2)
    
    # 重置索引，将日期作为列
    result = result.reset_index()
    result['日期'] = result['date'].dt.strftime('%Y-%m-%d')
    result = result[['日期', '收盘价', '净值', '溢价率']]
    
    return result


def main():
    """主函数"""
    etf_code = "159930.SZ"
    days = 10
    
    print("=" * 60)
    print(f"ETF: {etf_code} (中证能源ETF)")
    print(f"获取最近 {days} 天数据")
    print("=" * 60)
    
    df = fetch_etf_data(etf_code, days)
    
    if df is not None and len(df) > 0:
        print("\n" + "=" * 60)
        print("结果表格:")
        print("=" * 60)
        print(df.to_string(index=False))
        
        # 保存到CSV
        output_file = f"{etf_code.replace('.', '_')}_latest_{days}days.csv"
        df.to_csv(output_file, index=False, encoding='utf-8-sig')
        print(f"\n数据已保存到: {output_file}")
    else:
        print("\n获取数据失败")


if __name__ == "__main__":
    main()
