天天看点

【mosek.fusion】Portfolio OptimizationBasic ModelEfficient FrontierFactor model and efficiencySlippage CostMarket Impact CostsTransaction CostsCardinality constraints

导航

  • 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+2​x≥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=1n​Tj​(Δ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=1n​Tj​(Δxj​)=∑j=1n​mj​∣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​≤Uj​yj​,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 fj​yj​+gj​zj​

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​≤Uj​yj​,yj​∈{0,1},eTy≤kx≥0​j=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()
           

继续阅读