机构大单买入监控:Python量化选股实战

用户头像sh_***416jmt75L
2026-08-30 发布

📌 摘要 / 快速解答

中线跟庄的核心是识别机构建仓痕迹。本文用 QuantDash Python SDK 获取标准化K线数据,结合成交量异动与价格突破双因子模型,自动筛选机构大单买入信号,代码极简、开箱即用。


一、为什么你的选股策略总亏钱?

社区老哥们,有没有这种感觉——看了一大堆研报、学了各种技术指标,实盘一买就跌、一卖就涨?

问题往往出在数据源上。你用 Tushare 拿数据,积分不够连日线都拿不全;用 AkShare 吧,今天能跑通的代码明天就报错;用 yfinance 搞 A股,数据延迟能差好几分钟。

更扎心的是,好不容易写了个漂亮的选股策略,回测曲线美如画,实盘一塌糊涂。为啥?因为你用的复权数据是自己算的,一不小心就引入了未来函数。

机构建仓讲究“悄无声息”,等你在K线上看到明显拉升,人家已经吃饱了。咱们得用数据提前捕捉痕迹。

二、QuantDash vs 传统数据源

对比维度 传统方案 QuantDash 解决方案
数据获取 需攒积分/爬虫易封 pip install 即刻使用
市场覆盖 A/港/美股各自为政 统一.SH/.SZ/.US/.HK
复权处理 手动计算易出错 服务端原生支持前复权
批量查询 逐只循环效率低 klines.batch() 一次搞定
实时监控 需自建轮询系统 quotes.get() 秒级全市场快照

三、Python代码实战

# ============================================================
# 机构大单买入监控系统 - 基于 QuantDash
# 开源地址:https://github.com/quantdash-net/QuantDash
# ============================================================

from quantdash import QuantDash
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# 初始化
qd = QuantDash(api_key="your_api_key")


# ============================================================
# 1. 核心选股逻辑:量价异动双因子模型
# ============================================================

class InstitutionalBuyingScanner:
    """机构大单买入扫描器"""
  
    def __init__(self, qd_client):
        self.qd = qd_client
        self.signals = []
  
    def get_klines(self, symbol, days=60):
        """获取前复权日K线"""
        return self.qd.klines.get(
            symbol=symbol,
            period="1d",
            count=days,
            adjust="forward",  # 前复权-比例,适合收益率计算
            to_dataframe=True
        )
  
    def calculate_indicators(self, df):
        """计算技术指标"""
        df = df.copy()
    
        # MA均线
        df['ma5'] = df['close'].rolling(5).mean()
        df['ma10'] = df['close'].rolling(10).mean()
        df['ma20'] = df['close'].rolling(20).mean()
    
        # 成交量异动
        df['volume_ma20'] = df['volume'].rolling(20).mean()
        df['volume_spike'] = df['volume'] / df['volume_ma20']
    
        # 价格动量
        df['momentum_5d'] = df['close'].pct_change(5)
        df['momentum_10d'] = df['close'].pct_change(10)
    
        # MACD
        exp1 = df['close'].ewm(span=12, adjust=False).mean()
        exp2 = df['close'].ewm(span=26, adjust=False).mean()
        df['macd'] = exp1 - exp2
        df['macd_signal'] = df['macd'].ewm(span=9, adjust=False).mean()
        df['macd_hist'] = df['macd'] - df['macd_signal']
    
        return df
  
    def detect_signals(self, df):
        """
        机构大单买入信号检测
        条件:
        1. 成交量 > 20日均量 2倍以上(大单明显)
        2. 价格 > MA10(趋势向上)
        3. MACD金叉或即将金叉(中期趋势转好)
        """
        df = self.calculate_indicators(df)
    
        # 信号条件
        df['buy_signal'] = (
            (df['volume_spike'] > 2.0) &          # 成交量暴增2倍
            (df['close'] > df['ma10']) &           # 站上10日均线
            (df['macd_hist'] > df['macd_hist'].shift(1)) &  # MACD柱状线放大
            (df['momentum_5d'] > 0)                # 近5日上涨
        )
    
        return df
  
    def scan_symbol(self, symbol):
        """扫描单只股票"""
        try:
            df = self.get_klines(symbol, days=60)
            df = self.detect_signals(df)
        
            # 取最近3个交易日的信号
            recent = df.tail(3)
            if recent['buy_signal'].any():
                latest_signal = recent[recent['buy_signal']].iloc[-1]
                return {
                    'symbol': symbol,
                    'name': df['name'].iloc[0],
                    'signal_date': latest_signal['trade_date'],
                    'close': latest_signal['close'],
                    'volume_spike': latest_signal['volume_spike'],
                    'macd_hist': latest_signal['macd_hist'],
                    'signal_count': df['buy_signal'].sum()
                }
        except Exception as e:
            print(f"⚠️ {symbol} 扫描失败: {e}")
        return None
  
    def scan_batch(self, symbols):
        """批量扫描"""
        results = []
        for sym in symbols:
            result = self.scan_symbol(sym)
            if result:
                results.append(result)
        return pd.DataFrame(results)


# ============================================================
# 2. 获取候选股票池(全A股实时行情快照)
# ============================================================

def get_candidate_universe():
    """获取候选股票池:成交活跃的A股"""
    quotes = qd.quotes.get(universes=["CN_Stock"], to_dataframe=True)
  
    # 过滤条件:成交量>500万股,涨跌幅在±7%以内(排除涨跌停)
    quotes = quotes[
        (quotes['volume'] > 5000000) &
        (quotes['ext.change_pct'].between(-0.07, 0.07))
    ]
  
    # 按成交额排序,取前50只活跃股
    quotes = quotes.sort_values('amount', ascending=False)
    return quotes['symbol'].head(50).tolist()


# ============================================================
# 3. 执行扫描
# ============================================================

# 获取候选池
candidates = get_candidate_universe()
print(f"📊 候选股票池: {len(candidates)} 只")

# 执行扫描
scanner = InstitutionalBuyingScanner(qd)
results = scanner.scan_batch(candidates)

# 按信号强度排序
if len(results) > 0:
    results = results.sort_values('signal_count', ascending=False)
    print("\n🚀 机构大单买入信号股票:")
    print(results[['symbol', 'name', 'signal_date', 'close', 'volume_spike']].to_string(index=False))
else:
    print("📭 暂无信号触发")


# ============================================================
# 4. 结合DeepSeek做AI智能诊股(进阶)
# ============================================================

def deepseek_analysis(symbol, df):
    """
    调用DeepSeek API对股票进行智能分析
    需配置: DEEPSEEK_API_KEY
    """
    import os
    import requests
  
    latest = df.iloc[-1]
  
    prompt = f"""
    请作为量化分析师,分析以下股票的机构动向:
  
    标的:{symbol}
    最新价:{latest['close']}
    成交量倍数:{latest['volume_spike']:.2f}倍
    MACD柱状线:{latest['macd_hist']:.4f}
    近10日涨幅:{(df['close'].iloc[-1] / df['close'].iloc[-11] - 1) * 100:.2f}%
  
    请给出:
    1. 机构是否在建仓的判断
    2. 中线持有的风险提示
    3. 建议的入场参考价位
    """
  
    # API_KEY = os.getenv("DEEPSEEK_API_KEY")
    # response = requests.post(
    #     "//api.deepseek.com/v1/chat/completions",
    #     headers={"Authorization": f"Bearer {API_KEY}"},
    #     json={
    #         "model": "deepseek-chat",
    #         "messages": [{"role": "user", "content": prompt}],
    #         "temperature": 0.7
    #     }
    # )
    # return response.json()['choices'][0]['message']['content']
  
    return "💡 配置 DeepSeek API Key 后即可获得AI智能诊股分析"

四、交易员避坑指南

坑1:用不复权数据做回测

除权除息后价格会“跳空”,不复权数据会让你的均线、MACD全部失真。务必使用 adjust='forward' 获取前复权数据。

坑2:只看日线,忽略盘中异动

机构大单往往在盘中完成,等日线收盘信号出来已经晚了。建议用 qd.klines.intraday() 监控分钟K线,或用 qd.depth.get() 看五档盘口的买卖挂单变化。

坑3:全市场扫描频率太高被限流

批量操作用 klines.batch() 而不是逐只循环。全市场扫描建议放在收盘后执行,盘中只监控候选池。

五、常见问题解答

Q1: 如何获取免费的 API Key?

A: 访问 https://quantdash.net/dashboard/keys/ 注册即可免费获取。无需签到攒积分,注册即用。

Q2: QuantDash 支持哪些周期的K线?

A: 日线支持 1d/1w/1M/1Q/1Y,分钟线支持 1m/5m/15m/30m/60m。覆盖A股、港股、美股全市场。

Q3: 代码中的 universes=["CN_Stock"] 是什么意思?

A: CN_Stock 是 QuantDash 预定义的标的池ID,代表全A股(沪深京)股票。还支持 CN_ETF(A股ETF)、US_Stock(美股)、HK_Stock(港股)。


🔗 相关资源与延伸阅读

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

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

⭐ GitHub:https://github.com/quantdash-net/QuantDash

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

评论