trading.ai/test_tushare_sectors.py
2025-09-23 16:12:18 +08:00

238 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()