3. 建仓成本核心算法:VWAP、TWAP 与成本区间估算

好,咱们直接进入正题。建仓成本分析,说白了就是回答一个问题:主力到底是在什么价位买的?

这个问题看着简单,但实际操作起来坑不少。我刚开始做量化那会儿,以为算个均价就完事了,结果回测怎么都对不上真实走势。后来才明白,不同场景要用不同的算法。

今天我把最常用的三种方法拆开讲:VWAPTWAP成本区间估算。每种方法我都会给出代码实现,并告诉你什么时候该用、什么时候别用。

3.1 成交量加权平均价格(VWAP)

VWAP 是机构交易中最常用的基准。它的逻辑很简单:用成交量做权重,算一个加权平均价。

公式长这样:

VWAP = Σ(价格 × 成交量) / Σ(成交量)

嗯,看着确实简单。但实际计算时有个细节——你得用逐笔成交数据,而不是分钟线或 tick 数据。为什么?因为逐笔数据能捕捉到每一笔真实的成交,而分钟线已经把细节抹平了。

来看代码实现:

import pandas as pd
import numpy as np

def calc_vwap(trade_data):
    """
    计算逐笔成交的 VWAP
    trade_data: DataFrame,必须包含 'price' 和 'volume' 列
    """
    # 计算每笔的成交额
    trade_data['turnover'] = trade_data['price'] * trade_data['volume']
    
    # 累计成交额和累计成交量
    cum_turnover = trade_data['turnover'].cumsum()
    cum_volume = trade_data['volume'].cumsum()
    
    # VWAP = 累计成交额 / 累计成交量
    vwap = cum_turnover / cum_volume
    
    return vwap

# 示例用法
df = pd.DataFrame({
    'price': [10.0, 10.1, 10.05, 10.2, 10.15],
    'volume': [100, 200, 150, 300, 250]
})
df['vwap'] = calc_vwap(df)
print(df)

关键点:VWAP 是累计值,不是瞬时值。每一笔的 VWAP 代表从开盘到当前时刻的加权平均成本。

我在项目中遇到过一个问题:有些行情数据会把大单拆成多笔小单,导致 VWAP 失真。解决办法是——先做大单合并,把同一时间戳、同一价格的连续成交合并成一笔。这个后面章节会细讲。

3.2 时间加权平均价格(TWAP)

TWAP 是另一种思路。它不考虑成交量,只考虑时间。说白了就是:把交易时段等分成 N 个区间,每个区间取一个价格,然后算平均。

公式:

TWAP = (P1 + P2 + ... + Pn) / n

其中 Pi 是第 i 个时间区间的价格(通常用收盘价或中间价)。

你可能会问:既然 VWAP 已经能算成本了,为什么还要 TWAP?

原因很简单——当成交量数据不可靠时。比如某些品种的逐笔成交数据缺失严重,或者交易所只提供分钟线。这时候 VWAP 算出来就是错的,TWAP 反而更稳定。

代码实现:

def calc_twap(trade_data, interval='1min'):
    """
    计算时间加权平均价格
    trade_data: DataFrame,必须包含 'price' 和 'time' 列
    interval: 时间区间,默认1分钟
    """
    # 按时间区间分组,取每个区间的收盘价
    twap_series = trade_data.resample(interval, on='time')['price'].last()
    
    # 去掉空值
    twap_series = twap_series.dropna()
    
    # 计算平均值
    twap = twap_series.mean()
    
    return twap

# 示例用法
df['time'] = pd.date_range('2024-01-01 09:30:00', periods=5, freq='1min')
twap_value = calc_twap(df)
print(f'TWAP: {twap_value:.4f}')

个人经验:TWAP 适合用在流动性差的品种上。比如某些小盘股,一天就成交几十笔,VWAP 算出来波动极大。这时候用 TWAP 反而能反映真实的市场成本。

3.3 成本区间估算

VWAP 和 TWAP 给的都是一个点。但主力的建仓成本往往是一个区间,而不是一个精确的数值。

为什么?因为主力不会在一个价位上把所有货都买完。他们会分批建仓,在不同价位上买入不同数量。所以我们需要估算一个成本区间,比如「主力成本在 10.2 到 10.8 之间」。

常用的方法有两种:

  1. 分位数法:取成交量的分位数,比如 20% 分位和 80% 分位对应的价格。
  2. 聚类法:用 K-Means 或 DBSCAN 把成交价格聚类,找出主要的成交价格带。

先看分位数法的实现:

def cost_interval_quantile(trade_data, lower=0.2, upper=0.8):
    """
    基于成交量分位数的成本区间估算
    trade_data: DataFrame,包含 'price' 和 'volume'
    lower: 下分位数,默认0.2
    upper: 上分位数,默认0.8
    """
    # 按价格排序
    sorted_data = trade_data.sort_values('price')
    
    # 计算累计成交量占比
    sorted_data['cum_vol_pct'] = sorted_data['volume'].cumsum() / sorted_data['volume'].sum()
    
    # 找到分位数对应的价格
    lower_price = sorted_data[sorted_data['cum_vol_pct'] >= lower]['price'].iloc[0]
    upper_price = sorted_data[sorted_data['cum_vol_pct'] >= upper]['price'].iloc[0]
    
    return lower_price, upper_price

# 示例
lower, upper = cost_interval_quantile(df)
print(f'成本区间: [{lower:.2f}, {upper:.2f}]')

聚类法稍微复杂一点,但效果更好。它能自动识别出多个成本密集区:

from sklearn.cluster import KMeans

def cost_interval_cluster(trade_data, n_clusters=3):
    """
    基于聚类的成本区间估算
    trade_data: DataFrame,包含 'price' 和 'volume'
    n_clusters: 聚类数量
    """
    # 准备数据:用价格和成交量作为特征
    X = trade_data[['price', 'volume']].values
    
    # K-Means 聚类
    kmeans = KMeans(n_clusters=n_clusters, random_state=42)
    trade_data['cluster'] = kmeans.fit_predict(X)
    
    # 计算每个聚类的加权平均价格
    clusters = []
    for i in range(n_clusters):
        cluster_data = trade_data[trade_data['cluster'] == i]
        vwap = (cluster_data['price'] * cluster_data['volume']).sum() / cluster_data['volume'].sum()
        clusters.append(vwap)
    
    # 返回排序后的聚类中心价格
    return sorted(clusters)

# 示例
clusters = cost_interval_cluster(df)
print(f'成本密集区: {[f"{c:.2f}" for c in clusters]}')

避坑指南:我曾经在分析一只庄股时,直接用分位数法算成本区间,结果发现区间特别窄。后来一查,原来是主力用对倒单制造了虚假成交量。所以记住——任何算法都要先做数据清洗,把对倒单、自成交这些垃圾数据去掉。

3.4 三种方法的对比与选择

我把这三种方法的特点整理成了一张表,方便你对照:

方法 核心逻辑 适用场景 局限性
VWAP 成交量加权 逐笔数据完整、流动性好 受大单影响大
TWAP 时间加权 数据缺失、流动性差 忽略成交量信息
成本区间 分位数/聚类 需要成本范围而非单点 参数选择影响结果

我个人习惯是:先用 VWAP 算基准,再用成本区间做验证。如果两者差距很大,说明数据可能有问题,或者市场结构发生了异常变化。

你想想看,如果 VWAP 是 10.5,但成本区间显示 80% 的成交量集中在 10.2-10.4,那说明什么?说明有大量成交在低价区,VWAP 被高价单拉高了。这时候我会更相信成本区间给出的结论。

3.5 知识体系总览

下面这张图把本章的核心逻辑串起来了。你可以看到三种方法之间的关系,以及在实际分析中如何组合使用:

建仓成本核心算法知识体系 逐笔成交数据 VWAP 成交量加权平均价格 Σ(P×V) / ΣV TWAP 时间加权平均价格 ΣP / n 成本区间估算 分位数法 / 聚类法 [P_low, P_high] 单点成本 精确到小数点后2位 单点成本 忽略成交量影响 成本区间 多个密集区 综合判断:VWAP + 成本区间交叉验证

这张图的核心思想是:不要依赖单一算法。VWAP 和 TWAP 给出的是「点」,成本区间给出的是「面」。把点和面结合起来,才能更准确地判断主力的真实建仓成本。

嗯,以上就是建仓成本核心算法的全部内容。代码可以直接拿去用,但记得根据你的数据格式做适当调整。下一章我们会聊如何把这些算法应用到实战中,识别主力的建仓痕迹。


公众号:蓝海资料掘金营,微信deep3321