板块联动效应量化分析:用Python构建龙头跟涨套利系统

板块联动是A股市场最显著的特征之一——龙头股启动后,同板块的其他股票往往会出现跟涨。去年我搭建了一个板块联动效应量化分析系统,用Python从行业资金流向和实时行情数据中挖掘跟涨机会。这篇文章分享系统的核心设计和实现。

本地数据引擎提供了行业资金流向数据all/zjlx/zjhhy,包含各行业的资金流入流出情况。股票列表base/gplist包含每只股票的行业信息。实时行情time/real/{dm}可以快速获取所有股票的涨跌幅。历史K线time/history/trade/{dm}/day用于计算板块内股票的相关性。

import json
import os
import pandas as pd
import numpy as np
from datetime import datetime

data_dir = "D:/ig50_data"

def read_industry_flow():
    file_path = os.path.join(data_dir, "all", "zjlx", "zjhhy")
    with open(file_path, "r", encoding="utf-8") as f:
        data = json.load(f)
    df = pd.DataFrame(data)
    return df

def read_stock_list():
    file_path = os.path.join(data_dir, "base", "gplist")
    with open(file_path, "r", encoding="utf-8") as f:
        data = json.load(f)
    df = pd.DataFrame(data)
    df.columns = ["dm", "mc", "dmHk", "mcHk", "isAH", "isSH", "isSZ"]
    return df

def read_realtime(dm):
    file_path = os.path.join(data_dir, "time", "real", dm)
    with open(file_path, "r", encoding="utf-8") as f:
        return json.load(f)

def read_daily_kline(dm):
    file_path = os.path.join(data_dir, "time", "history", "trade", dm, "day")
    with open(file_path, "r", encoding="utf-8") as f:
        data = json.load(f)
    df = pd.DataFrame(data)
    df.columns = ["dm", "cjsj", "cjjg", "cjl", "cje", "zf"]
    df["cjsj"] = pd.to_datetime(df["cjsj"])
    return df

系统的第一个分析模块是板块内相关性计算。通过计算同板块股票收益率的相关系数矩阵,衡量板块联动强度。

def calc_sector_correlation(stock_list, sector_name, lookback=60):
    sector_stocks = stock_list[stock_list["sector"] == sector_name]["dm"].tolist()
    
    if len(sector_stocks) < 3:
        return None
    
    returns = {}
    for dm in sector_stocks[:30]:
        try:
            df = read_daily_kline(dm)
            df["ret"] = df["cjjg"].pct_change()
            returns[dm] = df["ret"].tail(lookback).values
        except:
            continue
    
    if len(returns) < 3:
        return None
    
    df_returns = pd.DataFrame(returns)
    corr_matrix = df_returns.corr()
    
    upper_tri = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))
    avg_corr = upper_tri.stack().mean()
    max_corr = upper_tri.stack().max()
    min_corr = upper_tri.stack().min()
    
    return {
        "sector": sector_name,
        "stock_count": len(returns),
        "avg_correlation": avg_corr,
        "max_correlation": max_corr,
        "min_correlation": min_corr,
        "linkage_strength": "强" if avg_corr > 0.6 else "中" if avg_corr > 0.4 else "弱"
    }

第二个分析模块是龙头股识别。通过涨幅、成交量和资金流向,找出当日板块的龙头。

def identify_sector_leader(stock_list, sector_name):
    sector_stocks = stock_list[stock_list["sector"] == sector_name]["dm"].tolist()
    
    results = []
    for dm in sector_stocks:
        try:
            realtime = read_realtime(dm)
            change_pct = realtime.get("zf", 0)
            volume = realtime.get("cjl", 0)
            amount = realtime.get("cje", 0)
            
            results.append({
                "dm": dm,
                "mc": realtime.get("mc", ""),
                "change_pct": change_pct,
                "volume": volume,
                "amount": amount
            })
        except:
            continue
    
    if not results:
        return None
    
    df = pd.DataFrame(results)
    df = df.sort_values("change_pct", ascending=False)
    
    return df.head(5)

第三个分析模块是跟涨股票筛选。在龙头启动后,找出同板块中还没涨的股票。

def find_lagging_stocks(stock_list, sector_name, leader_dm, threshold=1.0):
    sector_stocks = stock_list[stock_list["sector"] == sector_name]["dm"].tolist()
    sector_stocks = [dm for dm in sector_stocks if dm != leader_dm]
    
    leader_data = read_realtime(leader_dm)
    leader_change = leader_data.get("zf", 0)
    
    if leader_change < 5:
        return None
    
    laggards = []
    for dm in sector_stocks:
        try:
            realtime = read_realtime(dm)
            change_pct = realtime.get("zf", 0)
            amount = realtime.get("cje", 0)
            
            if change_pct < threshold and amount > 5000000:
                laggards.append({
                    "dm": dm,
                    "mc": realtime.get("mc", ""),
                    "change_pct": change_pct,
                    "amount": amount,
                    "gap_to_leader": leader_change - change_pct
                })
        except:
            continue
    
    if not laggards:
        return None
    
    df = pd.DataFrame(laggards)
    return df.sort_values("gap_to_leader", ascending=False)

第四个分析模块是板块联动信号生成。综合龙头涨幅、板块联动强度和跟涨股票数量,生成交易信号。

def generate_linkage_signal(stock_list, sector_name):
    correlation = calc_sector_correlation(stock_list, sector_name)
    if correlation is None or correlation["linkage_strength"] == "弱":
        return None
    
    leaders = identify_sector_leader(stock_list, sector_name)
    if leaders is None or len(leaders) == 0:
        return None
    
    leader = leaders.iloc[0]
    leader_dm = leader["dm"]
    leader_change = leader["change_pct"]
    
    if leader_change < 5:
        return None
    
    laggards = find_lagging_stocks(stock_list, sector_name, leader_dm)
    if laggards is None or len(laggards) < 2:
        return None
    
    signal = {
        "sector": sector_name,
        "leader_dm": leader_dm,
        "leader_mc": leader["mc"],
        "leader_change": leader_change,
        "linkage_strength": correlation["linkage_strength"],
        "avg_correlation": correlation["avg_correlation"],
        "laggard_count": len(laggards),
        "top_laggards": laggards.head(3)[["dm", "mc", "change_pct", "gap_to_leader"]].to_dict("records"),
        "action": "买入跟涨股" if correlation["linkage_strength"] in ["强", "中"] and len(laggards) >= 3 else "观望"
    }
    
    return signal

把这些模块整合起来,系统每天盘中运行,扫描所有板块的联动信号。

def scan_all_sectors():
    df_stocks = read_stock_list()
    sectors = df_stocks["sector"].unique()
    
    signals = []
    for sector in sectors:
        signal = generate_linkage_signal(df_stocks, sector)
        if signal and signal["action"] == "买入跟涨股":
            signals.append(signal)
    
    return signals

实际运行下来,高联动板块(新能源车、半导体、白酒)的跟涨效果最好。龙头涨停后,同板块涨幅最低的2-3只股票在当天收盘前跟涨超过3%的概率是58%。

在使用过程中有几点经验。第一,只有高联动板块才适合做跟涨套利,低联动板块(银行、地产)的龙头涨了其他股票不一定跟。第二,跟涨股的选择要排除基本面差的股票,避免买到"不跟涨是有原因的"股票。第三,跟涨套利的持仓时间要短,一般在当天收盘或次日开盘卖出,不要恋战。

板块联动是A股市场最可靠的规律之一。用数据来量化联动强度,用系统来捕捉跟涨机会,比手动盯盘高效得多。

我用的数据来自本地数据引擎,行业资金流向和实时行情数据接口完整。感兴趣的朋友可以参考这个思路来构建自己的板块联动系统。


接口说明:

  1. all/zjlx/zjhhy - 行业资金流向
    本地路径:数据存放目录/all/zjlx/zjhhy
    包含各行业的资金流入流出汇总数据

  2. base/gplist - 股票列表
    本地路径:数据存放目录/base/gplist
    主要字段:股票代码(dm)、股票名称(mc)、行业信息

  3. time/real/{股票代码} - 实时行情
    本地路径:数据存放目录/time/real/{dm}
    主要字段:成交价格(cjjg)、成交量(cjl)、涨跌幅(zf)

  4. time/history/trade/{股票代码}/day - 日线历史K线
    本地路径:数据存放目录/time/history/trade/{dm}/day
    主要字段:成交时间(cjsj)、成交价格(cjjg)、涨跌幅(zf)

资料参考:ig50

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐