2. VWAP计算公式详解:从成交量到价格的加权平均逻辑
VWAP,全称是Volume-Weighted Average Price。
翻译过来就是「成交量加权平均价格」。
很多人以为它就是个简单的均价。其实不是。它背后藏着成交量的分布逻辑。我个人习惯把VWAP看作「市场真实成交的共识价格」。为什么这么说?你想想看,普通均价只关心价格,不关心这笔交易到底有多少人参与。而VWAP把成交量拉进来,谁交易得多,谁就对价格更有话语权。
2.1 标准VWAP公式:一笔一笔算
公式其实不复杂。但理解它背后的含义,比背公式重要一百倍。
VWAP = Σ (价格_i × 成交量_i) / Σ 成交量_i
这里面的逻辑是:
- 每一笔成交,都贡献一个「价格 × 成交量」的乘积
- 把所有乘积加起来,再除以总成交量
- 结果就是VWAP
说白了,这就是一个加权平均。权重就是成交量。
核心理解:成交量大的价格点,对VWAP的影响更大。如果某笔交易量特别大,它会把VWAP往那个价格方向拉。
我在项目中遇到过一件事。有一次做回测,我发现策略在尾盘突然偏离VWAP很多。排查了半天,发现是某笔大宗交易把VWAP拉偏了。嗯,这里要注意:大宗交易如果被纳入计算,VWAP会失真。所以很多机构会把大宗交易单独处理。
2.2 累计VWAP:从开盘算到现在
实际交易中,我们很少只算一笔交易的VWAP。更多时候,我们算的是「从开盘到当前时刻」的累计VWAP。
公式变成这样:
累计VWAP = (累计价格×成交量之和) / (累计成交量)
举个例子:
| 时间 | 价格 | 成交量 | 价格×成交量 | 累计VWAP |
|---|---|---|---|---|
| 09:30 | 100.0 | 1000 | 100,000 | 100.00 |
| 09:31 | 100.5 | 2000 | 201,000 | 100.33 |
| 09:32 | 99.8 | 1500 | 149,700 | 100.11 |
| 09:33 | 101.0 | 500 | 50,500 | 100.18 |
你看,第三笔价格跌了,但因为成交量不大,VWAP只从100.33降到100.11。第四笔价格涨到101,但成交量只有500,VWAP只涨到100.18。这就是成交量的「话语权」。
实战技巧:我建议你在盘中实时计算累计VWAP时,用滚动窗口。比如每5分钟更新一次。这样既能捕捉趋势,又不会因为单笔异常数据而剧烈波动。
2.3 为什么成交量是「权重」?
这个问题我问过很多新人。大部分人的回答是:「因为公式里就是这么写的。」
嗯,这个回答没错,但不够深。
成交量作为权重,背后有一个核心假设:成交量大的价格,更能代表市场的真实供需。
你想想看,如果某只股票在100元只成交了1手,在99元成交了10000手。哪个价格更可信?显然是99元。因为大量资金在那个位置达成了共识。
避坑指南:我曾经犯过一个错误——直接用分钟线的收盘价和成交量算VWAP。结果发现和Tick级数据算出来的VWAP差了0.3%。原因很简单:分钟线内的价格波动被平滑掉了。如果你做高频交易,一定要用逐笔成交数据。如果是日内交易,分钟线勉强能用,但精度会打折扣。
2.4 VWAP的变体:你可能会遇到的
实际工作中,VWAP不是只有一种。我整理了几种常见的变体:
- 日内VWAP:从开盘到当前时刻,最常用
- 滚动VWAP:取最近N笔或N分钟的窗口,适合捕捉短期趋势
- 预期VWAP:用历史成交量分布预测未来VWAP,用于算法交易下单
- 行业VWAP:把同行业多只股票的VWAP加权平均,用于板块分析
我个人最常用的是日内VWAP和滚动VWAP。前者用来判断当前价格是否偏离市场共识,后者用来做短线交易的进出场参考。
2.5 一张图看懂VWAP计算逻辑
下面这张SVG图,把VWAP的计算流程画出来了。从原始数据到最终结果,每一步都很清楚。
2.6 代码实现:Python版
理论说完了,上代码。这是我平时用的一个简单实现:
def calculate_vwap(trades):
"""
计算VWAP
trades: list of dict, 每笔包含 price 和 volume
"""
total_pv = 0.0
total_vol = 0.0
for trade in trades:
total_pv += trade['price'] * trade['volume']
total_vol += trade['volume']
if total_vol == 0:
return 0.0
return total_pv / total_vol
# 增量更新版本
class VWAPCalculator:
def __init__(self):
self.cum_pv = 0.0
self.cum_vol = 0.0
def update(self, price, volume):
self.cum_pv += price * volume
self.cum_vol += volume
def get_vwap(self):
if self.cum_vol == 0:
return 0.0
return self.cum_pv / self.cum_vol
这个增量更新的版本,我建议你直接用在实盘里。每来一笔数据,就调用一次update。不用每次都从头算,效率高很多。
关键点:VWAP不是预测指标,是描述性指标。它告诉你「市场到目前为止的共识价格在哪里」。别用它来预测未来价格走势,那是另一套逻辑。
好了,VWAP的计算逻辑就这些。公式本身不复杂,但背后的加权思想值得反复琢磨。你想想看,同样的价格,成交量不同,意义完全不同。这就是VWAP的精髓。