4. 成交量加权平均价格算法(VWAP)

VWAP,全称是 Volume-Weighted Average Price。说白了,就是把你拆单的成交价格,用成交量做权重算个平均值。我刚开始做算法交易那会儿,觉得这东西不就是个均线吗?后来真上了生产环境才发现,VWAP 在机构交易里几乎是标配。

为什么?因为大资金进场,最怕的就是「吃相难看」。你一单砸下去,价格直接拉飞,成本全打水漂。VWAP 的核心思想就是:让我的成交价尽量贴近市场的全天均价。这样既完成了大额交易,又不至于被市场当成「猎物」盯上。

一句话总结:VWAP 策略的目标,就是让你的订单执行价格,尽可能接近当天市场的成交量加权平均价。

4.1 VWAP 原理

VWAP 的计算公式其实很简单:

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

嗯,就是每个成交价乘以对应的成交量,累加起来,再除以总成交量。这个值从开盘开始,随着每一笔交易动态更新。

举个例子:

时间 成交价 成交量 价格×成交量
09:30 10.00 1000 10000
09:31 10.02 2000 20040
09:32 10.01 1500 15015
累计 4500 45055

到 09:32 这一刻,VWAP = 45055 / 4500 ≈ 10.0122。你想想看,如果你在 09:32 之前买入,平均成本是 10.0122,那你的执行效果就算「跟上了 VWAP」。

我个人习惯把 VWAP 理解成「市场的公平价格线」。它不像收盘价那样受尾盘操纵影响,也不像开盘价那样容易被跳空干扰。它是一整天所有参与者用真金白银投票出来的结果。

4.2 VWAP 实现

实现 VWAP 策略,核心就两步:

  1. 预测全天的成交量分布 —— 你得知道什么时候该多下点单,什么时候该歇一歇。
  2. 按比例拆分订单 —— 把大单切成小单,按照预测的成交量曲线逐步喂给市场。

下面是一个简化版的 Python 实现。我当年在回测系统里就是这么写的:

import pandas as pd
import numpy as np

class VWAPExecutor:
    def __init__(self, total_shares, start_time, end_time):
        self.total_shares = total_shares
        self.start_time = start_time
        self.end_time = end_time
        self.executed_shares = 0
        self.executed_value = 0.0
        
    def get_volume_profile(self, minute_bars):
        """
        根据历史分钟线,预测今天的成交量分布
        """
        # 计算每分钟成交量占全天比例
        total_volume = minute_bars['volume'].sum()
        minute_bars['volume_ratio'] = minute_bars['volume'] / total_volume
        return minute_bars
        
    def get_target_shares(self, current_minute, volume_profile):
        """
        当前分钟应该下单多少股
        """
        ratio = volume_profile.loc[current_minute, 'volume_ratio']
        target = self.total_shares * ratio
        return int(target)
        
    def execute(self, market_data):
        """
        主执行逻辑
        """
        volume_profile = self.get_volume_profile(market_data)
        
        for minute, row in market_data.iterrows():
            target = self.get_target_shares(minute, volume_profile)
            
            # 实际成交逻辑(这里简化了)
            fill_price = row['close']
            fill_shares = min(target, market_data.loc[minute, 'volume'])
            
            self.executed_shares += fill_shares
            self.executed_value += fill_price * fill_shares
            
            # 检查是否完成
            if self.executed_shares >= self.total_shares:
                break
                
        # 计算实际 VWAP
        actual_vwap = self.executed_value / self.executed_shares
        return actual_vwap

我的经验:实际生产中,成交量预测不能只靠历史均值。我曾经踩过一个坑——某天突然出财报,成交量是平时的 5 倍,历史模型完全失效。后来我加了一个「实时修正因子」,用过去 5 分钟的成交量动态调整剩余时间的分配比例。效果好了很多。

4.3 VWAP 优缺点

任何策略都不是万能的。VWAP 也一样,有它的甜区,也有它的盲区。

优点

  • 执行成本可控:你的成交价天然贴近市场均价,不容易被「割韭菜」。
  • 市场冲击小:把大单拆成小单,按时间均匀释放,不会把价格打飞。
  • 评价标准清晰:VWAP 本身就是一个 benchmark。你跑赢了 VWAP,说明执行做得好。
  • 适合被动型策略:如果你不急着抢单,只想低调完成交易,VWAP 很合适。

缺点

  • 对成交量预测依赖大:预测不准,你的拆分比例就全歪了。
  • 无法应对极端行情:比如闪崩、熔断,VWAP 策略会「傻傻地」继续下单。
  • 不适合抢单策略:如果你需要快速建仓或者逃顶,VWAP 太慢了。
  • 日内波动大时效果差:价格上蹿下跳,VWAP 只能保证平均,不能保证最优。

避坑指南:我曾经在 2015 年股灾期间跑 VWAP 策略,结果因为流动性枯竭,小单根本成交不了。后来我加了一个「流动性检测模块」,如果当前盘口深度不足,就暂停下单,等流动性恢复再继续。这个改动救了我好几次。

4.4 VWAP 适用场景

VWAP 不是万能药,但它有几个非常明确的适用场景:

  • 指数基金调仓:比如某 ETF 要调整成分股,基金经理需要买入/卖出大量股票。用 VWAP 可以平滑执行,避免冲击成本。
  • 机构大单交易:保险、养老金这类资金,单笔交易动辄几千万。VWAP 是他们的首选。
  • 算法交易基准:很多券商的算法交易系统,默认就是以 VWAP 为基准来评价执行效果。
  • 日内做市商:做市商需要频繁买卖,VWAP 可以帮助他们控制库存风险。

你想想看,如果一个散户用 VWAP 策略去买 100 股茅台,那纯属杀鸡用牛刀。但如果你要买 10 万股,嗯,VWAP 就是你的好朋友。

4.5 VWAP 核心逻辑图

下面这张图,是我当年做内部培训时画的。它把 VWAP 的整个流程串起来了:

VWAP 大单拆分策略核心流程 大单指令(总股数) 步骤1:获取历史分钟线成交量数据 步骤2:预测全天成交量分布曲线 步骤3:按比例拆分大单为小单 输出:实际成交 VWAP 关键点 成交量预测 是核心难点 实时修正 避免过拟合 流动性检测 评价标准 实际 VWAP 与市场 VWAP 偏差越小越好

这张图把 VWAP 的执行流程讲得很清楚了。从大单指令进来,到最终输出实际成交 VWAP,中间每一步都有讲究。我个人觉得,最关键的还是第二步——成交量预测。预测准了,后面都是水到渠成的事。


好了,VWAP 的基本原理、实现、优缺点和适用场景,咱们就聊到这儿。下一章我会讲 TWAP(时间加权平均价格算法),它和 VWAP 是「亲兄弟」,但思路完全不同。到时候咱们再细聊。

一句话记住 VWAP:让大单像水滴一样融入市场,不惊起一丝波澜。

专注资料整理