#!/usr/bin/env python3
"""
使用腾讯财经API获取市值数据，过滤已有扫描结果
排除条件: 1.市值<100亿 2.ST/*ST个股
"""
import json
import os
import re
import requests
import time
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, as_completed

WORK_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
RESULT_FILE = os.path.join(WORK_DIR, "scan_results.json")
OUTPUT_FILE = os.path.join(WORK_DIR, "scan_results_filtered.json")

session = requests.Session()
session.headers.update({'User-Agent': 'Mozilla/5.0'})


def get_tencent_prefix(code):
    """获取腾讯API的股票前缀"""
    if code.startswith(('00', '30')):
        return 'sz' + code
    elif code.startswith('60'):
        return 'sh' + code
    elif code.startswith('8'):
        return 'bj' + code
    return 'sz' + code


def batch_get_market_caps(codes, batch_size=40):
    """批量获取市值数据（腾讯API支持批量查询）"""
    caps = {}
    batches = [codes[i:i+batch_size] for i in range(0, len(codes), batch_size)]

    for i, batch in enumerate(batches):
        symbols = ','.join(get_tencent_prefix(c) for c in batch)
        url = f'http://qt.gtimg.cn/q={symbols}'
        try:
            resp = session.get(url, timeout=10)
            text = resp.text.strip()
            # 解析每个股票的数据
            # 格式: v_sz000001="..."; v_sz000002="...";
            lines = text.split(';')
            for line in lines:
                line = line.strip()
                if not line or '=' not in line:
                    continue
                match = re.search(r'v_\w+(\d{6})="(.+?)"', line)
                if not match:
                    continue
                code = match.group(1)
                fields = match.group(2).split('~')
                if len(fields) < 50:
                    continue
                try:
                    mkt_cap_yi = float(fields[44]) if fields[44] else 0  # 总市值(亿元)
                    name = fields[1]
                    price = float(fields[3]) if fields[3] else 0
                    caps[code] = {
                        'name': name,
                        'mkt_cap_yi': mkt_cap_yi,
                        'price': price,
                    }
                except (ValueError, IndexError):
                    continue
            if (i + 1) % 5 == 0:
                print(f"  进度: {i+1}/{len(batches)} 批, 已获取 {len(caps)} 只")
            time.sleep(0.15)  # 避免请求过快
        except Exception as e:
            print(f"  批次 {i+1} 失败: {e}")
            time.sleep(1)

    return caps


def main():
    with open(RESULT_FILE, 'r') as f:
        data = json.load(f)

    all_results = data.get('all_results', data.get('top50', []))
    print(f"原始扫描结果: {len(all_results)} 只股票有信号")

    # 获取所有股票代码
    all_codes = [s['code'] for s in all_results]
    print(f"正在获取 {len(all_codes)} 只股票的市值数据...")

    caps = batch_get_market_caps(all_codes)
    print(f"成功获取 {len(caps)} 只股票的市值数据")

    # 过滤
    filtered = []
    excluded_st = 0
    excluded_cap = 0
    no_cap_data = 0

    for stock in all_results:
        code = stock['code']
        name = stock['name']

        # 排除 ST/*ST
        if 'ST' in name or '*ST' in name or '退' in name:
            excluded_st += 1
            continue

        cap_info = caps.get(code)
        if not cap_info or cap_info['mkt_cap_yi'] <= 0:
            no_cap_data += 1
            continue  # 无法获取市值数据的跳过

        mkt_cap_yi = cap_info['mkt_cap_yi']

        # 排除市值 < 100亿
        if mkt_cap_yi < 100:
            excluded_cap += 1
            continue

        stock['mkt_cap_yi'] = mkt_cap_yi
        filtered.append(stock)

    # 排序
    filtered.sort(key=lambda x: x['signal_count'], reverse=True)

    print(f"\n过滤结果:")
    print(f"  排除ST/*ST: {excluded_st} 只")
    print(f"  排除市值<100亿: {excluded_cap} 只")
    print(f"  无市值数据(跳过): {no_cap_data} 只")
    print(f"  最终保留: {len(filtered)} 只")

    # 保存
    output = {
        "scan_date": datetime.now().strftime('%Y-%m-%d %H:%M'),
        "original_scan_date": data.get('scan_date', ''),
        "total_scanned": data.get('total_scanned', 0),
        "total_with_signals": len(filtered),
        "filter_criteria": "市值>=100亿, 排除ST/*ST",
        "top50": filtered[:50],
        "all_results": filtered,
    }

    with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
        json.dump(output, f, ensure_ascii=False, indent=2)

    print(f"\n过滤结果已保存到 {OUTPUT_FILE}")
    print(f"\nTop 15 个股:")
    for s in filtered[:15]:
        print(f"  {s['code']} {s['name']} | {s['signal_count']}个指标 | 市值={s['mkt_cap_yi']:.0f}亿 | 价格={s['latest_price']:.2f}")


if __name__ == '__main__':
    main()
