板块联动效应量化分析:用Python构建龙头跟涨套利系统
板块联动效应量化分析:用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股市场最可靠的规律之一。用数据来量化联动强度,用系统来捕捉跟涨机会,比手动盯盘高效得多。
我用的数据来自本地数据引擎,行业资金流向和实时行情数据接口完整。感兴趣的朋友可以参考这个思路来构建自己的板块联动系统。
接口说明:
-
all/zjlx/zjhhy - 行业资金流向
本地路径:数据存放目录/all/zjlx/zjhhy
包含各行业的资金流入流出汇总数据 -
base/gplist - 股票列表
本地路径:数据存放目录/base/gplist
主要字段:股票代码(dm)、股票名称(mc)、行业信息 -
time/real/{股票代码} - 实时行情
本地路径:数据存放目录/time/real/{dm}
主要字段:成交价格(cjjg)、成交量(cjl)、涨跌幅(zf) -
time/history/trade/{股票代码}/day - 日线历史K线
本地路径:数据存放目录/time/history/trade/{dm}/day
主要字段:成交时间(cjsj)、成交价格(cjjg)、涨跌幅(zf)
资料参考:ig50
更多推荐
所有评论(0)