151 lines
5.2 KiB
Python
151 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
诊断板块资金异动检测
|
||
检查为什么没有找到异动板块
|
||
"""
|
||
import asyncio
|
||
import sys
|
||
import os
|
||
from datetime import datetime, timedelta
|
||
|
||
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 diagnose_sector_detection():
|
||
"""诊断板块检测"""
|
||
print("\n" + "=" * 80)
|
||
print("🔍 板块资金异动诊断")
|
||
print("=" * 80)
|
||
|
||
settings = get_settings()
|
||
ts_client = get_tushare_client(settings.tushare_token)
|
||
|
||
# 获取热门概念板块
|
||
print("\n【第一步】获取热门概念板块...")
|
||
hot_concept_sectors = [
|
||
'人工智能', '新能源汽车', '芯片', '半导体', '5G',
|
||
'智能电网', '物联网', '云计算', '大数据', '区块链'
|
||
]
|
||
|
||
sectors_df = ts_client.get_concept_sectors()
|
||
|
||
# 找到热门板块
|
||
hot_sectors_codes = []
|
||
for hot_name in hot_concept_sectors:
|
||
matches = sectors_df[sectors_df['name'].str.contains(hot_name, na=False)]
|
||
if not matches.empty:
|
||
for _, row in matches.iterrows():
|
||
hot_sectors_codes.append({
|
||
'ts_code': row['ts_code'],
|
||
'name': row['name']
|
||
})
|
||
|
||
print(f"✓ 找到 {len(hot_sectors_codes)} 个热门板块")
|
||
|
||
# 检查这些板块的资金异动
|
||
print("\n【第二步】检查板块资金异动(量比、额比、涨幅)...")
|
||
print("=" * 80)
|
||
|
||
today = datetime.now().strftime('%Y%m%d')
|
||
yesterday = (datetime.now() - timedelta(days=10)).strftime('%Y%m%d')
|
||
|
||
# 宽松模式的阈值
|
||
vol_threshold = 1.5
|
||
amount_threshold = 1.3
|
||
min_change = 0.5
|
||
|
||
qualified_sectors = []
|
||
|
||
for sector_info in hot_sectors_codes[:15]: # 只检查前15个
|
||
ts_code = sector_info['ts_code']
|
||
name = sector_info['name']
|
||
|
||
try:
|
||
daily_df = ts_client.pro.ths_daily(
|
||
ts_code=ts_code,
|
||
start_date=yesterday,
|
||
end_date=today
|
||
)
|
||
|
||
if daily_df.empty or len(daily_df) < 2:
|
||
print(f" ⚠️ {name}: 数据不足")
|
||
continue
|
||
|
||
daily_df = daily_df.sort_values('trade_date')
|
||
latest = daily_df.iloc[-1]
|
||
prev = daily_df.iloc[-2]
|
||
|
||
latest_vol = float(latest.get('vol', 0))
|
||
latest_avg_price = float(latest.get('avg_price', 0))
|
||
latest_amount = latest_vol * latest_avg_price * 100 # 估算成交额
|
||
|
||
prev_vol = float(prev.get('vol', 0))
|
||
prev_avg_price = float(prev.get('avg_price', 0))
|
||
prev_amount = prev_vol * prev_avg_price * 100
|
||
change_pct = float(latest.get('pct_change', 0))
|
||
|
||
# 计算量比和额比
|
||
vol_ratio = latest_vol / prev_vol if prev_vol > 0 else 0
|
||
amount_ratio = latest_amount / prev_amount if prev_amount > 0 else 0
|
||
|
||
# 判断是否符合条件
|
||
is_volume_surge = vol_ratio >= vol_threshold
|
||
is_amount_surge = amount_ratio >= amount_threshold
|
||
has_min_change = change_pct >= min_change
|
||
is_qualified = (is_volume_surge or is_amount_surge) and has_min_change
|
||
|
||
# 显示结果
|
||
status = "✅" if is_qualified else "❌"
|
||
vol_status = "🔥" if is_volume_surge else "📊"
|
||
amount_status = "🔥" if is_amount_surge else "📊"
|
||
change_status = "✓" if has_min_change else "✗"
|
||
|
||
print(f" {status} {name}")
|
||
print(f" 涨跌幅: {change_pct:+.2f}% {change_status}")
|
||
print(f" 量比: {vol_ratio:.2f}x {vol_status} (需要≥{vol_threshold})")
|
||
print(f" 额比: {amount_ratio:.2f}x {amount_status} (需要≥{amount_threshold})")
|
||
|
||
if is_qualified:
|
||
qualified_sectors.append({
|
||
'name': name,
|
||
'change_pct': change_pct,
|
||
'vol_ratio': vol_ratio,
|
||
'amount_ratio': amount_ratio
|
||
})
|
||
|
||
except Exception as e:
|
||
print(f" ❌ {name}: 查询失败 ({e})")
|
||
continue
|
||
|
||
print("\n" + "=" * 80)
|
||
print(f"【结果】找到 {len(qualified_sectors)} 个符合资金异动条件的板块")
|
||
|
||
if len(qualified_sectors) == 0:
|
||
print("\n⚠️ 没有板块符合条件,可能原因:")
|
||
print(" 1. 市场整体资金流入不足(量比、额比都未达标)")
|
||
print(" 2. 板块涨幅不够(需要≥0.5%)")
|
||
print(" 3. 阈值设置过高(当前:量比≥1.5,额比≥1.3)")
|
||
print("\n建议放宽阈值:")
|
||
print(" - 量比阈值: 1.5 → 1.2")
|
||
print(" - 额比阈值: 1.3 → 1.1")
|
||
print(" - 最小涨幅: 0.5% → 0.3%")
|
||
else:
|
||
print("\n✅ 符合条件的板块:")
|
||
for idx, sector in enumerate(qualified_sectors, 1):
|
||
print(f" {idx}. {sector['name']}: {sector['change_pct']:+.2f}%, "
|
||
f"量比{sector['vol_ratio']:.2f}x, 额比{sector['amount_ratio']:.2f}x")
|
||
|
||
print("=" * 80)
|
||
|
||
|
||
async def main():
|
||
await diagnose_sector_detection()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main())
|