【mosek.fusion】Portfolio Optimization

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(yEy)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γ2x0
方差-协方差矩阵 Σ \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=GTx22
风险约束可以表示为
γ ≥ ∥ 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+1x0
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+eTx0x0
使用旋转锥约束等价转换模型为
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+2x0
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 pn,通过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γ2x0
其中 Δ 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=xjxj0
函数 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Δxj3/2
其中 m j m_j mj为待估计的常数,可以使用幂锥power cone表示 t ≥ ∣ z ∣ 3 / 2 t\geq |z|^{3/2} tz3/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):tz3/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=1nmjxjxj03/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=xjxj0(tj,1,zj)P32/3,1/3
由于约束 z j = ∣ x j − x j 0 ∣ z_j=|x_j-x_j^0| zj=xjxj0,导致问题是非凸的,在一般情况下可以使用松弛约束条件
z j ≥ ∣ x j − x j 0 ∣ z_j\geq |x_j-x_j^0| zjxjxj0
如果所有资产中包含无风险资产,约束条件为
z j > ∣ x j − x j 0 ∣ z_j>|x_j-x_j^0| zj>xjxj0
建立模型如下
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,xjxj0)P32/3,1/3,j=1,,nx0
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+1zjxjxj0,j=1,,nzjxj0xj,j=1,,nzjUjyj,j=1,,nyj{0,1}x0
其中 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=xjxj0中最多有 k k k个元素非零,且 k ≪ n k\ll n kn,建立模型如下.
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+1zjxjxj0,zjxj0xj,zjUjyj,yj{0,1},eTykx0j=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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quant0xff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值