当前位置:首页>python>量化投资实战:用 Python 复刻「主力资金监控」指标,捕捉个股起爆点!

量化投资实战:用 Python 复刻「主力资金监控」指标,捕捉个股起爆点!

  • 2026-09-10 22:34:20
量化投资实战:用 Python 复刻「主力资金监控」指标,捕捉个股起爆点!
引言:为什么要监控主力资金?

在 A 股市场中,散户往往处于信息劣势地位,而主力资金的动向往往是股价变动的先行指标。如果能提前发现主力资金的介入迹象,就能在起涨前布局,获得超额收益。

今天,我们将把一个经典的通达信主力监控指标改写成 Python 版本,实现自动化监控和可视化,让你用代码「看见」主力的踪迹!

🎯 核心代码:技术指标的 Python 实现

以下是完整的指标计算代码,无需安装 TA-Lib,纯 Python 实现:

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport matplotlib.dates as mdatesfrom get_stock_data import df# 设置中文字体plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falsedef EMA(series, period):    """自定义指数移动平均函数"""    return series.ewm(span=period, adjust=False).mean()def calculate_indicators(df):    """    计算所有技术指标(不依赖 talib)    """    # M5: 收盘价    M5 = df['close']    # M6: 数据总数(从首日到当前的计数)    M6 = np.arange(len(df)) + 1    # M7: 成交量加权平均价 (VWAP)    M7 = (df['amount'] * df['close']).cumsum() / df['amount'].cumsum()    # M8: 全周期均线(动态窗口均值)    M8 = df['close'].expanding().mean()    # M12: 单日涨幅超过2%    M12 = df['close'] / df['close'].shift(1) > 1.02    # M13: 单日跌幅超过2%    M13 = df['close'] / df['close'].shift(1) < 0.98    # M14: 近期波动幅度小于5%(横盘特征)    HHV_M5 = df['close'].expanding().max()    LLV_M5 = df['close'].expanding().min()    M14 = (HHV_M5 - LLV_M5) / df['close'] < 0.05    # M15: 成交额的30日指数移动平均    M15 = EMA(df['amount'], 30)    # M16: 成交量相对强度大于95%(放量特征)    LLV_M15 = M15.expanding().min()    HHV_M15 = M15.expanding().max()    M16 = (M15 - LLV_M15) / (HHV_M15 - LLV_M15) > 0.95    # M17: 当日大涨或大跌    M17 = M12 | M13    # M18: 主力关注条件——横盘+放量+VWAP上穿全周期均线    M18 = (~M17) & M14 & M16 & (M7 > M8) & (M7.shift(1) <= M8.shift(1))    # M19: 强势起爆条件——收盘价同时上穿VWAP和全周期均线    cross_close_M7 = (df['close'] > M7) & (df['close'].shift(1) <= M7.shift(1))    cross_close_M8 = (df['close'] > M8) & (df['close'].shift(1) <= M8.shift(1))    M19 = (~M17) & M14 & M16 & cross_close_M7 & cross_close_M8    # AL指标:快慢均线差值动量    EMA8 = EMA(df['close'], 8)    EMA55 = EMA(df['close'], 55)    AL = (EMA8 - EMA55) * 10    # TRK指标:双平滑均线    EMA13_1 = EMA(df['close'], 13)    TRK = EMA(EMA13_1, 13)    # MTQ指标:双均线变化率    MTQ = (TRK - TRK.shift(1)) / TRK.shift(1) * 1000    # 大资金介入判定条件组    VX1 = (df['close'] - M7) / M7 < -0.005      # 价格低于VWAP    VX2 = (df['close'] - M7) / M7 < -0.03       # 明显偏离VWAP    VX3 = (MTQ > MTQ.shift(1)) & (MTQ < -0.2)   # MTQ反弹但仍处低位    EMA_AL_3 = EMA(AL, 3)    VX4 = (AL > EMA_AL_3) & (AL < -0.3)         # AL指标超卖反弹    # 综合判定:大资金介入信号    VX5 = VX1 & VX3 & VX4    VX6 = VX2 & VX3 & VX4    大资金介入 = VX5 & VX6    return {        'M5': M5, 'M6': M6, 'M7': M7, 'M8': M8,        'M12': M12, 'M13': M13, 'M14': M14,        'M15': M15, 'M16': M16, 'M17': M17,        'M18': M18, 'M19': M19, 'AL': AL,        'TRK': TRK, 'MTQ': MTQ,         'VX1': VX1, 'VX2': VX2, 'VX3': VX3, 'VX4': VX4,        '大资金介入': 大资金介入    }

📈 信号生成与数据封装

def generate_signals(df):    """    整合指标并生成交易信号表    """    df_copy = df.copy()    # 智能日期处理:兼容索引/列/序号三种模式    if hasattr(df_copy.index, 'strftime'):        dates = df_copy.index    elif 'date' in df_copy.columns:        try:            dates = pd.to_datetime(df_copy['date'])        except:            dates = pd.Series(range(len(df_copy)))    else:        dates = pd.Series(range(len(df_copy)))    indicators = calculate_indicators(df_copy)    results = pd.DataFrame({        'date': dates,        'close': df_copy['close'],        'open': df_copy['open'],        'high': df_copy['high'],        'low': df_copy['low'],        'amount': df_copy['amount']    })    # 批量添加指标列    for key, value in indicators.items():        results[key] = value    # 涨停板标记(对应通达信 STICKLINE)    results['涨停'] = ((df_copy['close'] - df_copy['close'].shift(1)) /                       df_copy['close'].shift(1) * 100 > 9.5)    return results

🎨 专业可视化:让信号一目了然

def visualize_results(signals, stock_code="sz002075"):    """    三图合一可视化:价格走势 + 成交量 + 指标曲线    """    fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 10), sharex=True)    dates = signals['date']    # --- 图1:价格与均线体系 ---    ax1.plot(dates, signals['close'], label='收盘价', linewidth=1, color='black')    ax1.plot(dates, signals['M7'], label='VWAP均价', linewidth=1, color='blue', linestyle='--')    ax1.plot(dates, signals['M8'], label='全周期均线', linewidth=1, color='red', linestyle='--')    # 动态标记各类信号点    if signals['M18'].any():        m18_mask = signals['M18'].fillna(False)        ax1.scatter(dates[m18_mask], signals.loc[m18_mask, 'close'],                    color='yellow', s=50, label='主力关注', marker='^', zorder=5)    if signals['M19'].any():        m19_mask = signals['M19'].fillna(False)        ax1.scatter(dates[m19_mask], signals.loc[m19_mask, 'close'] * 0.99,                    color='red', s=80, label='强势起爆', marker='*', zorder=5)    if signals['大资金介入'].any():        big_money_mask = signals['大资金介入'].fillna(False)        ax1.scatter(dates[big_money_mask], signals.loc[big_money_mask, 'low'] * 0.985,                    color='purple', s=60, label='大资金介入', marker='v', zorder=5)    ax1.set_title(f'{stock_code} - 主力资金监控分析', fontsize=14)    ax1.set_ylabel('价格')    ax1.legend(loc='upper left')    ax1.grid(True, alpha=0.3)    # --- 图2:成交量分析 ---    ax2.bar(dates, signals['amount'], label='成交额', alpha=0.7, color='gray')    ax2.plot(dates, signals['M15'], label='成交额EMA', color='orange', linewidth=2)    ax2.set_ylabel('成交额')    ax2.legend(loc='upper left')    ax2.grid(True, alpha=0.3)    # --- 图3:趋势指标 ---    ax3.plot(dates, signals['AL'], label='AL(均线差值动量)', color='green', linewidth=1)    ax3.plot(dates, signals['MTQ'], label='MTQ(双均线变化率)', color='blue', linewidth=1)    ax3.axhline(-0.3, color='red', linestyle='--', alpha=0.5, label='超卖阈值')    ax3.set_ylabel('指标数值')    ax3.set_xlabel('交易日期')    ax3.legend(loc='upper left')    ax3.grid(True, alpha=0.3)    # 日期刻度优化    if pd.api.types.is_datetime64_any_dtype(dates):        ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))        ax1.xaxis.set_major_locator(mdates.DayLocator(interval=5))    plt.xticks(rotation=45)    plt.tight_layout()    return fig

📋 结果解读与统计输出

def print_detailed_results(signals):    """    结构化输出信号明细与统计    """    print("="*60)    print("🔍 主力资金信号分析报告")    print("="*60)    signal_cols = ['M18', 'M19', '大资金介入']    has_signals = signals[signal_cols].any(axis=1)    if has_signals.any():        signal_days = signals[has_signals].copy()        # 智能日期格式化        if pd.api.types.is_datetime64_any_dtype(signal_days['date']):            signal_days['date_str'] = signal_days['date'].dt.strftime('%Y-%m-%d')        else:            signal_days['date_str'] = signal_days['date'].astype(str)        print(f"\n📅 发现信号天数: {len(signal_days)}")        print("-"*45)        for _, row in signal_days.iterrows():            date_str = row['date_str']            tags = []            if row['M18']: tags.append('🟡主力关注')            if row['M19']: tags.append('🔴强势起爆')            if row['大资金介入']: tags.append('💜大资金介入')            print(f"{date_str}: {' | '.join(tags)} —— 收盘价:{row['close']:.2f}")    else:        print("\n❌ 本期未检测到有效信号")    print(f"\n📊 信号汇总统计:")    print(f"  • 主力关注信号: {signals['M18'].sum():>2d} 次")    print(f"  • 强势起爆信号: {signals['M19'].sum():>2d} 次")    print(f"  • 大资金介入信号: {signals['大资金介入'].sum():>2d} 次")

🚦 主程序入口

if __name__ == "__main__":    # 🛠️ 执行指标计算    signals = generate_signals(df)    print("✅ 指标计算完成!")    print(f"📁 分析周期: {len(signals)} 个交易日")    # 📊 输出详细报告    print_detailed_results(signals)    # 🖼️ 可视化展示    try:        fig = visualize_results(signals, "sz002075")        plt.savefig('./主力监控分析.png', dpi=300, bbox_inches='tight')        plt.show()    except Exception as e:        print(f"⚠️ 绘图异常: {e}")        print("📄 原始数据预览:")        cols_to_show = ['date', 'close', 'M18', 'M19', '大资金介入']        print(signals[cols_to_show].tail(10))

📝 策略逻辑解析

🔑 核心思想

这套指标体系的本质是捕捉「横盘吸筹 + 资金异动 + 关键突破」的三重共振:

  1. M14 横盘过滤:排除大幅波动的噪音期,锁定蓄势阶段

  2. M16 量能确认:通过成交量相对强度识别主力动作

  3. 价格与均线关系:VWAP 与全周期均线的交叉作为趋势确认

🎯 三类信号含义

  • 🟡 主力关注:满足基本条件,主力开始活跃但尚未拉升

  • 🔴 强势起爆:价格同时突破双重均线,启动概率较高

  • 💜 大资金介入:结合动量指标的超跌反弹确认,适合左侧布局

最新文章

随机文章