导航
Basic Model
经典的Markowitz模型考虑投资
n
n
n支资产,设
x
j
x_j
xj表示在第
j
j
j支资产的投资比例,资产收益率为随机变量
r
r
r,并且期望收益率
μ
\mu
μ为已知
μ
=
E
r
\mu=\mathbb{E}r
μ=Er
资产的方差为
Σ
=
E
(
r
−
μ
)
(
r
−
μ
)
T
\Sigma=\mathbb{E}(r-\mu)(r-\mu)^T
Σ=E(r−μ)(r−μ)T
投资组合的期望收益率为
E
y
=
μ
T
x
\mathbb{E}y=\mu^Tx
Ey=μTx
组合方差为
E
(
y
−
E
y
)
2
=
x
T
Σ
x
\mathbb{E}(y-\mathbb{E}y)^2=x^T\Sigma x
E(y−Ey)2=xTΣx
在限制风险的情况下,组合收益率最大化模型为
max
μ
T
x
s
.
t
.
{
e
T
x
=
w
+
e
T
x
0
x
T
Σ
x
≤
γ
2
x
≥
0
\begin{aligned} &\max \mu^Tx\\ &s.t. \begin{cases} e^Tx=w+e^Tx^0\\ x^T\Sigma x\leq \gamma^2\\ x\geq 0 \end{cases} \end{aligned}
maxμTxs.t.⎩⎪⎨⎪⎧eTx=w+eTx0xTΣx≤γ2x≥0
方差-协方差矩阵
Σ
\Sigma
Σ为半正定矩阵,所以存在矩阵
G
G
G满足
Σ
=
G
G
T
\Sigma=GG^T
Σ=GGT
可以使用Cholesky
分解求出
G
G
G,对于给定的
G
G
G,有
x
T
Σ
x
=
x
T
G
G
T
x
=
∥
G
T
x
∥
2
2
x^T\Sigma x=x^TGG^Tx=\lVert G^Tx\rVert_2^2
xTΣx=xTGGTx=∥GTx∥22
风险约束可以表示为
γ
≥
∥
G
T
x
∥
\gamma\geq \lVert G^Tx\rVert
γ≥∥GTx∥
即
(
γ
,
G
T
,
x
)
∈
Q
n
+
1
(\gamma,G^T, x)\in\mathcal{Q}^{n+1}
(γ,GT,x)∈Qn+1
其中
Q
n
+
1
\mathcal{Q}^{n+1}
Qn+1是
(
n
+
1
)
(n+1)
(n+1)维的二阶锥,所以模型可以转化为
max
μ
T
x
s
.
t
.
{
e
T
x
=
w
+
e
T
x
0
(
γ
,
G
T
,
x
)
∈
Q
n
+
1
x
≥
0
\begin{aligned} &\max \mu^Tx\\ &s.t. \begin{cases} e^Tx=w+e^Tx^0\\ (\gamma,G^T, x)\in\mathcal{Q}^{n+1}\\ x\geq 0 \end{cases} \end{aligned}
maxμTxs.t.⎩⎪⎨⎪⎧eTx=w+eTx0(γ,GT,x)∈Qn+1x≥0
mosek
建模代码如下
from mosek.fusion import *
def Markowitz(n, mu, GT, x0, w, gamma):
with Model('markowitz') as M:
x=M.variable('x', n, Domain.greaterThan(0.0))
M.objective('obj', ObjectiveSense.Maximize, Expr.dot(mu, x))
M.constraint('budget', Expr.sum(x), Domain.equalsTo(w+sum(x0)))
M.constraint('risk', Expr.vstack(gamma, Expr.mul(GT, x)), Domain.inQCone())
M.solve()
Efficient Frontier
有效前沿也被称为帕累托最优组合(pareto optimal portfolio),显然投资者应该投资有效前沿上的组合,有效前沿上的组合是收益与风险的权衡,对于权衡因子
α
>
0
\alpha>0
α>0可以建立如下模型.
max
μ
T
−
α
x
T
Σ
x
s
.
t
.
{
e
T
x
=
w
+
e
T
x
0
x
≥
0
\begin{aligned} &\max \mu^T-\alpha x^T\Sigma x\\ &s.t. \begin{cases} e^Tx=w+e^Tx^0\\ x\geq 0 \end{cases} \end{aligned}
maxμT−αxTΣxs.t.{eTx=w+eTx0x≥0
使用旋转锥约束等价转换模型为
max
μ
T
x
−
α
s
s
.
t
.
{
e
T
x
=
w
+
e
T
x
0
(
s
,
0.5
,
G
T
x
)
∈
Q
r
n
+
2
x
≥
0
\begin{aligned} &\max \mu^Tx-\alpha s\\ &s.t. \begin{cases} e^Tx=w+e^Tx^0\\ (s, 0.5, G^Tx)\in \mathcal{Q}_r^{n+2}\\ x\geq 0 \end{cases} \end{aligned}
maxμTx−αss.t.⎩⎪⎨⎪⎧eTx=w+eTx0(s,0.5,GTx)∈Qrn+2x≥0
mosek
建模代码
from mosek.fusion import *
import numpy as np
def EfficientFrontier(n, mu, GT, x0, w, alphas):
with Model('EFF') as M:
x=M.variable('x', n, Domain.greaterThan(0.0))
s=M.variable('s', 1, Domain.unbounded())
M.constraint('budget', Expr.sum(x), Domain.equalsTo(w+sum(x0)))
M.constraint('variance', Expr.vstack(s, 0.5, Expr.mul(GT, x)), Domain.inRotatedQCone())
frontier=[]
ret = Expr.dot(mu, x)
for alpha in alphas:
M.objective('obj', ObjectiveSense.Maximize, Expr.sub(ret, Expr.mul(alpha, s)))
M.solve()
# 加入权衡因子,期望收益和风险水平 tuple
frontier.append((alpha, np.dot(mu, x.level()), s.level()[0]))
return frontier
Factor model and efficiency
模型计算成本取决于约束数量,变量数量和矩阵稀疏度,考虑从方差-协方差角度提升计算效率,假设
Σ
=
D
+
V
V
T
\Sigma=D+VV^T
Σ=D+VVT
其中
D
D
D是正定的对角矩阵,
V
V
V是
n
×
p
n\times p
n×p矩阵,且
p
≪
n
p\ll n
p≪n,通过Cholesky
分解,
G
G
G需要存储
O
(
n
(
n
+
1
)
/
2
)
\mathcal{O}(n(n+1)/2)
O(n(n+1)/2)的元素. 使用因子模型分解,可以将空间复杂度降低到
O
(
n
+
p
n
)
\mathcal{O}(n+pn)
O(n+pn),其中
G
T
=
[
D
1
/
2
V
T
]
G^T=\left[ \begin{matrix} D^{1/2}\\ V^T \end{matrix} \right]
GT=[D1/2VT]
Slippage Cost
考虑交易成本是一个更加接近实际的模型
max
μ
T
x
s
.
t
.
{
e
T
x
+
∑
j
=
1
n
T
j
(
Δ
x
j
)
=
w
+
e
T
x
0
x
T
Σ
x
≤
γ
2
x
≥
0
\begin{aligned} &\max \mu^Tx\\ &s.t. \begin{cases} e^Tx+\sum_{j=1}^nT_j(\Delta x_j)=w+e^Tx^0\\ x^T\Sigma x\leq \gamma^2\\ x\geq 0 \end{cases} \end{aligned}
maxμTxs.t.⎩⎪⎨⎪⎧eTx+∑j=1nTj(Δxj)=w+eTx0xTΣx≤γ2x≥0
其中
Δ
x
j
\Delta x_j
Δxj是资产
j
j
j的变化量
Δ
x
j
=
x
j
−
x
j
0
\Delta x_j=x_j-x_j^0
Δxj=xj−xj0
函数
T
j
(
Δ
x
j
)
T_j(\Delta x_j)
Tj(Δxj)表示资产
j
j
j的交易费用.
Market Impact Costs
在小额资产交易时,成交额不会影响市场价格,如果是大额资产交易,市场价格会受到冲击,可以用如下非线性函数设置资产
j
j
j的市场冲击成本(market impact cost)
T
j
(
Δ
x
j
)
=
m
j
∣
Δ
x
j
∣
3
/
2
T_j(\Delta x_j)=m_j|\Delta x_j|^{3/2}
Tj(Δxj)=mj∣Δxj∣3/2
其中
m
j
m_j
mj为待估计的常数,可以使用幂锥power cone
表示
t
≥
∣
z
∣
3
/
2
t\geq |z|^{3/2}
t≥∣z∣3/2
{
(
t
,
z
)
:
t
≥
∣
z
∣
3
/
2
}
≜
{
(
t
,
z
)
:
(
t
,
1
,
z
)
∈
P
3
2
/
3
,
1
/
3
}
\{(t, z): t\geq |z|^{3/2}\}\triangleq\{(t,z): (t, 1, z)\in \mathcal{P}_3^{2/3, 1/3}\}
{(t,z):t≥∣z∣3/2}≜{(t,z):(t,1,z)∈P32/3,1/3}
所以
∑
j
=
1
n
T
j
(
Δ
x
j
)
=
∑
j
=
1
n
m
j
∣
x
j
−
x
j
0
∣
3
/
2
\sum_{j=1}^nT_j(\Delta x_j)=\sum_{j=1}^n m_j|x_j-x_j^0|^{3/2}
∑j=1nTj(Δxj)=∑j=1nmj∣xj−xj0∣3/2可以表示如下
z
j
=
∣
x
j
−
x
j
0
∣
(
t
j
,
1
,
z
j
)
∈
P
3
2
/
3
,
1
/
3
\begin{aligned} &z_j=|x_j-x_j^0|\\ &(t_j, 1, z_j)\in \mathcal{P}_3^{2/3, 1/3} \end{aligned}
zj=∣xj−xj0∣(tj,1,zj)∈P32/3,1/3
由于约束
z
j
=
∣
x
j
−
x
j
0
∣
z_j=|x_j-x_j^0|
zj=∣xj−xj0∣,导致问题是非凸的,在一般情况下可以使用松弛约束条件
z
j
≥
∣
x
j
−
x
j
0
∣
z_j\geq |x_j-x_j^0|
zj≥∣xj−xj0∣
如果所有资产中包含无风险资产,约束条件为
z
j
>
∣
x
j
−
x
j
0
∣
z_j>|x_j-x_j^0|
zj>∣xj−xj0∣
建立模型如下
max
μ
T
x
s
.
t
.
{
e
T
+
m
T
t
=
w
+
e
T
x
0
(
γ
,
G
T
x
)
∈
Q
n
+
1
(
t
j
,
1
,
x
j
−
x
j
0
)
∈
P
3
2
/
3
,
1
/
3
,
j
=
1
,
…
,
n
x
≥
0
\begin{aligned} &\max \mu^Tx\\ &s.t. \begin{cases} e^T+m^Tt=w+e^Tx^0\\ (\gamma, G^Tx)\in\mathcal{Q}^{n+1}\\ (t_j, 1, x_j-x_j^0)\in\mathcal{P}_3^{2/3, 1/3}, j=1, \dots, n\\ x\geq 0 \end{cases} \end{aligned}
maxμTxs.t.⎩⎪⎪⎪⎨⎪⎪⎪⎧eT+mTt=w+eTx0(γ,GTx)∈Qn+1(tj,1,xj−xj0)∈P32/3,1/3,j=1,…,nx≥0
mosek
建模代码
def MarketImpact(n, mu, GT, x0, w, gamma, m):
with Model('mp') as M:
x=M.variable('x', n, Domain.greaterThan(0.0))
t=M.variable('t', n, Domain.unbounded())
M.objective('obj', ObjectiveSense.Maximize, Expr.dot(mu, x))
M.constraint('budget', Expr.add(Expr.sum(x), Expr.dot(m, t)), Domain.equalsTo(w+sum(x0)))
M.constraint('risk', Expr.vstack(gamma, Expr.mul(GT, x)), Domain.inQCone())
M.constraint('tz', Expr.hstack(t, Expr.constTerm(n, 1.0), Expr.sub(x, x0)), Domain.inPPowerCone(2.0/3.0))
M.solve()
return x.level(), t.level()
Transaction Costs
假设交易成本符合分段函数形式
T
j
(
Δ
x
j
)
=
{
0
,
Δ
x
j
=
0
f
j
+
g
j
∣
Δ
x
j
∣
,
O
.
W
T_j(\Delta x_j)=\begin{cases} 0, &\Delta x_j=0\\ f_j+g_j|\Delta x_j|, &O.W \end{cases}
Tj(Δxj)={0,fj+gj∣Δxj∣,Δxj=0O.W
交易成本分为固定成本
f
j
f_j
fj和变动成本
g
j
g_j
gj,建立模型如下
max
μ
T
x
s
.
t
.
{
e
T
x
+
f
T
y
+
g
T
z
=
w
+
e
T
x
0
(
γ
,
G
T
x
)
∈
Q
n
+
1
z
j
≥
x
j
−
x
j
0
,
j
=
1
,
…
,
n
z
j
≥
x
j
0
−
x
j
,
j
=
1
,
…
,
n
z
j
≤
U
j
y
j
,
j
=
1
,
…
,
n
y
j
∈
{
0
,
1
}
x
≥
0
\begin{aligned} &\max \mu^Tx\\ &s.t. \begin{cases} e^Tx+f^Ty+g^Tz=w+e^Tx^0\\ (\gamma, G^Tx)\in\mathcal{Q}^{n+1}\\ z_j\geq x_j-x_j^0, j=1,\dots, n\\ z_j\geq x_j^0-x_j, j=1,\dots, n\\ z_j\leq U_jy_j, j=1,\dots, n \\ y_j\in\{0 ,1\}\\ x\geq 0 \end{cases} \end{aligned}
maxμTxs.t.⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧eTx+fTy+gTz=w+eTx0(γ,GTx)∈Qn+1zj≥xj−xj0,j=1,…,nzj≥xj0−xj,j=1,…,nzj≤Ujyj,j=1,…,nyj∈{0,1}x≥0
其中
U
j
U_j
Uj表示可交易资产总量的先验上限,当
z
j
>
0
z_j\gt 0
zj>0时,
y
j
=
1
y_j=1
yj=1,即资产
j
j
j的交易费用方程为
f
j
y
j
+
g
j
z
j
f_jy_j+g_jz_j
fjyj+gjzj
mosek
建模代码
def TransactionCost(n, mu, GT, x0, w, gamma, f, g):
w0=w+sum(x0)
u=n*[w0]
with Model('tc') as M:
x=M.variable('x', n, Domain.greaterThan(0.0))
z=M.variable('z', n, Domain.unbounded())
# 0-1变量,表示资产j是否交易
y=M.variable('y', n, Domain.binary())
M.objective('obj', ObjectiveSense.Maximize, Expr.dot(mu, x))
M.constraint('budget', Expr.add([Expr.sum(x), Expr.dot(f, y), Expr.dot(g, z)]), Domain.equalsTo(w0))
M.constraint('risk', Expr.vstack(gamma, Expr.mul(GT, x)), Domain.inQCone())
# z>=|x-x0|
M.constraint('buy', Expr.sub(z, Expr.sub(x, x0)), Domain.greaterThan(0.0))
M.constraint('sell', Expr.sub(z, Expr.sub(x0, x)), Domain.greaterThan(0.0))
# 或者等价二阶锥形式
# M.constraint('trade', Expr.hstack(z, Expr.sub(x, x0)), Domain.inQCone())
# 开关变量y
M.constraint('y_on_off', Expr.sub(z, Expr.mulElm(u, y)), Domain.lessThan(0.0))
# 由于MIP问题的求解复杂度较高,设置求解时间上限
M.setSolverParam('mioMaxTime', 180.0)
M.solve()
return x.level(), y.level(), z.level()
Cardinality constraints
设置约束,最多有
k
k
k项资产可以被交易,即
Δ
x
j
=
∣
x
j
−
x
j
0
∣
\Delta x_j=|x_j-x_j^0|
Δxj=∣xj−xj0∣中最多有
k
k
k个元素非零,且
k
≪
n
k\ll n
k≪n,建立模型如下.
max
μ
T
x
s
.
t
.
{
e
T
x
=
w
+
e
T
x
0
(
γ
,
G
T
x
)
∈
Q
n
+
1
z
j
≥
x
j
−
x
j
0
,
j
=
1
,
…
,
n
z
j
≥
x
j
0
−
x
j
,
j
=
1
,
…
,
n
z
j
≤
U
j
y
j
,
j
=
1
,
…
,
n
y
j
∈
{
0
,
1
}
,
j
=
1
,
…
,
n
e
T
y
≤
k
x
≥
0
\begin{aligned} &\max \mu^Tx\\ &s.t. \begin{cases} e^Tx=w+e^Tx^0\\ (\gamma, G^Tx)\in \mathcal{Q}^{n+1}\\ z_j\geq x_j-x_j^0, &j=1,\dots, n\\ z_j\geq x_j^0-x_j, &j=1,\dots, n\\ z_j\leq U_jy_j, &j=1,\dots, n\\ y_j\in\{0, 1\}, &j=1,\dots, n\\ e^Ty\leq k\\ x\geq 0 \end{cases} \end{aligned}
maxμTxs.t.⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧eTx=w+eTx0(γ,GTx)∈Qn+1zj≥xj−xj0,zj≥xj0−xj,zj≤Ujyj,yj∈{0,1},eTy≤kx≥0j=1,…,nj=1,…,nj=1,…,nj=1,…,n
mosek
建模代码
def cardinality(n, mu, GT, x0, w, gamma, k):
w0=w+sum(x0)
u=n*[w0]
with Model('cb') as M:
x=M.variable('x', n, Domain.greaterThan(0.0))
z=M.variable('z', n, Domain.unbounded())
y=M.variable('y', n, Domain.binary())
M.objective('obj', ObjectiveSense.Maximize, Expr.dot(mu, x))
M.constraint('budget', Expr.sum(x), Domain.equalsTo(w+sum(x0)))
M.constraint('risk', Expr.vstack(gamma, Expr.mul(GT, x)), Domain.inQCone())
# z>=|x-x0|
M.constraint('buy', Expr.sub(z, Expr.sub(x, x0)), Domain.greaterThan(0.0))
M.constraint('sell', Expr.sub(z, Expr.sub(x0, x)), Domain.greaterThan(0.0))
M.constraint('y_on_off', Expr.sub(z, Expr.mulElm(u, y)), Domain.lessThan(0.0))
M.constraint('cardinality', Expr.sum(y), Domain.lessThan(k))
M.setSolverParam('mioMaxTime', 180.0)
M.solve()
return x.level()