# coding:utf-8

import requests
import pandas as pd
from sqlalchemy import create_engine
from datetime import datetime
from config import XUEQIU_HEADERS

def fetch_and_store_stock_data(db_url, table_name='limitup_analysis_stock_changes', page_size=100):
    """获取雪球数据并保存到数据库，只获取前3页数据"""
    base_url = 'https://stock.xueqiu.com/v5/stock/screener/quote/list.json'
    params = {
        'page': 1,
        'size': page_size,
        'order': 'desc',
        'order_by': 'percent',
        'market': 'CN',
        'type': 'sh_sz'
    }

    all_data = []
    # 只获取前3页数据
    for page in range(1, 4):
        params['page'] = page
        try:
            response = requests.get(base_url, headers=XUEQIU_HEADERS, params=params)
            if response.status_code == 200:
                data = response.json()
                all_data.extend(data['data']['list'])
            else:
                print("请求第 {} 页失败，状态码：{}".format(page, response.status_code))
        except Exception as e:
            print("请求第 {} 页时发生错误: {}".format(page, str(e)))

    if all_data:
        df = pd.DataFrame(all_data)
        df['id'] = range(1, len(df) + 1)
        engine = create_engine(db_url)
        df.to_sql(table_name, con=engine, if_exists='replace', index=False)
        return True
    return False

def analyze_limitup_stocks(db_url, sort_category):
    """分析涨停股票的封单情况和概念重叠度"""
    engine = create_engine(db_url)

    try:
        # 读取数据
        stock_changes_df = pd.read_sql_table('limitup_analysis_stock_changes', con=engine)
        gp_gnbk_df = pd.read_sql_table('gp_gnbk', con=engine)

        # 筛选涨停股票
        limitup_stocks = stock_changes_df[stock_changes_df['limitup_days'] > 0]

        results = []
        for _, row in limitup_stocks.iterrows():
            symbol = row['symbol']
            market_capital = row['float_market_capital']

            # 获取封单数据
            pankou_url = 'https://stock.xueqiu.com/v5/stock/realtime/pankou.json?symbol={}'.format(symbol)
            response = requests.get(pankou_url, headers=XUEQIU_HEADERS)
            if response.status_code == 200:
                data = response.json().get('data', {})
                bp1 = data.get('bp1', 0)
                bc1 = data.get('bc1', 0)

                if bp1 > 0 and bc1 > 0:
                    sealing_amount = bp1 * bc1
                    sealing_ratio = sealing_amount / market_capital
                    results.append((symbol, row['name'], sealing_amount, sealing_ratio))
            else:
                print("请求 {} 封单数据失败，状态码：{}".format(symbol, response.status_code))

        # 按指定方式排序并取前五
        results.sort(key=lambda x: x[2] if sort_category == 'sealed_amount' else x[3], reverse=True)
        top_stocks = results[:5]

        final_results = []
        for index, (symbol, name, sealing_amount, sealing_ratio) in enumerate(top_stocks):
            # 获取相关概念
            symbol_trimmed = symbol[2:]
            concepts = gp_gnbk_df[gp_gnbk_df['gp_code'] == symbol_trimmed]['bk_name'].tolist()

            # 找到概念重叠度最高的股票
            overlapping_stocks = gp_gnbk_df[
                gp_gnbk_df['bk_name'].isin(concepts) & 
                (gp_gnbk_df['gp_code'] != symbol_trimmed)
            ]
            overlap_counts = overlapping_stocks['gp_code'].value_counts()

            if not overlap_counts.empty:
                top_related_stock = overlap_counts.idxmax()
                top_related_count = overlap_counts.max()
                stock_changes_df['symbol_trimmed'] = stock_changes_df['symbol'].str[2:]
                top_related_name = stock_changes_df[
                    stock_changes_df['symbol_trimmed'] == top_related_stock
                ]['name'].values[0] if top_related_stock in stock_changes_df['symbol_trimmed'].values else None
            else:
                top_related_stock = None
                top_related_count = 0
                top_related_name = None

            final_results.append({
                'symbol': symbol_trimmed,
                'name': name,
                'sealing_amount': sealing_amount,
                'sealing_ratio': sealing_ratio,
                'top_related_stock': top_related_stock,
                'top_related_name': top_related_name,
                'overlap_count': top_related_count,
                'sequence': index + 1,
                'sort_categray': sort_category,
            })

        return final_results
    except Exception as e:
        print("分析过程中发生错误: {}".format(str(e)))
        return []

def save_results_to_db(db_url, results):
    """将分析结果保存到数据库"""
    if not results:
        print("没有数据需要保存")
        return

    df = pd.DataFrame(results)
    df['add_date'] = datetime.now().strftime('%Y-%m-%d')
    
    engine = create_engine(db_url)

    try:
        # 检查当天是否已有数据
        today = datetime.now().strftime('%Y-%m-%d')
        existing_data = pd.read_sql_query(
            "SELECT * FROM top_limitup_analysis WHERE add_date = '{}'".format(today),
            con=engine
        )

        # 处理重复数据
        if not existing_data.empty:
            existing_pairs = set(zip(existing_data['symbol'], existing_data['add_date']))
            duplicate_flags = [
                (row['symbol'], row['add_date']) in existing_pairs
                for idx, row in df.iterrows()
            ]
            df['is_duplicate'] = duplicate_flags
            new_records = df[df['is_duplicate'] == False].drop(columns=['is_duplicate'])
        else:
            new_records = df

        # 保存新记录
        if not new_records.empty:
            new_records.to_sql('top_limitup_analysis', con=engine, if_exists='append', index=False)

        # 打印结果
        for _, result in new_records.iterrows():
            print("股票代码: {}, 股票名称: {}, 封单金额: {:.2f}, 封单比例: {:.2%}".format(
                result['symbol'], result['name'], result['sealing_amount'], result['sealing_ratio']
            ))
            print("概念重叠度最高的个股: {} ({}), 重叠度: {}, 涨停序列: {}".format(
                result['top_related_stock'], result['top_related_name'], 
                result['overlap_count'], result['sequence']
            ))

    except Exception as e:
        print("保存数据时发生错误: {}".format(str(e)))

def analyze_limitup_stocks_main(db_url):
    """主函数：分析涨停股票并保存结果"""
    print("\n开始分析 - {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
    
    # 更新股票数据
    if not fetch_and_store_stock_data(db_url):
        print("更新股票数据失败")
        return
    
    print("\n按封单比例分析...")
    results_ratio = analyze_limitup_stocks(db_url, 'sealing_ratio')
    save_results_to_db(db_url, results_ratio)
    
    print("\n按封单金额分析...")
    results_amount = analyze_limitup_stocks(db_url, 'sealed_amount')
    save_results_to_db(db_url, results_amount)

if __name__ == "__main__":
    # 示例调用
    db_url = 'mysql+pymysql://root:Chlry#$.8@192.168.18.199:3306/db_gp_cj'
    analyze_limitup_stocks_main(db_url)