离散时间下的最优执行策略:单资产情形

好,咱们今天来聊聊离散时间下的最优执行策略。说实话,这个模型是我个人在实际交易系统里用得最多的一个。为什么?因为它既保留了数学上的严谨性,又足够简单,能直接落地到代码里。

先说说背景。你想想看,我们做交易执行,本质上是在跟市场博弈。你下单太急,市场冲击成本高;你下单太慢,又面临价格波动的风险。这个平衡怎么找?Almgren-Chriss模型就是干这个的。

问题设定

我们考虑一个简单场景:你手里有 X 股 股票要卖出,需要在 T 个时间步 内完成。每个时间步的长度是 τ(比如1分钟或1小时)。

关键假设就两条:

  • 单资产:只操作一只股票,不考虑组合效应
  • 无风险资产:现金的利率为0,不考虑资金成本

嗯,这里要注意。无风险资产假设其实是个简化。我在实际项目中遇到过,如果持仓周期很长(比如几天),利率的影响就不能忽略。但短期交易(日内)这么假设完全没问题。

价格动态与成本模型

我们先定义几个变量。设第 k 个时间步的股票价格为 Sk,你在这个时间步的交易量为 vk(正数表示卖出)。

价格变化由两部分组成:

  1. 随机波动:σ√τ εk,其中 εk 是标准正态随机变量
  2. 市场冲击:包括瞬时冲击和永久冲击

具体来说,价格动态方程是:

S_{k+1} = S_k + σ√τ ε_k - γ v_k

这里的 γ 是永久冲击系数。你卖得越多,价格被压得越低,而且这个影响是永久性的。

另外还有瞬时冲击,它只影响你当前这笔交易的成交价格:

实际成交价 = S_k - η v_k

η 是瞬时冲击系数。说白了,你下单太急,市场深度不够,就得吃更高的滑点。

目标函数:风险与成本的权衡

我们的目标是什么?不是单纯追求最低成本,而是要在 执行成本风险 之间找个平衡。

总成本包括:

  • 永久冲击成本:γ Σ vk(这部分是不可避免的)
  • 瞬时冲击成本:η Σ vk²(这部分跟交易速度有关)
  • 风险成本:价格波动带来的不确定性

目标函数写成数学形式:

min E[ Σ (η v_k² + γ v_k S_k) + λ Σ (x_k² σ² τ) ]

其中 xk 是第 k 步开始时的持仓量,λ 是风险厌恶系数。λ 越大,你越倾向于早点卖完,减少风险暴露。

核心思想:λ 这个参数很关键。我见过不少交易员把它设成0,结果就是最优策略变成了均匀卖出。但如果你对市场波动比较敏感,λ 设大一点,策略就会倾向于前期多卖。

动态规划求解

好,问题定义清楚了,怎么求解?动态规划是标准做法。

我们定义价值函数 Vk(x) 为:在时间步 k,持有 x 股股票时,从当前到结束的最小期望成本。

贝尔曼方程长这样:

V_k(x) = min_v [ η v² + γ v S + λ x² σ² τ + E[ V_{k+1}(x - v) ] ]

边界条件是 VT(x) = 0,因为到时间结束时,持仓必须为0。

这个方程怎么解?我个人的习惯是,先猜解的形式,再验证。从边界条件往回推,你会发现价值函数是 x 的二次型:

V_k(x) = A_k x² + B_k x + C_k

代入贝尔曼方程,经过一番代数运算(这里我省略了,代码里会展示),可以得到递推关系:

A_k = A_{k+1} - (A_{k+1}² τ) / (η + A_{k+1} τ)
B_k = B_{k+1} - (A_{k+1} B_{k+1} τ) / (η + A_{k+1} τ)
C_k = C_{k+1} + (B_{k+1}² τ) / (4(η + A_{k+1} τ)) + λ σ² τ x²
小技巧:实际编码时,我建议从后往前递推,先算 A_T, B_T, C_T,再一步步往前。这样计算量很小,O(T) 复杂度。

最优交易速度的闭式解

有了价值函数,最优交易速度 vk* 可以直接求导得到:

v_k* = (A_{k+1} x_k + B_{k+1}/2) τ / (η + A_{k+1} τ)

这个公式看着有点复杂,但它的含义很直观:

  • 分子里的 Ak+1 xk 代表「未来风险的折现」
  • 分母里的 η 是瞬时冲击成本
  • 整个式子告诉你:当前持仓越多,未来风险越大,就应该卖得越快

更妙的是,当 T 很大时,Ak 会收敛到一个常数:

A = (λ σ² τ) / (1 + √(1 + 4 λ σ² τ / η))

这时候最优策略就变成了一个简单的线性函数:

v_k* = (A / (η + A τ)) x_k

说白了,就是按固定比例减持。这个比例取决于风险厌恶、波动率和冲击成本。

避坑指南:我曾经在回测时发现,如果 λ 设得太大,最优策略会建议你在第一个时间步就卖掉大部分仓位。这在实际交易中可能引发严重的市场冲击。所以参数调优时,一定要结合市场深度数据来校准 η 和 λ。

Python实现示例

下面给个简单的实现,方便你理解整个流程:

import numpy as np

def almgren_chriss_optimal(T, X, sigma, tau, eta, lam):
    """
    计算Almgren-Chriss最优执行策略
    
    参数:
        T: 时间步数
        X: 初始持仓
        sigma: 波动率
        tau: 时间步长
        eta: 瞬时冲击系数
        lam: 风险厌恶系数
    """
    # 从后往前递推
    A = np.zeros(T+1)
    B = np.zeros(T+1)
    v = np.zeros(T)
    x = np.zeros(T+1)
    x[0] = X
    
    # 边界条件
    A[T] = 0
    B[T] = 0
    
    # 递推计算A和B
    for k in range(T-1, -1, -1):
        A[k] = A[k+1] - (A[k+1]**2 * tau) / (eta + A[k+1] * tau)
        B[k] = B[k+1] - (A[k+1] * B[k+1] * tau) / (eta + A[k+1] * tau)
    
    # 计算最优交易量
    for k in range(T):
        v[k] = (A[k+1] * x[k] + B[k+1]/2) * tau / (eta + A[k+1] * tau)
        x[k+1] = x[k] - v[k]
    
    return v, x

# 示例参数
T = 10
X = 10000
sigma = 0.02
tau = 1/252  # 日频
eta = 0.001
lam = 0.1

v_opt, x_opt = almgren_chriss_optimal(T, X, sigma, tau, eta, lam)
print("最优交易量:", v_opt)
print("持仓变化:", x_opt)

核心逻辑流程图

下面这张图帮你梳理整个求解过程:

离散时间最优执行策略求解流程 1. 问题设定 单资产、无风险、T步 2. 建立目标函数 成本 + 风险惩罚 3. 动态规划 贝尔曼方程 4. 二次型假设 V = Ax² + Bx + C 5. 递推求解 A_k, B_k, C_k 6. 最优交易速度 闭式解 v_k* 7. 策略执行 按比例减持 从问题设定到闭式解,整个流程清晰可循

关键参数的影响

最后,我用一个表格总结一下各个参数对策略的影响:

参数 增大时的影响 实际含义
λ(风险厌恶) 前期卖出更多,持仓下降更快 你更担心价格波动,宁愿多付冲击成本
η(瞬时冲击) 交易更均匀,避免集中下单 市场深度不足,大单会严重推高成本
σ(波动率) 类似λ,加速减持 市场波动大,持仓风险高
T(时间步数) 每步交易量减少,执行更分散 时间充裕,可以慢慢卖

嗯,到这里离散时间下的最优执行策略就讲完了。这个模型虽然简单,但它是很多量化交易系统的基础。我个人建议你先把这段代码跑通,然后试着调调参数,看看策略怎么变化。实践出真知嘛。

一句话总结:离散时间Almgren-Chriss模型的核心,就是用动态规划在冲击成本和风险之间找到最优平衡点,最终得到一个简洁的闭式解。
专注资料整理