棋高一着——多周期投资组合优化

在前文《股票多因子量化多头策略之组合优化框架》中,已经较为全面地介绍了如何将单期投资组合权重的求解,转化为二次规划问题。本文是对斯坦福大学与黑石基金合作论文《Multi-Period Trading via Convex Optimization》 的要点解读与核心内容总结。该文在2017年提出,首次较为系统的介绍了多期优化的应用。

本文包含AI辅助创作

模型

资产与现金

我们考虑一个包含 \(n\) 种资产和一个现金账户的投资组合,时间范围为有限的 \(T\) 个离散时间段。投资组合在每个时间段的持有量为 \(h_t \in \mathbb{R}^{n+1}\) ,其中 \((h_{ti}\) 表示第 \(i\) 个资产在时间段 \(t\) 的美元价值,\((h_t)_{n+1}\) 表示现金余额。投资组合的总价值 \(v_t\) 为 \(v_t = 1^T h_t\) ,资产权重为 \(w_t = h_t / v_t\) 。

交易

假设所有交易都发生在每个时间段的开始。交易向量 \(u_t \in \mathbb{R}^n\) 表示在时间段 \(t\) 开始时的交易金额,其中 \(u_{ti} > 0\) 表示购买资产 \(i\) ,\(u_{ti} < 0\) 表示卖出资产 \(i\) 。新的投资组合持有量为 \(h_{t+1} = h_t + u_t\) ,交易后持有的现金为

$$ (h_{t+1})_{n+1} = (h_t)_{n+1} - 1^T u_t $$

交易成本

比如交易成本由线性和固定成本组成:

$$ \text{交易成本} = \gamma^T |u_t| + \delta^T \mathbf{1}_{|u_t| > 0} $$

其中 \(\gamma\) 是每单位交易量的成本向量,\(\delta\) 是每笔交易的固定成本向量。

持有成本

持有成本包括借贷成本和管理费:

$$ \text{持有成本} = \lambda^T h_t + \mu^T \mathbf{1}_{h_t < 0} $$

其中 \(\lambda\) 是持有每单位资产的成本,\(\mu\) 是借贷每单位资产的成本。

自筹条件

自筹条件要求每个时间段的现金余额满足:

$$ (h_{t+1})_{n+1} = (h_t)_{n+1} - 1^T u_t \geq 0 $$

单周期优化(SPO)

单周期优化(SPO)是一种常见的投资组合优化方法,旨在在单个时间段内最大化投资组合的预期回报,同时控制风险和交易成本。SPO的主要特点是仅考虑当前时间段的资产配置决策,而不考虑未来时间段的变化。

目标函数

在单周期优化中,目标函数通常是最大化风险调整后的回报。一个典型的目标函数可以表示为:

$$ \max_{w_t} \left( r_t^T w_t - \gamma_t \psi_t(w_t) - \phi_{\text{hold}, t} (w_t) - \phi_{\text{trade}, t} (w_t - w_{t-1}) \right) $$

其中:

  • \(w_t\) 是当前时间段 \(t\) 的资产权重。
  • \(r_t\) 是当前时间段 \(t\) 的资产预期回报。
  • \(\gamma_t\) 是风险规避参数。
  • \(\psi_t(w_t)\) 是当前时间段 \(t\) 的风险函数(例如,专家因子风险模型预测的协方差)。
  • \(\phi_{\text{hold}, t}(w_t)\) 是当前时间段 \(t\) 的持有成本。
  • \(\phi_{\text{trade}, t}(w_t - w_{t-1})\) 是当前时间段 \(t\) 的交易成本。

约束条件

单周期优化问题需要满足一系列约束条件,以确保投资组合的合理性和合规性。常见的约束条件包括:

  • 资产权重的总和为1:

    $$ \sum_{i=1}^{n} (w_{t})_i = 1 $$

  • 资产权重非负:

    $$ w_t \geq 0 $$

这些约束条件保证了投资组合是一个有效的组合。

求解

单周期优化问题通常通过凸优化方法求解,可以使用优化工具如 cvxpy 来实现。下面是一个简单的单周期优化示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import cvxpy as cp
import numpy as np

# 设置参数
n = 5 # 资产数量
r_t = np.random.randn(n) # 当前时间段的资产回报率
gamma_t = 10 # 风险厌恶
Sigma_t = np.random.rand(n, n) # 风险矩阵
Sigma_t = np.dot(Sigma_t, Sigma_t.T) # 确保风险矩阵为正定
phi_hold_t = np.random.rand(n) # 持有成本
phi_trade_t = np.random.rand(n) # 交易成本
w_t_1 = np.ones(n) / n # 上一个时间段的资产权重

# 决策变量
w_t = cp.Variable(n) # 当前时间段的资产权重

# 目标函数
objective = cp.Maximize(r_t.T @ w_t - gamma_t * cp.quad_form(w_t, Sigma_t) - phi_hold_t.T @ w_t - phi_trade_t.T @ cp.abs(w_t - w_t_1))

# 约束条件
constraints = [cp.sum(w_t) == 1, w_t >= 0]

# 优化问题
prob = cp.Problem(objective, constraints)
prob.solve()

# 输出结果
print("最优资产权重:")
print(w_t.value)

小结

单周期优化(SPO)是一种针对单个时间段的投资组合优化方法,主要目标是最大化当前时间段的风险调整回报。尽管SPO在单个时间段内能够提供有效的资产配置决策,但其缺点是未能考虑未来多个时间段的变化和决策对后续时间段的影响。因此,单周期优化在处理长期投资决策时存在一定的局限性。

多周期规划 (MPO)

多周期优化考虑未来多个时期的资产配置和交易决策,通过在更长的时间跨度内进行规划和优化,来提高投资组合的整体表现。比如我们预测短期内回报为正,但长期回报为负,SPO可能为了最大化下一期收益,使得未来持仓处于不利位置,不得不付出更高的交易成本才能脱身。而多周期优化可以通过考虑交易成本和未来的回报变化,做出更加优化的决策。

目标函数

多周期优化问题通常在一个规划范围内解决,范围可以延伸到未来的多个时期。具体而言,我们在每个时期选择当期的交易向量 \(z_t\),并通过一个优化问题来规划未来 \(H\) 个时期内的交易:

$$ t, t+1, \ldots, t+H-1 $$

多周期优化的目标是最大化整个规划范围内的风险调整回报。对于一个规划范围 \( t \) 到 \( t+H-1 \) 的多周期优化问题,其目标函数可以表示为:

$$ \sum_{\tau=t}^{t+H-1} \left( r_{\tau|t}^T (w_\tau + z_\tau) - \gamma_\tau \psi_\tau(w_\tau + z_\tau) - \phi_{\text{hold}, \tau} (w_\tau + z_\tau) - \phi_{\text{trade}, \tau} (z_\tau) \right) $$

其中:

  • \(r_{\tau|t}\) 是在时期 \(t\) 对时期 \(\tau\) 回报的估计。
  • \(w_\tau\) 是时期 \(\tau\) 的资产权重。
  • \(z_\tau\) 是时期 \(\tau\) 的交易向量。
  • \(\gamma_\tau\) 是风险规避参数。
  • \(\psi_\tau\) 是风险函数。
  • \(\phi_{\text{hold}, \tau}\) 是持有成本函数。
  • \(\phi_{\text{trade}, \tau}\) 是交易成本函数。

在多周期优化中,资产权重的变化通过以下动态方程来描述:

$$ w_{t+1} = \frac{1}{1 + R_t^p} (1 + r_t) \circ (w_t + z_t) $$

其中 \(R_t^p\) 是时期 \(t\) 的无风险回报率,\(r_t\) 是时期 \(t\) 的资产回报率,\(\circ\) 表示元素乘法。

在此,我们引入一个简化条件,忽略资产价格波动导致的权重变化。

$$ w_{\tau+1} = w_\tau + z_\tau, \quad \tau = t, \ldots, t+H-1 $$

此时我们可以得到等价问题:

$$ \max \sum_{\tau=t+1}^{t+H} \left( r_{\tau|t}^T w_\tau - \gamma_\tau \psi_\tau (w_\tau) - \phi_{\text{hold}, \tau} (w_\tau) - \phi_{\text{trade}, \tau} (w_\tau - w_{\tau-1}) \right) $$

该问题的决策变量为未来 \(H\) 个时期的资产权重 \(w_{t+1}, \ldots, w_{t+H}\)。

求解

下面是一个示例代码,展示如何使用 cvxpy 进行多周期优化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import cvxpy as cp
import numpy as np

# 设置参数
n = 5 # 资产数量
T = 10 # 时间段数量

# 生成随机数据
np.random.seed(42)
r = np.random.randn(T, n) # 资产回报率
gamma = 0.1 # 风险规避参数
phi_hold = np.random.rand(T, n) # 持有成本
phi_trade = np.random.rand(T, n) # 交易成本
Sigma = np.random.rand(T, n, n) # 风险矩阵
Sigma = np.array([np.dot(S, S.T) for S in Sigma]) # 确保风险矩阵为正定

# 初始资产权重
w0 = np.ones(n) / n

# 决策变量
w = cp.Variable((T, n)) # 每个时间段的资产权重
z = cp.Variable((T, n)) # 每个时间段的交易向量

# 目标函数
objective = 0
for t in range(T):
if t == 0:
prev_w = w0
else:
prev_w = w[t-1]
objective += r[t] @ w[t] - gamma * cp.quad_form(w[t], Sigma[t]) - phi_hold[t] @ w[t] - phi_trade[t] @ cp.abs(z[t])

# 约束条件
constraints = []
for t in range(T):
if t > 0:
constraints.append(w[t] == w[t-1] + z[t])
constraints.append(cp.sum(w[t]) == 1) # 资产权重总和为1
constraints.append(w[t] >= 0) # 权重非负

# 优化问题
prob = cp.Problem(cp.Maximize(objective), constraints)
prob.solve()

# 输出结果
print("最优资产权重:")
print(w.value)
print("最优交易向量:")
print(z.value)

代码说明

  1. 参数设置

    • n 表示资产数量。
    • T 表示时间段数量。
    • H 表示规划范围。
  2. 随机数据生成

    • r 为资产回报率矩阵,形状为 (T, n)
    • gamma 为风险规避参数。
    • phi_holdphi_trade 分别为持有成本和交易成本矩阵,形状为 (T, n)
    • Sigma 为风险矩阵,形状为 (T, n, n),通过确保矩阵为正定生成。
  3. 初始资产权重

    • w0 为初始资产权重,假设初始均匀分布。
  4. 决策变量

    • w 为每个时间段的资产权重变量,形状为 (T, n)
    • z 为每个时间段的交易向量变量,形状为 (T, n)
  5. 目标函数

    • 目标函数为在整个时间段内最大化风险调整后的回报。
  6. 约束条件

    • w[t] 为每个时间段的资产权重。
    • z[t] 为每个时间段的交易向量。
    • 约束条件确保资产权重总和为1且非负。
  7. 优化问题

    • 使用 cvxpyProblem 类定义并求解优化问题。
  8. 输出结果

    • 输出最优资产权重和交易向量。

通过以上代码示例,我们可以看到如何使用 cvxpy 库实现多周期优化(MPO)。这种方法可以有效地解决多个时间段的资产配置和交易决策问题,提高投资组合的整体表现。

棋高一着——多周期投资组合优化

https://heth.ink/MultiPeriodOpt/

作者

YK

发布于

2024-06-21

更新于

2024-06-21

许可协议