司守奎《数学建模算法与应用》第二版
线性规划——投资的收益和风险
1. 符号规定
( 1 ) s i 表示第 i 种投资项目 , i = 0 , 1 , . . . , n , 其中 s 0 指存入银行。 (1)s_i表示第i种投资项目,i=0,1,...,n,其中s_0指存入银行。 (1)si表示第i种投资项目,i=0,1,...,n,其中s0指存入银行。
( 2 ) r i , p i , q i 分别表示 s i 的平均收益率、交易费率、风险损失率 , i = 0 , 1 , . . . , n , 其中 p 0 = 0 , q 0 = 0 (2)r_i,p_i,q_i分别表示s_i的平均收益率、交易费率、风险损失率,i=0,1,...,n,其中p_0=0,q_0=0 (2)ri,pi,qi分别表示si的平均收益率、交易费率、风险损失率,i=0,1,...,n,其中p0=0,q0=0
( 3 ) u i 表示 s i 的购买定值 , i = 1 , 2 , . . . , n 。 (3)u_i表示s_i的购买定值,i=1,2,...,n。 (3)ui表示si的购买定值,i=1,2,...,n。
( 4 ) x i 表示投资项目 s i 的资金 , i = 0 , 1 , . . . , n 。 (4)x_i表示投资项目s_i的资金,i=0,1,...,n。 (4)xi表示投资项目si的资金,i=0,1,...,n。
( 5 ) a 表示投资风险度。 (5)a表示投资风险度。 (5)a表示投资风险度。
( 6 ) Q 表示总体收益。 (6)Q表示总体收益。 (6)Q表示总体收益。
2. 基本假设
假设的思想一定要学会,好的假设能够增加答案的严谨性。假设1中由于投资数额应该是常量,常量可以设为1来简化计算,同时题中已经给出投资数额相当大;假设2-3是题中所给的假设条件;假设4-6是为了方便后续数据处理即增加严谨性所做出的假设,可以当作是假设的套话,xxx之间相互独立;xxx不受其他因素干扰。
( 1 ) 投资数额 M 相当大 , 为了便于计算 , 假设 M = 1 。 (1)投资数额M相当大,为了便于计算,假设M=1。 (1)投资数额M相当大,为了便于计算,假设M=1。
( 2 ) 投资越分散 , 总的风险越小。 (2)投资越分散,总的风险越小。 (2)投资越分散,总的风险越小。
( 3 ) 总体风险用投资项目 s i 中最大的一个风险来度量。 (3)总体风险用投资项目s_i中最大的一个风险来度量。 (3)总体风险用投资项目si中最大的一个风险来度量。
( 4 ) n + 1 中资产 s i 之间是相互独立的。 (4)n+1中资产s_i之间是相互独立的。 (4)n+1中资产si之间是相互独立的。
( 5 ) 在投资的这一时期内 , r i , p i , q i 为定值 , 不受意外因素影响。 (5)在投资的这一时期内,r_i,p_i,q_i为定值,不受意外因素影响。 (5)在投资的这一时期内,ri,pi,qi为定值,不受意外因素影响。
( 6 ) 净收益和总体风险只受 r i , p i , q i 影响 , 不受其他因素干扰。 (6)净收益和总体风险只受r_i,p_i,q_i影响,不受其他因素干扰。 (6)净收益和总体风险只受ri,pi,qi影响,不受其他因素干扰。
3. 模型的分析与建立
(1)总体风险用所投资的
s
i
s_i
si中最大的一个风险来衡量,注意风险=风险损失率x投资资金,即
max
{
q
i
x
i
∣
i
=
1
,
2
,
.
.
.
,
n
}
\max\{q_ix_i|i=1,2,...,n\}
max{qixi∣i=1,2,...,n}
(2)购买
s
i
(
i
=
1
,
2
,
.
.
.
,
n
)
s_i(i=1,2,...,n)
si(i=1,2,...,n)所付交易费是一个分段函数,即
交易费
=
{
p
i
x
i
,
x
>
u
i
p
i
u
i
,
x
≤
u
i
\begin{equation} 交易费 = \begin{cases} p_ix_i ,& x > u_i \\ p_iu_i , & x \leq u_i \end{cases} \end{equation}
交易费={pixi,piui,x>uix≤ui
由于投资数额
M
M
M相当大,所以
x
i
x_i
xi应该也相当大,这里分情况讨论。若
x
i
>
>
u
i
x_i>>u_i
xi>>ui,则交易费为
p
i
x
i
p_ix_i
pixi,若
x
i
<
u
i
x_i<u_i
xi<ui,则相对于
x
i
>
>
u
i
x_i>>u_i
xi>>ui的情况来说,无论是
p
i
u
i
p_iu_i
piui还是
p
i
x
i
p_ix_i
pixi都是很小的,可以忽略不计,这里为了方便计算可以令购买
s
i
s_i
si的净收益为
(
r
i
−
p
i
)
x
i
(r_i-p_i)x_i
(ri−pi)xi。
(3)要使净收益尽可能大,总体风险尽可能小,这是一个多目标规划模型。
目标函数为
{
Q
=
max
∑
i
=
0
n
(
r
i
−
p
i
)
x
i
a
=
min
{
max
0
≤
i
≤
n
{
q
i
x
i
}
}
\begin{equation} \begin{cases} Q=\max\sum\limits_{i=0}^{n}(r_i-p_i)x_i \\ a=\min\{\max\limits_{0\leq i \leq n}\{q_ix_i\}\} \end{cases} \end{equation}
⎩
⎨
⎧Q=maxi=0∑n(ri−pi)xia=min{0≤i≤nmax{qixi}}
约束条件为
{
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
x
i
≥
0
,
i
=
0
,
1
,
.
.
.
,
n
\begin{equation} \begin{cases} \sum\limits_{i=0}^{n}(1+p_i)x_i=M \\ x_i \geq{0} , & i=0,1,...,n \end{cases} \end{equation}
⎩
⎨
⎧i=0∑n(1+pi)xi=Mxi≥0,i=0,1,...,n
(4)模型简化
由于多目标规划模型不好处理,所以使用定一动一,先固定一个目标,
模型一
- 固定投资者能接受的最大风险水平
a
a
a,优化收益
Q = max ∑ i = 0 n ( r i − p i ) x i s . t . { q i x i ≤ a , i = 0 , 1 , . . . , n ∑ i = 0 n ( 1 + p i ) x i = M x i ≥ 0 , i = 0 , 1 , . . . , n Q=\max\sum\limits_{i=0}^{n}(r_i-p_i)x_i \\ \begin{equation} s.t. \begin{cases} q_ix_i \leq a,&i=0,1,...,n \\ \sum\limits_{i=0}^{n}(1+p_i)x_i=M\\ x_i\geq 0,&i=0,1,...,n \end{cases} \end{equation} Q=maxi=0∑n(ri−pi)xis.t.⎩ ⎨ ⎧qixi≤a,i=0∑n(1+pi)xi=Mxi≥0,i=0,1,...,ni=0,1,...,n
将问题转换成一个单目标的线性规划,最后就可以得到最大收益 Q Q Q和最大风险水平 a a a之间的关系。这里理论上可以得到两者之间的关系,但是由于最大风险水平 a a a是未知数,所以还是比较抽象的,可以在 a a a的合理区间内取具体值,画出 a a a和 Q Q Q之间的图像。
将题中的信息带入上式
Q
=
0.05
x
0
+
0.27
x
1
+
0.19
x
2
+
0.185
x
3
+
0.185
x
4
s
.
t
.
{
0
x
0
≤
a
,
0.025
x
1
≤
a
,
0.015
x
2
≤
a
,
0.055
x
3
≤
a
,
0.026
x
4
≤
a
x
0
+
1.01
x
1
+
1.02
x
2
+
1.045
x
3
+
1.065
x
4
=
1
x
i
≥
0
,
i
=
0
,
1
,
.
.
.
,
n
Q=0.05x_0+0.27x_1+0.19x_2+0.185x_3+0.185x_4 \\ \begin{equation} s.t. \begin{cases} 0x_0\leq a,0.025x_1\leq a,0.015x_2\leq a,0.055x_3\leq a,0.026x_4\leq a \\ x_0+1.01x_1+1.02x_2+1.045x_3+1.065x_4=1\\ x_i\geq 0,&i=0,1,...,n \end{cases} \end{equation}
Q=0.05x0+0.27x1+0.19x2+0.185x3+0.185x4s.t.⎩
⎨
⎧0x0≤a,0.025x1≤a,0.015x2≤a,0.055x3≤a,0.026x4≤ax0+1.01x1+1.02x2+1.045x3+1.065x4=1xi≥0,i=0,1,...,n
python进行线性规划并绘制最大风险水平-最优值max的图像,如下:
from sympy import symbols
from scipy.optimize import linprog
import matplotlib.pyplot as plt
import numpy as np
#解决中文显示问题
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
if __name__ == "__main__":
# 创建100个最大风险水平a的索引,最小值从0开始,最大值应为M*max{q_i},这里M=1,最大的q_i为0.55
a = np.arange(0, 0.055, 0.00001)
y = [] # 保存最优值的列表
for i in a:
f = np.array([-0.05, -0.27, -0.19, -0.185, -0.185])
Aeq = np.array([[1, 1.01, 1.02, 1.045, 1.065]])
beq = 1
lb = np.zeros(5)
ub = np.array([None, i / 0.025, i / 0.015, i / 0.055, i / 0.026])
bound = np.vstack((lb, ub)).T
res = linprog(f, A_ub=None, b_ub=None, A_eq=Aeq, b_eq=beq, bounds=bound)
y.append(-res.fun) # 由于所求的是min,所以需要添加负号得到最大的max
x = a.tolist()
# print(y)
plt.plot(x, y) # 绘制最大风险水平-最优值的二维图像
plt.xlabel("最大风险水平a")
plt.ylabel("最优值max")
plt.title("固定风险水平,优化收益")
plt.show()
4. 结果分析
最大风险水平
a
a
a与收益最优值
Q
Q
Q之间的关系如图所示。
从图中可以看出:
(1)风险越大,收益越大。看图说话第一步,xxx越大,xxx越大/小。
(2)当投资越分散时,投资者承担的风险越小,这与题意一致。冒险的投资者会出现集中投资的情况,保守的投资者则尽量分散投资。看图说话第二步,分析图像和题目所给条件是否冲突,验证正确性。
(3)在 a = 0.00579 a=0.00579 a=0.00579附近有一个转折点,在这一点左边,风险增加很少时,收益增长很快;在这一点右边,风险增加很大时,利润增长很缓慢。所以对于风险和收益没有特殊偏好的投资者来说,应该学则曲线的转折点作为最优投资组合,大约是 a = 5.79 % , Q = 19.78 % a=5.79\%,Q=19.78\% a=5.79%,Q=19.78%,所对应的投资方案为 x 0 = 2.52 % , x 1 = 23.16 % , x 2 = 38.6 % , x 3 = 10.53 % , x 4 = 22.27 % x_0=2.52\%,x_1=23.16\%,x_2=38.6\%,x_3=10.53\%,x_4=22.27\% x0=2.52%,x1=23.16%,x2=38.6%,x3=10.53%,x4=22.27%。看图说话第三步,根据转折点这些特殊的点做出相应的推荐,才能让解决这个问题具有实际意义。
模型二
- 固定投资者能接受的最小的最大收益
Q
Q
Q,优化投资风险水平
a
a
a,使
a
a
a尽可能的小(在底下的算式中,如果最大收益取
≤
\leq
≤那么不符合现实逻辑,想让风险最小收益最大,固定收益肯定是给出一个保底的数,越大越好,在此基础上风险越小越好。也可以当作结论记住,在多目标线性规划问题转换成单目标线性规划问题的过程中,需要固定的变量为
max
\max
max则取
≥
\geq
≥,需要固定的变量为
min
\min
min则取
≤
\leq
≤。)
a = min { max 0 ≤ i ≤ n { q i x i } } s . t . { ∑ i = 0 n ( r i − p i ) x i ≥ Q ∑ i = 0 n ( 1 + p i ) x i = M x i ≥ 0 , i = 0 , 1 , . . . , n a=\min\{\max\limits_{0\leq i \leq n}\{q_ix_i\}\} \\ \begin{equation} s.t. \begin{cases} \sum\limits_{i=0}^{n}(r_i-p_i)x_i \geq Q \\ \sum\limits_{i=0}^{n}(1+p_i)x_i=M\\ x_i\geq 0,&i=0,1,...,n \end{cases} \end{equation} a=min{0≤i≤nmax{qixi}}s.t.⎩ ⎨ ⎧i=0∑n(ri−pi)xi≥Qi=0∑n(1+pi)xi=Mxi≥0,i=0,1,...,n
这里令
v
=
max
0
≤
i
≤
n
{
q
i
x
i
}
v=\max\limits_{0\leq i \leq n}\{q_ix_i\}
v=0≤i≤nmax{qixi},则
a
=
min
{
v
}
s
.
t
.
{
∑
i
=
0
n
(
r
i
−
p
i
)
x
i
≥
Q
∑
i
=
0
n
(
1
+
p
i
)
x
i
=
M
x
i
≥
0
,
i
=
0
,
1
,
.
.
.
,
n
q
i
x
i
≤
v
,
i
=
0
,
1
,
.
.
.
,
n
a=\min\{v\}\\ \begin{equation} s.t. \begin{cases} \sum\limits_{i=0}^{n}(r_i-p_i)x_i \geq Q \\ \sum\limits_{i=0}^{n}(1+p_i)x_i=M\\ x_i\geq 0,&i=0,1,...,n\\ q_ix_i \leq v,&i=0,1,...,n \end{cases} \end{equation}
a=min{v}s.t.⎩
⎨
⎧i=0∑n(ri−pi)xi≥Qi=0∑n(1+pi)xi=Mxi≥0,qixi≤v,i=0,1,...,ni=0,1,...,n
将题中的信息带入上式
a
=
v
s
.
t
.
{
0.05
x
0
+
0.27
x
1
+
0.19
x
2
+
0.185
x
3
+
0.185
x
4
≥
Q
x
0
+
1.01
x
1
+
1.02
x
2
+
1.045
x
3
+
1.065
x
4
=
1
x
i
≥
0
,
i
=
0
,
1
,
.
.
.
,
n
0
≤
v
,
0.025
x
1
≤
v
,
0.015
x
2
≤
v
,
0.055
x
3
≤
v
,
0.026
x
4
≤
v
a = v \\ \begin{equation} s.t. \begin{cases} 0.05x_0+0.27x_1+0.19x_2+0.185x_3+0.185x_4 \geq Q \\ x_0+1.01x_1+1.02x_2+1.045x_3+1.065x_4=1\\ x_i\geq 0,&i=0,1,...,n\\ 0 \leq v,0.025x_1 \leq v,0.015x_2 \leq v,0.055x_3 \leq v,0.026x_4 \leq v \end{cases} \end{equation}
a=vs.t.⎩
⎨
⎧0.05x0+0.27x1+0.19x2+0.185x3+0.185x4≥Qx0+1.01x1+1.02x2+1.045x3+1.065x4=1xi≥0,0≤v,0.025x1≤v,0.015x2≤v,0.055x3≤v,0.026x4≤vi=0,1,...,n
代码如下
from scipy.optimize import linprog
import matplotlib.pyplot as plt
import numpy as np
# 解决中文显示问题
plt.rcParams["font.sans-serif"] = ["KaiTi"] # 指定默认字体
plt.rcParams["axes.unicode_minus"] = False # 解决保存图像是负号'-'显示为方块的问题
if __name__ == "__main__":
x = np.arange(0,0.27,0.00027) # 此处大致估算一下收益能达到的最大值为0.27
y=[]
f = np.array([0,0,0,0,0,1])
A = np.array([[-0.05,-0.27,-0.19,-0.185,-0.185,0],[0,0.025,0,0,0,-1],[0,0,0.015,0,0,-1],[0,0,0,0.055,0,-1],[0,0,0,0,0.026,-1]])
Aeq = np.array([[1,1.01,1.02,1.045,1.065,0]])
beq = 1
lb = np.zeros(6)
ub = np.array([[None]*6])
bound = np.vstack((lb,ub)).T
for i in x:
b = np.array([[-i, 0,0,0,0]])
res = linprog(f,A,b,Aeq,beq,bound)
y.append(res.fun)
x = x.tolist()
plt.plot(x,y)
plt.xlabel("最大收益Q")
plt.ylabel("最大风险a")
plt.title("最大收益Q-最大风险a")
plt.show()
4. 结果分析
从图中可以看出
(1)要获取更高的收益,就要承担相应的风险。
(2)想要获取更高的收益,那么就应该集中投资。冒险的投资者会选择集中投资,而保守的投资者会选择分散投资。
(3)当最大收益超过 Q = 0.20 Q=0.20 Q=0.20后,想要获取更多收益所需要面临的风险陡然增加。所以我们会建议保守的投资者们在 Q = 0.20 , a = 0.0059 Q=0.20,a=0.0059 Q=0.20,a=0.0059这一点进行投资,此时的投资方案为 x 0 = 1.07 % , x 1 = 23.5 % , x 2 = 39.17 % , x 3 = 10.68 % , x 4 = 22.6 % x_0=1.07\%,x_1=23.5\%,x_2=39.17\%,x_3=10.68\%,x_4=22.6\% x0=1.07%,x1=23.5%,x2=39.17%,x3=10.68%,x4=22.6%。
模型三
- 投资者在权衡资产风险和预期收益两方面时,希望选择一个令自己满意的投资组合。因此对风险、收益分别赋予权重 s ( 0 < s ≤ 1 ) s(0\lt s\leq 1) s(0<s≤1)和 1 − s 1-s 1−s, s s s称为投资偏好系数。
min s { max 0 ≤ i ≤ n { q i x i } } − ( 1 − s ) ∑ i = 0 n ( r i − p i ) x i s . t . { ∑ i = 0 n ( 1 + p i ) x i = M x i ≥ 0 , i = 0 , 1 , . . . , n \min\ s\{\max\limits_{0\leq i\leq n}\{q_ix_i\}\}-(1-s)\sum\limits_{i=0}^{n}(r_i-p_i)x_i \\ \begin{equation} s.t. \begin{cases} \sum\limits_{i=0}^{n}(1+p_i)x_i=M\\ x_i\geq 0,&i=0,1,...,n \end{cases} \end{equation} min s{0≤i≤nmax{qixi}}−(1−s)i=0∑n(ri−pi)xis.t.⎩ ⎨ ⎧i=0∑n(1+pi)xi=Mxi≥0,i=0,1,...,n
令
v
=
max
0
≤
i
≤
n
{
q
i
x
i
}
v=\max\limits_{0\leq i \leq n}\{q_ix_i\}
v=0≤i≤nmax{qixi},将题中信息带入
min
=
s
v
−
(
1
−
s
)
(
0.05
x
0
+
0.27
x
1
+
0.19
x
2
+
0.185
x
3
+
0.185
x
4
)
s
.
t
.
{
x
0
+
1.01
x
1
+
1.02
x
2
+
1.045
x
3
+
1.065
x
4
=
1
x
i
≥
0
,
i
=
0
,
1
,
.
.
.
,
n
0
≤
v
,
0.025
x
1
≤
v
,
0.015
x
2
≤
v
,
0.055
x
3
≤
v
,
0.026
x
4
≤
v
\min = sv-(1-s)(0.05x_0+0.27x_1+0.19x_2+0.185x_3+0.185x_4) \\ \begin{equation} s.t. \begin{cases} x_0+1.01x_1+1.02x_2+1.045x_3+1.065x_4=1\\ x_i\geq 0,&i=0,1,...,n \\ 0 \leq v,0.025x_1 \leq v,0.015x_2 \leq v,0.055x_3 \leq v,0.026x_4 \leq v \end{cases} \end{equation}
min=sv−(1−s)(0.05x0+0.27x1+0.19x2+0.185x3+0.185x4)s.t.⎩
⎨
⎧x0+1.01x1+1.02x2+1.045x3+1.065x4=1xi≥0,0≤v,0.025x1≤v,0.015x2≤v,0.055x3≤v,0.026x4≤vi=0,1,...,n
代码如下
from scipy.optimize import linprog
import matplotlib.pyplot as plt
import numpy as np
# 解决中文显示问题
plt.rcParams["font.sans-serif"] = ["KaiTi"] # 指定默认字体
plt.rcParams["axes.unicode_minus"] = False # 解决保存图像是负号'-'显示为方块的问题
if __name__ == "__main__":
s = np.arange(0, 1, 0.01)
x = []
y = []
min = []
Aeq = np.array([[1, 1.01, 1.02, 1.045, 1.065, 0]])
A = np.array(
[
[0, 0.025, 0, 0, 0, -1],
[0, 0, 0.015, 0, 0, -1],
[0, 0, 0, 0.055, 0, -1],
[0, 0, 0, 0, 0.026, -1],
]
)
b = np.array([[0, 0, 0, 0]])
beq = 1
lb = np.zeros(6)
ub = np.array([[None] * 6])
bound = np.vstack((lb, ub)).T
for i in s:
f = np.array(
[
0.05 * (i - 1),
0.27 * (i - 1),
0.19 * (i - 1),
0.185 * (i - 1),
0.185 * (i - 1),
i,
]
)
res = linprog(f, A_ub=A, b_ub=b, A_eq=Aeq, b_eq=beq, bounds=bound)
x.append(res.x[5])
y.append(
0.05 * res.x[0]
+ 0.27 * res.x[1]
+ 0.19 * res.x[2]
+ 0.185 * res.x[3]
+ 0.185 * res.x[4]
)
min.append(res.fun)
plt.plot(s, x, linestyle="dashed")
plt.plot(s, y, linestyle="dashed")
plt.plot(s, min, linestyle="dashed")
plt.legend(["s-最小风险a", "s-最大收益Q", "s-min"])
plt.xlabel("s")
plt.show()
4. 结果分析
由上图可以分析出:
(1)能够获得的最大投资收益越高,对应的投资风险也越高。
(2)如果投资者越是认为比起投资风险更应该重视投资能够获得的最大的投资收益,那么投资者最后能够获得的投资收益也越大。