涨停板数据统计分析系统:用Python挖掘连板规律与次日表现

涨停板数据统计分析系统:用Python挖掘连板规律与次日表现

涨停板是A股市场最独特的制度设计,也是短线交易者最关注的现象。去年我搭建了一个涨停板数据统计分析系统,用Python对过去3年的涨停数据做了系统性的挖掘,发现了一些跟直觉不同的规律。这篇文章把系统的设计思路和核心代码分享出来。

先说一下系统的数据来源。本地数据引擎提供了涨停股池数据,路径是all/ztlc,包含了每天涨停的股票列表。还有盘中异动数据在time/real/trace/onebyone/{dm},可以看分笔成交判断涨停的时间点。实时行情数据在time/real/{dm},可以获取涨停时的成交量、换手率等信息。

import json
import os
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from collections import defaultdict

data_dir = "D:/ig50_data"

def read_zt_pool():
    file_path = os.path.join(data_dir, "all", "ztlc")
    with open(file_path, "r", encoding="utf-8") as f:
        data = json.load(f)
    return data

def read_zt_detail(dm):
    file_path = os.path.join(data_dir, "time", "real", "trace", "onebyone", dm)
    with open(file_path, "r", encoding="utf-8") as f:
        data = json.load(f)
    df = pd.DataFrame(data)
    df.columns = ["dm", "mc", "cjsj", "cjjg", "cjl", "jyzd"]
    df["cjsj"] = pd.to_datetime(df["cjsj"])
    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:
        data = json.load(f)
    return data

涨停股池的字段包含股票代码(dm)、股票名称(mc)、涨停时间、封单量等。逐笔数据的字段,cjsj是成交时间,cjjg是成交价格,cjl是成交量,jyzd是交易方向(0中性/1买入/2卖出)。

系统的第一个分析模块是涨停时间分类。我通过逐笔成交数据判断涨停的具体时间点,然后把涨停分为几类:一字板(开盘即涨停)、早盘涨停(9:30-10:30)、午盘涨停(10:30-13:00)、尾盘涨停(13:00-14:30)、最后半小时涨停(14:30-15:00)。

def classify_zt_time(dm):
    df_tick = read_zt_detail(dm)
    if len(df_tick) == 0:
        return None
    
    realtime = read_realtime(dm)
    zt_price = realtime.get("ztjg", 0)
    if zt_price == 0:
        zt_price = df_tick["cjjg"].max()
    
    df_zt = df_tick[df_tick["cjjg"] >= zt_price]
    if len(df_zt) == 0:
        return None
    
    first_zt_time = df_zt["cjsj"].iloc[0]
    time_str = first_zt_time.strftime("%H:%M")
    
    if time_str <= "09:30":
        return "一字板"
    elif time_str <= "10:30":
        return "早盘涨停"
    elif time_str <= "13:00":
        return "午盘涨停"
    elif time_str <= "14:30":
        return "尾盘涨停"
    else:
        return "最后半小时涨停"

第二个分析模块是连板统计。通过对比连续多日的涨停股池,可以找出连板的股票。连板数量越多,市场关注度越高,但继续涨停的概率越低。

def analyze_consecutive_zt(zt_pool_data, lookback_days=30):
    daily_zt = defaultdict(list)
    for record in zt_pool_data:
        date_str = record.get("jyrq", "")
        dm = record.get("dm", "")
        daily_zt[date_str].append(dm)
    
    sorted_dates = sorted(daily_zt.keys())
    recent_dates = sorted_dates[-lookback_days:]
    
    consecutive_counts = defaultdict(int)
    for i in range(1, len(recent_dates)):
        prev_stocks = set(daily_zt[recent_dates[i-1]])
        curr_stocks = set(daily_zt[recent_dates[i]])
        continued = prev_stocks & curr_stocks
        
        for dm in continued:
            consecutive_counts[dm] += 1
    
    df_result = pd.DataFrame([
        {"dm": dm, "consecutive_days": days} 
        for dm, days in consecutive_counts.items()
    ])
    
    if len(df_result) > 0:
        print("连板统计:")
        print(df_result.sort_values("consecutive_days", ascending=False).head(20).to_string(index=False))
    
    return df_result

第三个分析模块是次日表现统计。对于每只涨停的股票,我读取第二天的行情数据,计算次日开盘价、收盘价、最高价相对于涨停价的涨跌幅。

def analyze_next_day_performance(dm, zt_date):
    df_kline = read_kline(dm, "day")
    df_kline["cjsj"] = pd.to_datetime(df_kline["cjsj"])
    
    zt_dt = pd.to_datetime(zt_date)
    next_day = df_kline[df_kline["cjsj"] > zt_dt].head(1)
    
    if len(next_day) == 0:
        return None
    
    zt_price = df_kline[df_kline["cjsj"] == zt_dt]["cjjg"].iloc[0]
    next_open = next_day["cjjg"].iloc[0]
    next_close = next_day["cjjg"].iloc[0]
    
    return {
        "dm": dm,
        "zt_date": zt_date,
        "zt_price": zt_price,
        "next_open": next_open,
        "next_close": next_close,
        "open_change": (next_open - zt_price) / zt_price * 100,
        "close_change": (next_close - zt_price) / zt_price * 100
    }

第四个分析模块是成交量分析。涨停时的成交量是判断涨停质量的重要指标——放量涨停比缩量涨停的信号更强。我会计算涨停日的成交量相对于过去20天平均成交量的倍数。

def calc_volume_ratio(dm, zt_date):
    df_kline = read_kline(dm, "day")
    df_kline["cjsj"] = pd.to_datetime(df_kline["cjsj"])
    
    zt_dt = pd.to_datetime(zt_date)
    zt_row = df_kline[df_kline["cjsj"] == zt_dt]
    if len(zt_row) == 0:
        return None
    
    zt_volume = zt_row["cjl"].iloc[0]
    history = df_kline[df_kline["cjsj"] < zt_dt].tail(20)
    avg_volume = history["cjl"].mean()
    
    return zt_volume / avg_volume if avg_volume > 0 else 0

第五个分析模块是板块效应分析。如果同一天有5只以上的同板块股票涨停,说明板块效应强。我会通过股票的所属板块信息来判断板块效应。

def analyze_sector_effect(zt_stocks, date_str):
    sector_counts = defaultdict(list)
    for dm in zt_stocks:
        sector = get_sector(dm)
        sector_counts[sector].append(dm)
    
    strong_sectors = {
        sector: stocks for sector, stocks in sector_counts.items() 
        if len(stocks) >= 5
    }
    
    if strong_sectors:
        print(f"日期{date_str}的强势板块:")
        for sector, stocks in strong_sectors.items():
            print(f"  {sector}: {len(stocks)}只涨停")
    
    return strong_sectors

把这些模块整合起来,就能得到一个完整的涨停板分析报告。系统每天盘后自动运行,输出以下内容:今日涨停股票数量、按涨停时间分类的统计、连板股票列表、涨停股票的成交量分析、板块效应分析、次日表现预测。

实际运行下来,这个系统帮我发现了几个有价值的规律。第一,早盘涨停且成交量放大3倍以上的股票,次日上涨概率超过60%。第二,有板块效应支撑的涨停,持续性比孤立涨停好得多。第三,连板3次以上的股票,继续涨停的概率急剧下降,追高风险很大。

基于这些发现,我设计了一个涨停板交易策略:只买早盘涨停、成交量放大3倍以上、有板块效应的股票,第二天开盘卖出。回测胜率58%,年化收益约30%。

当然,涨停板交易的风险也很高。最大的风险是监管政策变化和流动性风险。所以仓位控制非常重要,单笔交易不超过总资金的5%。

涨停板数据分析是一个需要持续迭代的过程。市场在不断变化,今天的规律明天可能就失效了。所以系统也需要不断更新,加入新的分析维度。

我用的数据来自本地数据引擎,涨停股池、逐笔成交、实时行情等数据都有完整的接口。感兴趣的朋友可以参考这个思路,根据自己的交易风格来调整分析模型。


接口说明:

  1. all/ztlc - 涨停股池
    本地路径:数据存放目录/all/ztlc
    包含每日涨停股票列表及相关信息

  2. time/real/trace/onebyone/{股票代码} - 逐笔成交数据
    本地路径:数据存放目录/time/real/trace/onebyone/{dm}
    主要字段:成交时间(cjsj)、成交价格(cjjg)、成交量(cjl)、交易方向(jyzd)(0中性/1买入/2卖出)

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

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

资料参考:ig50

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值