#!/usr/bin/env python3 """ 使用Tushare直接获取板块数据的测试 """ import sys from pathlib import Path import pandas as pd from datetime import datetime, timedelta # 添加项目根目录到路径 current_dir = Path(__file__).parent sys.path.insert(0, str(current_dir)) from src.data.tushare_fetcher import TushareFetcher from loguru import logger def get_concept_sectors(fetcher: TushareFetcher): """获取概念板块数据""" try: if not fetcher.pro: logger.error("需要Tushare Pro权限") return logger.info("尝试获取概念板块数据...") # 1. 尝试获取概念板块列表 try: concept_list = fetcher.pro.concept() logger.info(f"获取到 {len(concept_list)} 个概念板块") if not concept_list.empty: print("概念板块列表(前10个):") for _, concept in concept_list.head(10).iterrows(): print(f" {concept['code']}: {concept['name']}") except Exception as e: logger.error(f"获取概念板块列表失败: {e}") # 2. 尝试获取同花顺概念指数 try: ths_concept = fetcher.pro.ths_index(exchange='A', type='N') logger.info(f"获取同花顺概念指数: {len(ths_concept)} 个") if not ths_concept.empty: print("\n同花顺概念指数(前10个):") for _, index in ths_concept.head(10).iterrows(): print(f" {index['ts_code']}: {index['name']}") except Exception as e: logger.error(f"获取同花顺概念指数失败: {e}") # 3. 尝试获取行业指数 try: industry_index = fetcher.pro.index_basic(market='SW') logger.info(f"获取申万行业指数: {len(industry_index)} 个") if not industry_index.empty: print("\n申万行业指数(前10个):") for _, index in industry_index.head(10).iterrows(): print(f" {index['ts_code']}: {index['name']}") except Exception as e: logger.error(f"获取申万行业指数失败: {e}") except Exception as e: logger.error(f"获取板块数据失败: {e}") def analyze_hot_concepts(fetcher: TushareFetcher): """分析热门概念板块""" try: if not fetcher.pro: logger.error("需要Tushare Pro权限") return logger.info("分析热门概念板块...") # 获取今日涨跌停统计 today = datetime.now().strftime('%Y%m%d') try: # 获取涨停股票 limit_up = fetcher.pro.limit_list(trade_date=today, limit_type='U') logger.info(f"今日涨停股票: {len(limit_up)} 只") if not limit_up.empty: print(f"\n今日涨停股票(前10只):") for _, stock in limit_up.head(10).iterrows(): print(f" {stock['ts_code']}: {stock['name']} (+{stock['pct_chg']:.2f}%)") # 分析涨停股票的行业分布 if 'industry' in limit_up.columns: industry_counts = limit_up['industry'].value_counts() print(f"\n涨停股票行业分布:") for industry, count in industry_counts.head(5).items(): print(f" {industry}: {count}只") except Exception as e: logger.error(f"获取涨停数据失败: {e}") # 获取龙虎榜数据 try: top_list = fetcher.pro.top_list(trade_date=today) logger.info(f"今日龙虎榜: {len(top_list)} 只股票") if not top_list.empty: print(f"\n今日龙虎榜股票(前5只):") for _, stock in top_list.head(5).iterrows(): print(f" {stock['ts_code']}: {stock['name']} 净买入: {stock['amount']:.0f}万元") except Exception as e: logger.error(f"获取龙虎榜数据失败: {e}") except Exception as e: logger.error(f"分析热门概念失败: {e}") def get_sector_performance_direct(fetcher: TushareFetcher): """直接通过指数数据获取板块表现""" try: if not fetcher.pro: logger.error("需要Tushare Pro权限") return logger.info("通过指数数据分析板块表现...") # 获取申万一级行业指数 try: sw_index = fetcher.pro.index_basic(market='SW', level='L1') logger.info(f"获取申万一级行业指数: {len(sw_index)} 个") if sw_index.empty: logger.warning("未获取到申万行业指数") return # 获取最近两个交易日的指数行情 end_date = datetime.now().strftime('%Y%m%d') start_date = (datetime.now() - timedelta(days=7)).strftime('%Y%m%d') sector_performance = [] for _, index in sw_index.head(15).iterrows(): # 分析前15个行业 ts_code = index['ts_code'] name = index['name'] try: # 获取指数行情 index_data = fetcher.pro.index_daily( ts_code=ts_code, start_date=start_date, end_date=end_date ) if not index_data.empty and len(index_data) >= 2: # 计算涨跌幅 latest = index_data.iloc[0] previous = index_data.iloc[1] change_pct = (latest['close'] - previous['close']) / previous['close'] * 100 sector_performance.append({ 'name': name, 'code': ts_code, 'change_pct': change_pct, 'latest_close': latest['close'], 'volume': latest['vol'] }) logger.debug(f"{name}: {change_pct:+.2f}%") except Exception as e: logger.debug(f"获取 {name} 指数数据失败: {e}") continue # 输出结果 if sector_performance: df = pd.DataFrame(sector_performance) df = df.sort_values('change_pct', ascending=False) print("\n" + "="*60) print("📈 申万行业指数表现排行") print("="*60) print(f"{'排名':<4} {'行业名称':<20} {'涨跌幅':<10} {'最新点位':<10}") print("-" * 60) for i, (_, row) in enumerate(df.iterrows()): rank = i + 1 name = row['name'][:18] + '..' if len(row['name']) > 18 else row['name'] change = f"{row['change_pct']:+.2f}%" close = f"{row['latest_close']:.2f}" print(f"{rank:<4} {name:<20} {change:<10} {close:<10}") # 强势行业 print(f"\n🚀 强势行业TOP5:") for _, row in df.head(5).iterrows(): print(f" {row['name']}: {row['change_pct']:+.2f}%") # 弱势行业 print(f"\n📉 弱势行业TOP5:") for _, row in df.tail(5).iterrows(): print(f" {row['name']}: {row['change_pct']:+.2f}%") except Exception as e: logger.error(f"获取申万指数失败: {e}") except Exception as e: logger.error(f"分析板块表现失败: {e}") def main(): """主函数""" logger.info("测试Tushare板块数据接口...") # 初始化Tushare数据获取器 token = "0ed6419a00d8923dc19c0b58fc92d94c9a0696949ab91a13aa58a0cc" fetcher = TushareFetcher(token=token) # 1. 获取板块分类数据 get_concept_sectors(fetcher) print("\n" + "="*80 + "\n") # 2. 分析热门概念 analyze_hot_concepts(fetcher) print("\n" + "="*80 + "\n") # 3. 通过指数直接获取板块表现 get_sector_performance_direct(fetcher) logger.info("测试完成!") if __name__ == "__main__": main()