大宗交易数据追踪系统:用Python挖掘折溢价信号与机构意图

大宗交易数据追踪系统:用Python挖掘折溢价信号与机构意图

大宗交易是A股市场大额股权转让的专用通道,每笔交易都透露着大资金的真实意图。但大部分散户对大宗交易的理解停留在"大股东在卖"的层面,忽略了其中丰富的信号。去年我搭建了一个大宗交易数据追踪系统,用Python从大单成交数据中挖掘折溢价信号和机构意图。这篇文章分享系统的核心设计和实现。

本地数据引擎提供了大单成交数据,路径是time/real/trace/bigdeal/{dm},包含了每笔大单的成交时间、价格、数量和方向。实时行情数据在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, timedelta

data_dir = "D:/ig50_data"

def read_bigdeal(dm):
    file_path = os.path.join(data_dir, "time", "real", "trace", "bigdeal", 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"])
    df["cje"] = df["cjjg"] * df["cjl"]
    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

字段方面,dm是股票代码,mc是股票名称,cjsj是成交时间,cjjg是成交价格,cjl是成交量,jyzd是交易方向(0中性/1买入/2卖出),cje是成交额。

系统的第一个分析模块是折溢价率计算。大宗交易的成交价通常偏离当日收盘价,折价说明买方要求补偿,溢价说明买方急于建仓。

def calc_premium_discount(dm):
    df_bigdeal = read_bigdeal(dm)
    if len(df_bigdeal) == 0:
        return None
    
    realtime = read_realtime(dm)
    close_price = realtime.get("cjjg", 0)
    
    if close_price == 0:
        return None
    
    results = []
    for _, row in df_bigdeal.iterrows():
        deal_price = row["cjjg"]
        discount = (deal_price - close_price) / close_price * 100
        
        results.append({
            "cjsj": row["cjsj"],
            "deal_price": deal_price,
            "close_price": close_price,
            "discount_pct": discount,
            "amount": row["cje"],
            "direction": row["jyzd"],
            "type": "溢价" if discount > 0 else "折价" if discount < -0.5 else "平价"
        })
    
    return pd.DataFrame(results)

def classify_bigdeal(dm):
    df = calc_premium_discount(dm)
    if df is None or len(df) == 0:
        return None
    
    total_amount = df["amount"].sum()
    avg_discount = df["discount_pct"].mean()
    
    has_premium = (df["discount_pct"] > 0).any()
    has_large_discount = (df["discount_pct"] < -10).any()
    
    if has_premium:
        signal = "强烈看多"
        score = 80
    elif avg_discount > -2:
        signal = "中性偏多"
        score = 55
    elif has_large_discount:
        signal = "看空"
        score = 25
    else:
        signal = "中性"
        score = 50
    
    return {
        "total_amount": total_amount,
        "avg_discount": avg_discount,
        "signal": signal,
        "score": score,
        "deal_count": len(df)
    }

第二个分析模块是大宗交易频率追踪。如果一只股票在短时间内出现多笔大宗交易,说明大额筹码在转移。

def analyze_bigdeal_frequency(dm, lookback_days=30):
    df_bigdeal = read_bigdeal(dm)
    if len(df_bigdeal) == 0:
        return None
    
    cutoff = datetime.now() - timedelta(days=lookback_days)
    recent = df_bigdeal[df_bigdeal["cjsj"] >= cutoff]
    
    if len(recent) == 0:
        return None
    
    daily_deals = recent.groupby(recent["cjsj"].dt.date).agg({
        "cje": "sum",
        "cjsj": "count"
    }).rename(columns={"cjsj": "deal_count"})
    
    consecutive_days = 0
    max_consecutive = 0
    dates = sorted(daily_deals.index)
    for i in range(len(dates) - 1):
        if (dates[i + 1] - dates[i]).days <= 3:
            consecutive_days += 1
            max_consecutive = max(max_consecutive, consecutive_days)
        else:
            consecutive_days = 0
    
    return {
        "total_deals": len(recent),
        "total_amount": recent["cje"].sum(),
        "avg_daily_deals": len(recent) / lookback_days,
        "max_consecutive_days": max_consecutive,
        "frequency_signal": "高频" if len(recent) > 5 else "正常"
    }

第三个分析模块是大宗交易后走势分析。统计大宗交易发生后股价的表现,验证信号的有效性。

def analyze_post_bigdeal_performance(dm, lookback_days=60):
    df_bigdeal = read_bigdeal(dm)
    df_kline = read_daily_kline(dm)
    
    if len(df_bigdeal) == 0 or len(df_kline) == 0:
        return None
    
    cutoff = datetime.now() - timedelta(days=lookback_days)
    recent_deals = df_bigdeal[df_bigdeal["cjsj"] >= cutoff]
    
    results = []
    for _, deal in recent_deals.iterrows():
        deal_date = deal["cjsj"]
        deal_price = deal["cjjg"]
        
        post_kline = df_kline[df_kline["cjsj"] > deal_date].head(5)
        if len(post_kline) < 5:
            continue
        
        price_5d = post_kline["cjjg"].iloc[-1]
        return_5d = (price_5d - deal_price) / deal_price * 100
        
        max_price = post_kline["cjjg"].max()
        min_price = post_kline["cjjg"].min()
        
        results.append({
            "deal_date": deal_date,
            "deal_price": deal_price,
            "price_5d": price_5d,
            "return_5d": return_5d,
            "max_return": (max_price - deal_price) / deal_price * 100,
            "min_return": (min_price - deal_price) / deal_price * 100
        })
    
    if not results:
        return None
    
    df_result = pd.DataFrame(results)
    return {
        "avg_return_5d": df_result["return_5d"].mean(),
        "win_rate": (df_result["return_5d"] > 0).mean() * 100,
        "avg_max_return": df_result["max_return"].mean(),
        "avg_min_return": df_result["min_return"].mean()
    }

第四个分析模块是大单方向汇总。通过jyzd字段判断大单是买入还是卖出,计算净买入金额。

def summarize_bigdeal_direction(dm):
    df = read_bigdeal(dm)
    if len(df) == 0:
        return None
    
    buy_amount = df[df["jyzd"] == 1]["cje"].sum()
    sell_amount = df[df["jyzd"] == 2]["cje"].sum()
    neutral_amount = df[df["jyzd"] == 0]["cje"].sum()
    
    net_flow = buy_amount - sell_amount
    total_amount = buy_amount + sell_amount + neutral_amount
    
    return {
        "buy_amount": buy_amount,
        "sell_amount": sell_amount,
        "net_flow": net_flow,
        "buy_ratio": buy_amount / total_amount if total_amount > 0 else 0,
        "sell_ratio": sell_amount / total_amount if total_amount > 0 else 0,
        "direction": "净买入" if net_flow > 0 else "净卖出"
    }

把这些模块整合起来,形成完整的大宗交易分析报告。

def generate_bigdeal_report(dm):
    classification = classify_bigdeal(dm)
    frequency = analyze_bigdeal_frequency(dm)
    performance = analyze_post_bigdeal_performance(dm)
    direction = summarize_bigdeal_direction(dm)
    
    report = f"大宗交易分析报告 - {dm}\n"
    
    if classification:
        report += f"折溢价信号: {classification['signal']} (评分: {classification['score']})\n"
        report += f"平均折溢价: {classification['avg_discount']:.2f}%\n"
        report += f"交易笔数: {classification['deal_count']}\n"
    
    if frequency:
        report += f"30日内交易频率: {frequency['total_deals']}笔\n"
        report += f"频率信号: {frequency['frequency_signal']}\n"
    
    if direction:
        report += f"大单方向: {direction['direction']}\n"
        report += f"净流入金额: {direction['net_flow']/10000:.1f}万\n"
    
    if performance:
        report += f"大宗后5日平均收益: {performance['avg_return_5d']:.2f}%\n"
        report += f"大宗后5日胜率: {performance['win_rate']:.1f}%\n"
    
    return report

实际运行下来,这个系统帮我筛选出了几只溢价成交的股票,后续表现确实不错。溢价成交是最强的看多信号——买方愿意以高于市价的价格买入大额筹码,说明他们非常看好。

在使用过程中有几点经验。第一,大宗交易的折价是正常的,因为买方要承担锁定期风险,折价5%以内不用太担心。第二,溢价成交是稀有信号,全市场一年也出现不了几次,一旦出现要重点关注。第三,连续多笔大宗交易是负面信号,说明有人在持续出货。

大宗交易数据是大资金意图的直接体现。用数据来追踪这些信号,比看消息面靠谱多了。

我用的数据来自本地数据引擎,大单成交数据接口完整,做大宗交易分析很方便。感兴趣的朋友可以参考这个思路来构建自己的追踪系统。


接口说明:

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

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

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

  4. base/gplist - 股票列表
    本地路径:数据存放目录/base/gplist
    用于获取全市场股票代码列表

资料参考:ig50

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值