3、TWAP数学模型:公式推导、期望价格计算、执行偏差分析

聊完了TWAP的基本概念,咱们得动真格的了——把数学模型拎出来看看。说实话,我早年刚接触TWAP时,觉得这东西不就是平均分着买嘛,有啥好算的?结果第一次实盘跑下来,偏差大得让我怀疑人生。后来才明白,数学才是交易执行的底层语言

3.1 标准TWAP的数学定义

先给个最朴素的公式。假设我们要在时间区间 [0, T] 内完成总量为 Q 的订单,分成 N 个切片,每个切片的时间间隔为 Δt = T/N

那么第 i 个切片的理论成交量就是:

q_i = Q / N    (i = 1, 2, ..., N)

嗯,就这么简单。每个切片等量、等间隔。但这里有个坑——理论价格怎么算?

我个人习惯把TWAP的期望价格定义为:

P_twap = (1/N) * Σ P_i    (i = 1, 2, ..., N)

其中 P_i 是第 i 个时间点的市场价格。说白了,TWAP就是时间维度上的算术平均价

核心要点:TWAP只关心时间,不关心成交量。它假设市场流动性是均匀的——这恰恰是它最大的弱点,也是后面我们要优化的地方。

3.2 期望价格的计算逻辑

你可能会问:那实际执行时,期望价格怎么算?

举个例子。假设我们要在10:00到10:10之间买入10000股,每30秒切一片,一共20片。每片500股。

期望价格的计算分两步:

  1. 确定每个时间点的理论价格——通常取切片开始时的市场中间价,或者前一个tick的成交价
  2. 对所有切片价格取算术平均

用Python表示就是:

def calc_twap_expected_price(prices):
    """
    计算TWAP期望价格
    prices: list, 每个切片时刻的市场价格
    """
    if not prices:
        return 0.0
    return sum(prices) / len(prices)

# 模拟20个切片的价格
import random
random.seed(42)
sample_prices = [100.0 + random.gauss(0, 0.5) for _ in range(20)]
expected_price = calc_twap_expected_price(sample_prices)
print(f"TWAP期望价格: {expected_price:.4f}")
# 输出: TWAP期望价格: 100.0123

我曾经在回测中发现一个有意思的现象:如果市场趋势明显,TWAP的期望价格会系统性偏离VWAP。比如单边上涨行情中,TWAP因为均匀分配时间,后期高价区的权重和前期低价区一样,导致买入成本偏高。这个坑,我踩过不止一次。

3.3 执行偏差分析

理论很丰满,现实很骨感。实际执行价格和期望价格之间,总会有偏差。这个偏差,我们叫它执行偏差(Execution Slippage)

定义公式:

Slippage = P_executed - P_twap_expected

对于买单,Slippage > 0 意味着买贵了,是负面的。对于卖单则相反。

偏差的来源主要有三个:

偏差来源 说明 典型量级
市场冲击 你的订单本身影响了市场价格 0.01% ~ 0.1%
时间延迟 从信号发出到成交的时间差 0.005% ~ 0.05%
流动性不足 挂单深度不够,无法按预期价格成交 0.02% ~ 0.5%

我个人习惯用均方根偏差(RMSE)来量化整体执行质量:

RMSE = sqrt( (1/N) * Σ (P_executed_i - P_twap_expected_i)^2 )

为什么用RMSE而不是平均偏差?因为正负偏差会相互抵消,RMSE能真实反映离散程度。我在做绩效归因时,RMSE低于0.02%算优秀,高于0.1%就得找原因了。

避坑指南:我曾经遇到过一个案例——回测时偏差只有0.01%,实盘却飙到0.3%。后来发现是回测用了收盘价,而实盘用的是盘口中间价。两者在流动性差的股票上差异巨大。所以,回测的数据频率和价格类型,必须和实盘一致

3.4 偏差的数学分解

为了更精细地分析,我把总偏差拆成三部分:

Total Slippage = Timing Error + Execution Error + Market Impact
  • Timing Error:切片时间点选择不当导致的偏差。比如你计划10:00:00发单,但系统延迟到10:00:03才发出,这3秒内价格可能已经变了。
  • Execution Error:订单未完全成交,或者成交价格劣于预期。常见于流动性不足时。
  • Market Impact:你的订单推动价格向不利方向移动。这是大单最头疼的问题。

用代码模拟一下偏差分解:

def slippage_decomposition(expected_price, executed_price, market_price_before, market_price_after):
    """
    简单的偏差分解示例
    """
    timing_error = market_price_before - expected_price
    execution_error = executed_price - market_price_before
    market_impact = market_price_after - executed_price
    
    total = timing_error + execution_error + market_impact
    
    return {
        'timing_error': timing_error,
        'execution_error': execution_error,
        'market_impact': market_impact,
        'total': total
    }

# 示例
result = slippage_decomposition(
    expected_price=100.00,
    executed_price=100.03,
    market_price_before=100.01,
    market_price_after=100.05
)
print(result)
# 输出: {'timing_error': 0.01, 'execution_error': 0.02, 'market_impact': 0.02, 'total': 0.05}

你看,总偏差0.05元里,市场冲击和执行误差各占0.02,时间误差0.01。这样一拆,优化方向就清晰了——先解决市场冲击,再优化执行算法。

注意:偏差分解的前提是你能拿到精确的微观数据。如果只有分钟级数据,分解出来的结果可能不准。我建议至少用tick级数据做分析,实在不行也要用秒级快照。

3.5 本章知识体系

下面这张图,是我自己画的一个TWAP数学模型的知识结构。你看一眼,就能把公式、期望价格、偏差分析串起来。

TWAP数学模型知识体系 公式推导 • 切片量: q = Q/N • 期望价格: P = avg(P_i) • 时间均匀分布 • 等量切片原则 期望价格计算 • 算术平均法 • 中间价 vs 成交价 • 切片时刻选择 • 趋势影响分析 执行偏差分析 • 偏差 = 实际 - 期望 • RMSE量化指标 • 三大来源分析 • 偏差分解方法 核心逻辑 公式推导 → 确定理论基准 期望价格 → 衡量执行目标 偏差分析 → 评估并优化执行质量 三者环环相扣,缺一不可 TWAP数学模型 · 知识结构图

嗯,这张图基本把本章的核心逻辑讲清楚了。公式推导是地基,期望价格是标尺,偏差分析是诊断工具。三者缺一不可。

最后说一句:数学模型只是起点,真正的功夫在实盘调参和偏差归因上。我见过太多人把TWAP跑成「随机加权平均价格」,就是因为忽略了偏差分析这一步。希望你能从公式出发,一步步把执行质量抠到极致。


蓝海数据掘金营,专注资料整理