131 lines
4.2 KiB
Python
131 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
测试单个股票的筛选逻辑
|
|
"""
|
|
import asyncio
|
|
import sys
|
|
import os
|
|
|
|
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
|
|
from app.astock_agent.short_term_thematic_selector import get_thematic_selector
|
|
|
|
|
|
async def test_single_stock():
|
|
"""测试单个股票"""
|
|
print("\n" + "=" * 80)
|
|
print("🔍 测试单个股票筛选")
|
|
print("=" * 80)
|
|
|
|
settings = get_settings()
|
|
ts_client = get_tushare_client(settings.tushare_token)
|
|
selector = get_thematic_selector(ts_client)
|
|
|
|
# 测试股票代码(从诊断脚本中找到的通过股票)
|
|
test_stock = "000682.SZ"
|
|
|
|
# 获取该股票所属的板块
|
|
sectors_df = ts_client.get_concept_sectors()
|
|
smart_grid = sectors_df[sectors_df['name'] == '智能电网']
|
|
|
|
if smart_grid.empty:
|
|
print("未找到智能电网板块")
|
|
return
|
|
|
|
sector_code = smart_grid.iloc[0]['ts_code']
|
|
sector_name = smart_grid.iloc[0]['name']
|
|
|
|
# 获取板块成分股
|
|
members_df = ts_client.get_sector_members(sector_code)
|
|
stock_codes = members_df['con_code'].tolist()
|
|
|
|
if test_stock not in stock_codes:
|
|
print(f"{test_stock} 不在智能电网板块中")
|
|
return
|
|
|
|
print(f"\n测试股票: {test_stock}")
|
|
print(f"所属板块: {sector_name} ({sector_code})")
|
|
print(f"板块成分股数量: {len(stock_codes)}")
|
|
print(f"测试股票在板块中的位置: {stock_codes.index(test_stock) + 1}/{len(stock_codes)}")
|
|
|
|
# 获取实时行情 - 检查更多股票
|
|
check_count = min(200, len(stock_codes))
|
|
print(f"\n获取前 {check_count} 只股票的实时行情...")
|
|
|
|
realtime_df = ts_client.get_realtime_data(stock_codes[:check_count])
|
|
|
|
if realtime_df.empty:
|
|
print("无法获取实时行情")
|
|
return
|
|
|
|
print(f"实时行情数据获取成功,共 {len(realtime_df)} 只股票")
|
|
|
|
# 检查目标股票是否在行情数据中
|
|
if test_stock not in realtime_df['ts_code'].values:
|
|
print(f"❌ {test_stock} 不在行情数据中")
|
|
print(f"行情数据中的股票: {realtime_df['ts_code'].tolist()[:10]}")
|
|
return
|
|
|
|
stock_row = realtime_df[realtime_df['ts_code'] == test_stock].iloc[0]
|
|
print(f"\n✓ {test_stock} 行情数据:")
|
|
print(f" 现价: {stock_row['close']}")
|
|
print(f" 涨跌幅: {stock_row['pct_chg']}%")
|
|
print(f" 成交量: {stock_row['vol']}")
|
|
print(f" 成交额: {stock_row['amount']}千元")
|
|
|
|
# 获取每日指标
|
|
trade_date = realtime_df.iloc[0]['trade_date']
|
|
basic_df = ts_client.get_stock_daily_basic([test_stock], str(trade_date))
|
|
|
|
print(f"\n每日指标数据: {'有' if not basic_df.empty else '无'}")
|
|
if not basic_df.empty:
|
|
basic_row = basic_df[basic_df['ts_code'] == test_stock]
|
|
if not basic_row.empty:
|
|
print(f" 换手率: {basic_row.iloc[0]['turnover_rate']}%")
|
|
|
|
# 调用选股器的内部检查函数
|
|
print("\n开始筛选检查...")
|
|
print("=" * 80)
|
|
|
|
# 检查所有股票
|
|
passed_stocks = []
|
|
for idx, stock_code in enumerate(stock_codes[:check_count], 1):
|
|
try:
|
|
result = selector._check_single_stock(
|
|
stock_code=stock_code,
|
|
sector_name=sector_name,
|
|
sector_change=2.77,
|
|
realtime_df=realtime_df,
|
|
basic_df=basic_df
|
|
)
|
|
|
|
if result:
|
|
passed_stocks.append((stock_code, result.get('name', '')))
|
|
print(f" ✓ [{idx}] {stock_code}: {result.get('name', '')}")
|
|
|
|
except Exception as e:
|
|
print(f" ✗ [{idx}] {stock_code}: 检查失败 - {e}")
|
|
|
|
print("=" * 80)
|
|
print(f"\n检查了 {check_count} 只股票,通过筛选: {len(passed_stocks)} 只")
|
|
|
|
if passed_stocks:
|
|
print("\n✅ 通过的股票:")
|
|
for stock_code, name in passed_stocks[:20]: # 只显示前20只
|
|
print(f" - {stock_code}: {name}")
|
|
if len(passed_stocks) > 20:
|
|
print(f" ... 还有 {len(passed_stocks) - 20} 只")
|
|
else:
|
|
print("\n❌ 没有股票通过筛选")
|
|
|
|
|
|
async def main():
|
|
await test_single_stock()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|