stock-ai-agent/backend/debug_astock_selector.py
2026-03-11 00:01:18 +08:00

226 lines
7.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
"""
A股短期题材选股 - 调试版本
用于诊断为什么没有选出股票
"""
import asyncio
import sys
import os
from datetime import datetime, timedelta
# 添加项目根目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from app.utils.logger import logger
from app.config import get_settings
from app.astock_agent.tushare_client import get_tushare_client
async def debug_tushare_connection():
"""测试Tushare连接"""
print("\n" + "=" * 60)
print("📊 测试1: Tushare连接测试")
print("=" * 60)
try:
settings = get_settings()
print(f"Token配置: {'已配置' if settings.tushare_token else '未配置'}")
if not settings.tushare_token:
print("❌ Tushare Token未配置请在.env文件中设置TUSHARE_TOKEN")
return False
ts_client = get_tushare_client(settings.tushare_token)
print(f"✅ Tushare客户端初始化成功")
# 测试基本API调用
print("\n测试API调用...")
# 测试获取概念板块
sectors_df = ts_client.get_concept_sectors()
print(f"概念板块数量: {len(sectors_df)}")
if not sectors_df.empty:
print(f"示例板块: {sectors_df.head(3)['name'].tolist()}")
else:
print("❌ 无法获取概念板块列表")
return False
return True
except Exception as e:
print(f"❌ Tushare连接失败: {e}")
import traceback
print(traceback.format_exc())
return False
async def debug_hot_sectors():
"""测试异动板块获取"""
print("\n" + "=" * 60)
print("📊 测试2: 异动板块检测")
print("=" * 60)
try:
settings = get_settings()
ts_client = get_tushare_client(settings.tushare_token)
sectors_df = ts_client.get_concept_sectors()
print(f"总概念板块数: {len(sectors_df)}")
# 检查异动板块
today = datetime.now().strftime('%Y%m%d')
print(f"当前日期: {today}")
# 检查是否是交易日
weekday = datetime.now().weekday()
if weekday >= 5:
print(f"⚠️ 当前是周末(周{weekday}),可能没有最新数据")
else:
print(f"✅ 当前是工作日(周{weekday}")
# 手动检查几个热门板块
print("\n检查前10个板块的行情...")
check_count = min(10, len(sectors_df))
hot_count = 0
for idx, row in sectors_df.head(check_count).iterrows():
ts_code = row['ts_code']
name = row['name']
try:
yesterday = (datetime.now() - timedelta(days=10)).strftime('%Y%m%d')
daily_df = ts_client.pro.ths_daily(
ts_code=ts_code,
start_date=yesterday,
end_date=today
)
if not daily_df.empty:
latest = daily_df.sort_values('trade_date').iloc[-1]
change_pct = float(latest.get('pct_change', 0))
trade_date = str(latest.get('trade_date', ''))
status = "🔥" if change_pct >= 2.0 else "📊"
print(f" {status} {name}: {change_pct:+.2f}% (日期: {trade_date})")
if change_pct >= 2.0:
hot_count += 1
else:
print(f" ⚠️ {name}: 无数据")
except Exception as e:
print(f"{name}: 查询失败 ({e})")
print(f"\n找到 {hot_count} 个涨幅≥2%的板块")
if hot_count == 0:
print("\n⚠️ 没有找到符合条件的异动板块,可能原因:")
print(" 1. 当前不是交易日(周末或节假日)")
print(" 2. 盘中时段数据未更新")
print(" 3. 市场整体表现平淡")
return hot_count > 0
except Exception as e:
print(f"❌ 异动板块检测失败: {e}")
import traceback
print(traceback.format_exc())
return False
async def debug_stock_screening():
"""测试个股筛选"""
print("\n" + "=" * 60)
print("📊 测试3: 个股筛选条件分析")
print("=" * 60)
print("\n筛选条件回顾:")
print(" 1. 市值: 50-500亿")
print(" 2. 换手率: 3%-15%")
print(" 3. 涨跌幅: -5% 到 +8%")
print(" 4. MA多头排列: MA5 > MA10 > MA20")
print(" 5. 量能配合: 量比 > 1.2")
print(" 6. 20日动量 > 0")
print(" 7. 距离高点回撤 < 15%")
print("\n⚠️ 如果没有选出股票,可能是因为:")
print(" 1. 市场整体不符合技术形态没有MA多头排列的股票")
print(" 2. 筛选条件较严格(可以尝试放宽参数)")
print(" 3. 数据时间窗口问题需要30天以上历史数据")
# 建议放宽的条件
print("\n建议放宽的参数(在当前市场环境下):")
print(" - 换手率: 1%-15% (降低下限)")
print(" - 涨跌幅: -7% 到 +10% (扩大范围)")
print(" - 市值: 30-500亿 (降低下限)")
async def debug_selector_run():
"""尝试运行选股器并显示详细信息"""
print("\n" + "=" * 60)
print("📊 测试4: 运行选股器(详细日志)")
print("=" * 60)
try:
from app.astock_agent.short_term_thematic_selector import get_thematic_selector
settings = get_settings()
ts_client = get_tushare_client(settings.tushare_token)
selector = get_thematic_selector(ts_client)
# 运行选股,启用详细日志
import logging
logging.basicConfig(level=logging.DEBUG)
result = selector.select_stocks(max_stocks=10)
print(f"\n选股结果: {result['total_stocks']}")
if result['total_stocks'] == 0:
print("\n❌ 未选出股票")
print("\n请查看上方详细日志,分析哪个环节过滤掉了股票")
else:
print("\n✅ 选股成功!")
print(selector.format_output_text(result))
except Exception as e:
print(f"❌ 选股器运行失败: {e}")
import traceback
print(traceback.format_exc())
async def main():
"""主函数"""
print("\n" + "=" * 60)
print("🔍 A股选股器诊断工具")
print("=" * 60)
# 运行所有测试
step1_ok = await debug_tushare_connection()
if not step1_ok:
print("\n❌ Tushare连接失败请检查配置")
return 1
step2_ok = await debug_hot_sectors()
if not step2_ok:
print("\n⚠️ 没有找到异动板块,这是正常的(取决于市场情况)")
await debug_stock_screening()
print("\n" + "=" * 60)
print("📋 诊断完成")
print("=" * 60)
print("\n如果所有测试通过但未选出股票,说明当前市场条件不符合策略要求。")
print("这是正常的,策略不会在市场条件不符合时强行选股。")
print("\n建议:")
print(" 1. 在交易日15:00后运行确保有完整数据")
print(" 2. 或者放宽筛选条件以适应当前市场环境")
print("")
return 0
if __name__ == "__main__":
exit_code = asyncio.run(main())
sys.exit(exit_code)