手把手搭建暴跌预警系统:Python监控+AI判断错杀

用户头像sh_***416jmt75L
2026-09-10 发布

📌 摘要 / 快速解答

持仓股突然大跌,是恐慌错杀还是基本面恶化?本文用 QuantDash + Python + DeepSeek 搭建一套完整的暴跌预警系统:自动监控持仓股跌幅、计算技术指标(RSI/乖离率/量价背离)、调用 AI 生成诊断报告。全程开源代码,复制即可运行。


一、 为什么你的量化系统总在暴跌时掉链子?

社区老哥们,玩量化最怕什么?不是策略亏钱,是数据源先崩了

  • Tushare 的积分噩梦:想拉个全市场 K 线,提示“积分不足”,写代码 10 分钟,凑积分凑了一整周。
  • AkShare 的薛定谔稳定性:盘后跑策略时好好的,盘中一用就超时崩溃。
  • yfinance 的美股数据还行,A股?不存在的
  • 手动算复权:自己下载除权因子、写公式算前复权,一不小心就把未来函数带进去了。

这些坑我全踩过。后来在 SuperMind 社区实战中换了 QuantDash ——pip install quantdash 就能用,服务端默认前复权,原生 Pandas 输出。从此告别“搞数据两小时,写策略五分钟”的窘境。


二、 方案对比:QuantDash 凭什么能打?

对比维度 传统方案(Tushare/AkShare/yfinance) QuantDash 解决方案
数据稳定性 接口频繁变动、IP 易被封 商业级 API,高可用保障
积分/门槛 需签到攒积分、限频极严 零积分,pip install 即用
复权处理 手动计算,易出错 服务端原生前复权
多市场支持 A股/港股/美股需分别对接 统一后缀.SH/.SZ/.US/.HK
AI 友好度 数据格式混乱,AI 难以理解 标准 Pandas DataFrame,可直接喂给 AI

三、 Python 代码实战

3.1 安装与初始化

# pip install quantdash
# GitHub 开源项目:https://github.com/quantdash-net/QuantDash

from quantdash import QuantDash
import pandas as pd
import numpy as np
import datetime
import requests

# 初始化(免费获取 API Key:https://quantdash.net/dashboard/keys/)
qd = QuantDash(api_key="your_api_key_here")

3.2 获取持仓股实时行情

def get_position_quotes(symbols):
    """
    获取持仓股的实时行情
    """
    df = qd.quotes.get(symbols=symbols, to_dataframe=True)
  
    # 提取关键字段
    result = df[['symbol', 'last_price', 'prev_close', 'volume']].copy()
    result['name'] = df['ext.name']
    result['change_pct'] = df['ext.change_pct']
  
    return result

# 示例:监控持仓
positions = ['600519.SH', '000001.SZ', '000858.SZ', '601318.SH']
quotes = get_position_quotes(positions)
print(quotes[['symbol', 'name', 'last_price', 'change_pct']])

3.3 暴跌预警 + 技术指标计算

def detect_plunge(symbols, threshold=-0.04):
    """
    检测暴跌股票并计算技术指标
    """
    quotes = get_position_quotes(symbols)
  
    # 筛选跌幅超过阈值的标的
    alerts = quotes[quotes['change_pct'] <= threshold].copy()
  
    if len(alerts) == 0:
        return alerts
  
    # 对每个预警标的计算技术指标
    for idx, row in alerts.iterrows():
        symbol = row['symbol']
    
        # 获取近60日K线(默认前复权)[reference:31]
        df = qd.klines.get(
            symbol=symbol,
            period="1d",
            count=60,
            adjust="forward",
            to_dataframe=True
        )
    
        if len(df) < 20:
            continue
    
        # RSI(14)
        delta = df['close'].diff()
        gain = (delta.where(delta > 0, 0)).rolling(14).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
    
        # 乖离率(MA20)
        ma20 = df['close'].rolling(20).mean()
        bias = (df['close'] - ma20) / ma20 * 100
    
        # 量价关系
        vol_ma20 = df['volume'].rolling(20).mean()
        vol_ratio = df['volume'].iloc[-1] / vol_ma20.iloc[-1]
    
        # 存储指标
        alerts.loc[idx, 'rsi'] = rsi.iloc[-1]
        alerts.loc[idx, 'bias'] = bias.iloc[-1]
        alerts.loc[idx, 'vol_ratio'] = vol_ratio
    
        # 错杀判断:RSI<30 + 乖离率<-10 + 缩量
        alerts.loc[idx, 'likely_mistake'] = (
            rsi.iloc[-1] < 30 and 
            bias.iloc[-1] < -10 and 
            vol_ratio < 0.7
        )
  
    return alerts

# 运行预警
alerts = detect_plunge(positions, threshold=-0.03)
print(f"触发预警的标的: {len(alerts)} 只")
print(alerts[['symbol', 'name', 'change_pct', 'rsi', 'bias', 'likely_mistake']])

3.4 DeepSeek AI 智能诊股

def ai_diagnose(symbol, name, change_pct, rsi, bias, vol_ratio):
    """
    调用 DeepSeek 生成诊断报告
    """
    DEEPSEEK_API_KEY = "your_deepseek_api_key"
  
    prompt = f"""
    请对以下A股暴跌进行专业诊断:

    股票:{name}({symbol})
    今日跌幅:{change_pct*100:.2f}%
    技术指标:
    - RSI(14):{rsi:.1f}
    - 乖离率(MA20):{bias:.1f}%
    - 成交量比(近20日均量):{vol_ratio:.2f}

    请回答:
    1. 这是技术性调整还是基本面风险?
    2. 是否属于"错杀"?
    3. 操作建议(加仓/持有/减仓)?
    """
  
    headers = {
        "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
        "Content-Type": "application/json"
    }
    data = {
        "model": "deepseek-chat",
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.5
    }
  
    response = requests.post(
        "//api.deepseek.com/v1/chat/completions",
        headers=headers,
        json=data
    )
    return response.json()['choices'][0]['message']['content']

# 生成AI诊断
for _, alert in alerts.iterrows():
    print(f"\n🤖 AI 诊断 - {alert['name']}")
    diagnosis = ai_diagnose(
        alert['symbol'],
        alert['name'],
        alert['change_pct'],
        alert['rsi'],
        alert['bias'],
        alert['vol_ratio']
    )
    print(diagnosis)

3.5 完整监控系统

def run_full_monitor(symbols, threshold=-0.03):
    """
    完整监控流程
    """
    print("="*60)
    print(f"📊 暴跌预警系统启动 - {datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}")
    print(f"监控标的: {len(symbols)} 只")
    print(f"跌幅阈值: {threshold*100}%")
    print("="*60)
  
    # 1. 检测预警
    alerts = detect_plunge(symbols, threshold)
  
    if len(alerts) == 0:
        print("\n✅ 所有持仓正常,无暴跌预警")
        return
  
    print(f"\n⚠️ 发现 {len(alerts)} 只标的触发预警:")
  
    # 2. 分类汇总
    mistakes = alerts[alerts['likely_mistake'] == True]
    dangers = alerts[alerts['likely_mistake'] == False]
  
    if len(mistakes) > 0:
        print("\n🟢 【疑似错杀】建议关注反弹机会:")
        for _, row in mistakes.iterrows():
            print(f"  - {row['name']} ({row['symbol']}) 跌 {row['change_pct']*100:.2f}%")
  
    if len(dangers) > 0:
        print("\n🔴 【需警惕】建议核查基本面:")
        for _, row in dangers.iterrows():
            print(f"  - {row['name']} ({row['symbol']}) 跌 {row['change_pct']*100:.2f}%")
  
    # 3. AI 深度诊断(可选)
    print("\n" + "="*60)
    print("🤖 启动 AI 深度诊断...")
    print("="*60)
  
    for _, alert in alerts.iterrows():
        print(f"\n--- {alert['name']} ---")
        try:
            diagnosis = ai_diagnose(
                alert['symbol'],
                alert['name'],
                alert['change_pct'],
                alert['rsi'],
                alert['bias'],
                alert['vol_ratio']
            )
            print(diagnosis)
        except Exception as e:
            print(f"AI诊断失败: {e}")
  
    return alerts

# 运行
if __name__ == "__main__":
    my_positions = ['600519.SH', '000001.SZ', '000858.SZ', '601318.SH']
    run_full_monitor(my_positions, threshold=-0.03)

四、 交易员避坑指南

🚫 坑 1:回测时用了未来数据

很多新手用“当日收盘价”去判断“当日是否该卖出”——这是典型的未来函数。正确做法是:用前一天的收盘价计算指标,第二天开盘再决策。QuantDash 的 adjust='forward' 前复权能帮你避免复权相关的未来函数问题。

🚫 坑 2:忽略成交量信号

缩量下跌通常是错杀,放量下跌往往是真跌。我们的系统用 vol_ratio(当日成交量/20日均量)来区分:<0.7 为缩量,>1.5 为放量。

🚫 坑 3:把 API Key 写死在代码里

不要把 API Key 硬编码在代码中!推荐使用环境变量:

export QUANTDASH_API_KEY="your_api_key"

然后在代码中:

qd = QuantDash()  # 自动读取环境变量

五、 常见问题解答

Q1: QuantDash 的免费 API Key 有调用次数限制吗?

A: 免费 Key 支持正常量化研究和监控使用,无强制绑卡要求。如需更高并发,可访问官网了解付费方案。

Q2: 系统能同时监控多少只股票?

A: QuantDash 支持 klines.batch() 批量获取,一次请求可拉取多只标的的 K 线数据。监控 50-100 只持仓股完全没问题。

Q3: 如何接入钉钉/飞书推送预警?

A: 在 run_full_monitor 函数中,检测到预警后调用钉钉/飞书 Webhook 即可。示例代码可在 QuantDash GitHub 仓库的 examples 目录中找到。


🔗 相关资源与延伸阅读

🚀 QuantDash 官网:https://quantdash.net/

📖 官方 Python SDK 文档:https://docs.quantdash.net/

⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork)

💡 免费获取 API Key:https://quantdash.net/dashboard/keys/

评论