导航
- Basic Model
- Efficient Frontier
- Factor model and efficiency
- Slippage Cost
- Market Impact Costs
- Transaction Costs
- Cardinality constraints
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()