参考02:非线性规划

配套R编程文件

特别说明

教材《第8章,非线性最优化模型》,提供了一些非线性规划的案例,但是求解过程使用了我们不熟悉的LINGO编程语言。

由于管理科学家软件MST6的编程软件没有提供非线性规划的编程,这里我们提供一些非线性规划的功能模块,因此这里我提供了使用开源R编程语言的代码文件,供大家参考。

非线性规划的R包:在R语言中,非线性规划的求解可以通过nloptr包来实现。

1 Hauck基金公司案例背景

指数化基金一般会针对特定的市场指数:

  • 前两个指数基金是股票投资型:对应标准普尔500指数和MSCI广泛市场指数

  • REIT指数化基金主要是紧盯房地市场上的投资,对应MSCI REIT市场指数

  • 短基债券指数化基金主要在公司偾券市场上投资,对应Barclays US 1-5市场指数

  • 即使收益显示基金间有相当大的变化,指数化基金在匹配对应市场指数的收益上依然表现很好。

2 案例数据

共同基金 投资比例变量 Year01 Year02 Year03 Year04 Year05
外国股票 FS 10.06% 13.12% 13.47% 45.42% -21.93%
中期债券 IB 17.64% 3.25% 7.51% -1.33% 7.36%
大市值成长 LG 32.41% 18.71% 33.28% 41.46% -23.26%
大市值价值 LV 32.36% 20.61% 12.93% 7.06% -5.37%
小市值成长 SG 33.44% 19.40% 3.85% 58.68% -9.02%
小市值价值 SV 24.56% 25.32% -6.70% 5.43% 17.31%
标准普尔500收益 SP 25.00% 20.00% 8.00% 30.00% -10.00%

其中:

  • 投资比例变量,用来表达在相应基金上的投资配置比重(%)。

  • 标准普尔500收益仅作为投资的收益参照。

3 策略1:简单二次方非线性规划

3.1 投资组合策略

投资目标:我们想要通过选择投资组合投资于每个共有基金的比例,以尽可能地接近标准普尔500的回报。

  • 给定6种基金选择 \(i \in (1,2,3,4,5,6)\),和5个年度方案 \(n \in (1,2,3,4,5)\)

  • 给定五种基金的投资比率分别为: \(c_i = \{FS, IB, LG, LV, SG, SV\}= \{c_1, c_2, c_3, c_4,c_5\}\)

  • 给定年度计划下6种基金的收益为(见上表): \(r_{ni} = \{r_{n1}, r_{n2},r_{n3},r_{n4},r_{n5},r_{n6}\}\)

  • 每一年度方案的投资组合的回报 \(R_n=\{R1,R2,R3,R4,R5\}\)

那么,年度方案的投资组合回报则为:

\[ \begin{align} R_n = \sum_{i=1}^{6}{r_{ni}c_i} = r_{n1}\cdot FS + r_{n2}\cdot IB + r_{n3}\cdot LG + r_{n4}\cdot SG + r_{n5}\cdot SV \end{align} \]

年度方案的投资组合回报计算公式:

\[ \begin{align} R_n = \sum_{i=1}^{6}{r_{ni}c_i} = r_{n1}\cdot FS + r_{n2}\cdot IB + r_{n3}\cdot LG + r_{n4}\cdot SG + r_{n5}\cdot SV \end{align} \]

根据前述年度方案表,可以得到每年的投资组合回报 \(R_n\)分别为\((n \in 1,\ldots,5)\)

\[ \begin{align} R_1 = +10.06FS +17.64IB +32.41LG +32.36LV +33.44SG +24.56SV \end{align} \]

\[ \begin{align} R_2 = +13.12FS +3.25IB +18.71LG +20.61LV +19.40SG +25.32SV \end{align} \]

\[ \begin{align} R_3 = +13.47FS +7.51IB +33.28LG +12.93LV +3.85SG -6.70SV \end{align} \]

\[ \begin{align} R_4 = +45.42FS -1.33IB +41.46LG +7.06LV +58.68SG +5.43SV \end{align} \]

\[ \begin{align} R_5 = -21.93FS +7.36IB -23.26LG -5.37LV -9.02SG +17.31SV \end{align} \]

3.2 非线性规划模型

为了达到投资组合的回报尽可能接近标准普尔500的回报,要求每个年度投资收益方案回报和标准普尔500的回报间的差值,尽可能最小化。

考虑设置为非线性最小化目标函数:

\[ \begin{align} \textrm{Min}\quad (R_1-25.00)^2 + (R_2-20.00)^2 + (R_3-8.00)^2 + (R_4-30.00)^2 + (R_5+10.00)^2 \end{align} \]

最终,我们建立的完整的数学模型包括11个变量和6个约束条件:

\[ \begin{align} \textrm{Min}\quad (R_1-25.00)^2 + (R_2-20.00)^2 + (R_3-8.00)^2 + (R_4-30.00)^2 + (R_5+10.00)^2 \end{align} \]

s.t.

\[ \begin{align} R_1 = +10.06FS +17.64IB +32.41LG +32.36LV +33.44SG +24.56SV \\ R_2 = +13.12FS +3.25IB +18.71LG +20.61LV +19.40SG +25.32SV \\ R_3 = +13.47FS +7.51IB +33.28LG +12.93LV +3.85SG -6.70SV \\ R_4 = +45.42FS -1.33IB +41.46LG +7.06LV +58.68SG +5.43SV \\ R_5 = -21.93FS +7.36IB -23.26LG -5.37LV -9.02SG +17.31SV\\ FS + IB + LG + LV + SG + SV=1\\ FS, IB, LG, LV, SG, SV \geq 0 \end{align} \]

上述约束模型特点:

  • 最小化问题是非线性的,因为目标函数中出现了二次项。

  • 因为每个平方项的系数是正的,并且没有交叉乘积项,所以目标函数是凸函数。

  • 因此可以保证局部最小值也是整体最小值。

下面我们将使用R编程语言进行求解。

3.3 非线性规划的R求解过程

我们先展示R求解的求解结果,然后展示求解R代码。

3.3.1 求解结果

  1. 最优投资组合配置
最优投资组合配置
Fund Weight
外国股票(FS) 0.30334
中期债券(IB) 0.00000
大市值成长(LG) 0.00000
大市值价值(LV) 0.36498
小市值成长(SG) 0.22655
小市值价值(SV) 0.10513
  1. 年度回报对比
年度回报对比
Year Portfolio_Return SP500_Return
1 25.02024% 25
2 18.55903% 20
3 8.97303% 8
4 30.21927% 30
5 -8.83586% -10
  1. 目标函数的最优值
[1] "4.42689%"

3.3.2 求解R代码命令行

以下展示的是所有求解的R代码命令行。

Show the code
# Hauck基金公司案例:非线性规划求解
# 目标:通过选择投资组合投资于每个共有基金的比例,以尽可能地接近标准普尔500的回报

## 加载必要的包----
if (!require("nloptr")) install.packages("nloptr")
library(nloptr)

## 定义目标函数----
eval_f <- function(x) {
  # 提取决策变量
  FS <- x[1]; IB <- x[2]; LG <- x[3]; LV <- x[4]; SG <- x[5]; SV <- x[6]
  
  # 计算每年的投资组合回报
  R1 <- 0.1006*FS + 0.1764*IB + 0.3241*LG + 0.3236*LV + 0.3344*SG + 0.2456*SV
  R2 <- 0.1312*FS + 0.0325*IB + 0.1871*LG + 0.2061*LV + 0.1940*SG + 0.2532*SV
  R3 <- 0.1347*FS + 0.0751*IB + 0.3328*LG + 0.1293*LV + 0.0385*SG - 0.0670*SV
  R4 <- 0.4542*FS - 0.0133*IB + 0.4146*LG + 0.0706*LV + 0.5868*SG + 0.0543*SV
  R5 <- -0.2193*FS + 0.0736*IB - 0.2326*LG - 0.0537*LV - 0.0902*SG + 0.1731*SV
  
  # 计算目标函数值(与标准普尔500收益的差距平方和)
  obj <- (R1 - 0.25)^2 + (R2 - 0.20)^2 + (R3 - 0.08)^2 + 
         (R4 - 0.30)^2 + (R5 + 0.10)^2
  
  return(obj)
}

## 定义目标函数的梯度----
eval_grad_f <- function(x) {
  # 提取决策变量
  FS <- x[1]; IB <- x[2]; LG <- x[3]; LV <- x[4]; SG <- x[5]; SV <- x[6]
  
  # 计算每年的投资组合回报与目标的差距
  R1 <- 0.1006*FS + 0.1764*IB + 0.3241*LG + 0.3236*LV + 0.3344*SG + 0.2456*SV - 0.25
  R2 <- 0.1312*FS + 0.0325*IB + 0.1871*LG + 0.2061*LV + 0.1940*SG + 0.2532*SV - 0.20
  R3 <- 0.1347*FS + 0.0751*IB + 0.3328*LG + 0.1293*LV + 0.0385*SG - 0.0670*SV - 0.08
  R4 <- 0.4542*FS - 0.0133*IB + 0.4146*LG + 0.0706*LV + 0.5868*SG + 0.0543*SV - 0.30
  R5 <- -0.2193*FS + 0.0736*IB - 0.2326*LG - 0.0537*LV - 0.0902*SG + 0.1731*SV + 0.10
  
  # 计算梯度
  grad <- c(
    2*(0.1006*R1 + 0.1312*R2 + 0.1347*R3 + 0.4542*R4 - 0.2193*R5),  # dF/dFS
    2*(0.1764*R1 + 0.0325*R2 + 0.0751*R3 - 0.0133*R4 + 0.0736*R5),  # dF/dIB
    2*(0.3241*R1 + 0.1871*R2 + 0.3328*R3 + 0.4146*R4 - 0.2326*R5),  # dF/dLG
    2*(0.3236*R1 + 0.2061*R2 + 0.1293*R3 + 0.0706*R4 - 0.0537*R5),  # dF/dLV
    2*(0.3344*R1 + 0.1940*R2 + 0.0385*R3 + 0.5868*R4 - 0.0902*R5),  # dF/dSG
    2*(0.2456*R1 + 0.2532*R2 - 0.0670*R3 + 0.0543*R4 + 0.1731*R5)   # dF/dSV
  )
  
  return(grad)
}

## 定义约束条件----
eval_g <- function(x) {
  # 所有投资比例之和等于1的约束
  return(sum(x) - 1)
}

## 定义约束条件的梯度----
eval_grad_g <- function(x) {
  # 约束条件 sum(x) - 1 = 0 的梯度
  return(rep(1, 6))
}

## 设置初始值和边界条件----
x0 <- rep(1/6, 6)  # 初始均匀分配
lb <- rep(0, 6)    # 下界
ub <- rep(1, 6)    # 上界

## 使用 nloptr 求解----
result <- nloptr(
  x0 = x0,  # 初始值
  eval_f = eval_f,  # 目标函数
  eval_grad_f = eval_grad_f,  # 目标函数的梯度
  lb = lb,  # 下界
  ub = ub,  # 上界
  eval_g_eq = eval_g,  # 约束条件
  eval_jac_g_eq = eval_grad_g,  # 约束条件的梯度
  opts = list(
    "algorithm" = "NLOPT_LD_SLSQP",  # 算法
    "xtol_rel" = 1.0e-8,  # 相对误差
    "maxeval" = 1000  # 最大迭代次数
  )
)

## 创建最优解数据框----
optimal_solution <- data.frame(
  Fund = c("外国股票(FS)", "中期债券(IB)", "大市值成长(LG)", 
           "大市值价值(LV)", "小市值成长(SG)", "小市值价值(SV)"),
  Weight = result$solution
)

## 计算最优投资组合下的年度回报----
x_opt <- result$solution
FS <- x_opt[1]; IB <- x_opt[2]; LG <- x_opt[3]
LV <- x_opt[4]; SG <- x_opt[5]; SV <- x_opt[6]

## 计算每年的回报率----
R1 <- 0.1006*FS + 0.1764*IB + 0.3241*LG + 0.3236*LV + 0.3344*SG + 0.2456*SV
R2 <- 0.1312*FS + 0.0325*IB + 0.1871*LG + 0.2061*LV + 0.1940*SG + 0.2532*SV
R3 <- 0.1347*FS + 0.0751*IB + 0.3328*LG + 0.1293*LV + 0.0385*SG - 0.0670*SV
R4 <- 0.4542*FS - 0.0133*IB + 0.4146*LG + 0.0706*LV + 0.5868*SG + 0.0543*SV
R5 <- -0.2193*FS + 0.0736*IB - 0.2326*LG - 0.0537*LV - 0.0902*SG + 0.1731*SV

## 创建年度回报对比表----
annual_returns <- data.frame(
  Year = 1:5,
  Portfolio_Return = 100*c(R1, R2, R3, R4, R5),  # 转换为百分比
  SP500_Return = c(25, 20, 8, 30, -10)  # 标准普尔500收益率(百分比)
)

## 计算目标函数的最优值----
optimal_value <- eval_f(result$solution)*100  # 转换为百分比

# 注释掉打印语句
# print("最优投资组合配置:")
# print(optimal_solution)
# print("\n年度回报对比:")
# print(annual_returns)
# print(paste("目标函数的最优值:", scales::percent(optimal_value, accuracy=0.000001))) 

4 策略2:考虑期望和风险的非线性规划

4.1 markowitz投资组合模型

基于上一节Hauck公司的共同基金投资组合案例,我们进一步建立Markowitz均方差投资组合模型。

(1)考虑期望收益:

  • 给定年度投资方案的回报为 \(R_s\),方案被选中的概率为 \(p_s\),其中 \(s \in (1, 2 , \ldots,n)\)。那么 n个方案的投资组合的期望收益是:

\[ \overline{R} = \sum_{s=1}^n{p_s}R_s \]

  • 假定Hack金融服务公司中,5个计划方案有相同的选中概率,则

\[ \overline{R} = \sum_{s=1}^5{1/5R_s} = 1/5\sum_{s=1}^5{R_s} \]

(2)考虑风险测量:

要想衡量上述投资组合的风险大小,这往往具有一定的测量难度。Markowitz投资组合模型最常用的风险测量是投资组合的方差

\[ \begin{align} \operatorname{Var}&=\sum_{s=1}^{n} p_{s}\left(R_{s}-\overline{R}\right)^{2} \\ \operatorname{Var}&=\sum_{s=1}^{n} 1/5\left(R_{s}-\overline{R}\right)^{2} = 1/5 \sum_{s=1}^{n} \left(R_{s}-\overline{R}\right)^{2} \end{align} \]

  • 假定Hauck的客户想要构建一个投资组合,来最小化由投资组合方差测量的风险。而且客户还要求预期的投资收益至少为10%。

  • 此时该如何构建分析模型?

4.2 非线性规划模型

\[ \begin{align} Min \quad f=1/5 \sum_{s=1}^{5} \left(R_{s}-\overline{R}\right)^{2} \end{align} \]

s.t.

\[ \begin{align} R_1 = +10.06FS +17.64IB +32.41LG +32.36LV +33.44SG +24.56SV\\ R_2 = +13.12FS +3.25IB +18.71LG +20.61LV +19.40SG +25.32SV\\ R_3 = +13.47FS +7.51IB +33.28LG +12.93LV +3.85SG -6.70SV\\ R_4 = +45.42FS -1.33IB +41.46LG +7.06LV +58.68SG +5.43SV\\ R_5 = -21.93FS +7.36IB -23.26LG -5.37LV -9.02SG +17.31SV\\ FS + IB + LG + LV + SG + SV=1\\ FS, IB, LG, LV, SG, SV \geq 0\\ 1/5 \sum_{s=1}^{5} {R_{s}}=\overline{R}\\ \overline{R}\geq10 \end{align} \]

4.3 非线性规划的R求解过程

我们先展示R求解的求解结果,然后展示求解R代码。

4.3.1 求解结果

  1. 最优投资组合配置(权重):
最优投资组合配置
Fund Weight
外国股票(FS) 0.15841
中期债券(IB) 0.52548
大市值成长(LG) 0.04207
大市值价值(LV) 0.00000
小市值成长(SG) 0.00000
小市值价值(SV) 0.27405
  1. 年度回报对比
年度回报对比
Year Portfolio_Return
1 18.95698%
2 11.51205%
3 5.64390%
4 9.72807%
5 4.15899%
平均收益R 10.00000%
  1. 最优目标函数值(投资组合方差)
[1] "0.2713615"

4.3.2 求解R代码命令行

以下展示的是所有求解的R代码命令行。

Show the code
# Markowitz投资组合模型:考虑期望收益和风险的非线性规划
# 目标:在满足最小期望收益要求下,最小化投资组合的方差

## 加载必要的包----
if (!require("nloptr")) install.packages("nloptr")
library(nloptr)
library(scales)

## 定义目标函数(投资组合方差)----
eval_f <- function(x) {
  # 提取决策变量
  FS <- x[1]; IB <- x[2]; LG <- x[3]; LV <- x[4]; SG <- x[5]; SV <- x[6]
  
  # 计算每年的投资组合回报
  R1 <- 0.1006*FS + 0.1764*IB + 0.3241*LG + 0.3236*LV + 0.3344*SG + 0.2456*SV
  R2 <- 0.1312*FS + 0.0325*IB + 0.1871*LG + 0.2061*LV + 0.1940*SG + 0.2532*SV
  R3 <- 0.1347*FS + 0.0751*IB + 0.3328*LG + 0.1293*LV + 0.0385*SG - 0.0670*SV
  R4 <- 0.4542*FS - 0.0133*IB + 0.4146*LG + 0.0706*LV + 0.5868*SG + 0.0543*SV
  R5 <- -0.2193*FS + 0.0736*IB - 0.2326*LG - 0.0537*LV - 0.0902*SG + 0.1731*SV
  
  # 计算期望收益
  R_mean <- (R1 + R2 + R3 + R4 + R5) / 5
  
  # 计算方差
  variance <- ((R1 - R_mean)^2 + (R2 - R_mean)^2 + (R3 - R_mean)^2 + 
               (R4 - R_mean)^2 + (R5 - R_mean)^2) / 5
  
  return(variance)
}

## 定义目标函数的梯度----
eval_grad_f <- function(x) {
  # 提取决策变量
  FS <- x[1]; IB <- x[2]; LG <- x[3]; LV <- x[4]; SG <- x[5]; SV <- x[6]
  
  # 计算每年的投资组合回报
  R1 <- 0.1006*FS + 0.1764*IB + 0.3241*LG + 0.3236*LV + 0.3344*SG + 0.2456*SV
  R2 <- 0.1312*FS + 0.0325*IB + 0.1871*LG + 0.2061*LV + 0.1940*SG + 0.2532*SV
  R3 <- 0.1347*FS + 0.0751*IB + 0.3328*LG + 0.1293*LV + 0.0385*SG - 0.0670*SV
  R4 <- 0.4542*FS - 0.0133*IB + 0.4146*LG + 0.0706*LV + 0.5868*SG + 0.0543*SV
  R5 <- -0.2193*FS + 0.0736*IB - 0.2326*LG - 0.0537*LV - 0.0902*SG + 0.1731*SV
  
  # 计算期望收益
  R_mean <- (R1 + R2 + R3 + R4 + R5) / 5
  
  # 计算梯度
  grad <- c(
    2/5 * (0.1006*(R1-R_mean) + 0.1312*(R2-R_mean) + 0.1347*(R3-R_mean) + 
           0.4542*(R4-R_mean) - 0.2193*(R5-R_mean)),
    2/5 * (0.1764*(R1-R_mean) + 0.0325*(R2-R_mean) + 0.0751*(R3-R_mean) - 
           0.0133*(R4-R_mean) + 0.0736*(R5-R_mean)),
    2/5 * (0.3241*(R1-R_mean) + 0.1871*(R2-R_mean) + 0.3328*(R3-R_mean) + 
           0.4146*(R4-R_mean) - 0.2326*(R5-R_mean)),
    2/5 * (0.3236*(R1-R_mean) + 0.2061*(R2-R_mean) + 0.1293*(R3-R_mean) + 
           0.0706*(R4-R_mean) - 0.0537*(R5-R_mean)),
    2/5 * (0.3344*(R1-R_mean) + 0.1940*(R2-R_mean) + 0.0385*(R3-R_mean) + 
           0.5868*(R4-R_mean) - 0.0902*(R5-R_mean)),
    2/5 * (0.2456*(R1-R_mean) + 0.2532*(R2-R_mean) - 0.0670*(R3-R_mean) + 
           0.0543*(R4-R_mean) + 0.1731*(R5-R_mean))
  )
  
  return(grad)
}

## 定义约束条件----
eval_g <- function(x) {
  # 提取决策变量
  FS <- x[1]; IB <- x[2]; LG <- x[3]; LV <- x[4]; SG <- x[5]; SV <- x[6]
  
  # 计算每年的投资组合回报
  R1 <- 0.1006*FS + 0.1764*IB + 0.3241*LG + 0.3236*LV + 0.3344*SG + 0.2456*SV
  R2 <- 0.1312*FS + 0.0325*IB + 0.1871*LG + 0.2061*LV + 0.1940*SG + 0.2532*SV
  R3 <- 0.1347*FS + 0.0751*IB + 0.3328*LG + 0.1293*LV + 0.0385*SG - 0.0670*SV
  R4 <- 0.4542*FS - 0.0133*IB + 0.4146*LG + 0.0706*LV + 0.5868*SG + 0.0543*SV
  R5 <- -0.2193*FS + 0.0736*IB - 0.2326*LG - 0.0537*LV - 0.0902*SG + 0.1731*SV
  
  # 计算期望收益
  R_mean <- (R1 + R2 + R3 + R4 + R5) / 5
  
  # 返回约束条件
  return(c(
    sum(x) - 1,           # 投资比例之和等于1
    R_mean - 0.10         # 期望收益至少为10%
  ))
}

## 定义约束条件的雅可比矩阵----
eval_jac_g <- function(x) {
  # 提取决策变量
  FS <- x[1]; IB <- x[2]; LG <- x[3]; LV <- x[4]; SG <- x[5]; SV <- x[6]
  
  # 计算期望收益对各变量的偏导数
  # 正确计算:考虑所有五年的收益情况
  dR_mean <- c(
    (0.1006 + 0.1312 + 0.1347 + 0.4542 - 0.2193) / 5,  # FS的偏导数
    (0.1764 + 0.0325 + 0.0751 - 0.0133 + 0.0736) / 5,  # IB的偏导数
    (0.3241 + 0.1871 + 0.3328 + 0.4146 - 0.2326) / 5,  # LG的偏导数
    (0.3236 + 0.2061 + 0.1293 + 0.0706 - 0.0537) / 5,  # LV的偏导数
    (0.3344 + 0.1940 + 0.0385 + 0.5868 - 0.0902) / 5,  # SG的偏导数
    (0.2456 + 0.2532 - 0.0670 + 0.0543 + 0.1731) / 5   # SV的偏导数
  )
  
  # 返回雅可比矩阵
  return(rbind(
    rep(1, 6),           # 投资比例之和的梯度
    dR_mean              # 期望收益的梯度
  ))
}

## 设置初始值和边界条件----
x0 <- rep(1/6, 6)  # 初始均匀分配
lb <- rep(0, 6)    # 下界
ub <- rep(1, 6)    # 上界

## 使用 nloptr 求解----
result <- nloptr(
  x0 = x0, # 初始值
  eval_f = eval_f, # 目标函数
  eval_grad_f = eval_grad_f, # 目标函数的梯度
  lb = lb, # 下界
  ub = ub, # 上界
  eval_g_eq = eval_g, # 约束条件
  eval_jac_g_eq = eval_jac_g, # 约束条件的雅可比矩阵
  opts = list(
    "algorithm" = "NLOPT_LD_SLSQP", # 算法
    "xtol_rel" = 1.0e-8, # 相对误差
    "maxeval" = 1000 # 最大迭代次数
  )
)

## 创建最优解数据框----
optimal_solution <- data.frame(
  Fund = c("外国股票(FS)", "中期债券(IB)", "大市值成长(LG)", 
           "大市值价值(LV)", "小市值成长(SG)", "小市值价值(SV)"),
  Weight = result$solution
)

## 计算最优投资组合下的年度回报----
x_opt <- result$solution
FS <- x_opt[1]; IB <- x_opt[2]; LG <- x_opt[3]
LV <- x_opt[4]; SG <- x_opt[5]; SV <- x_opt[6]

## 计算每年的回报率----
R1 <- 0.1006*FS + 0.1764*IB + 0.3241*LG + 0.3236*LV + 0.3344*SG + 0.2456*SV
R2 <- 0.1312*FS + 0.0325*IB + 0.1871*LG + 0.2061*LV + 0.1940*SG + 0.2532*SV
R3 <- 0.1347*FS + 0.0751*IB + 0.3328*LG + 0.1293*LV + 0.0385*SG - 0.0670*SV
R4 <- 0.4542*FS - 0.0133*IB + 0.4146*LG + 0.0706*LV + 0.5868*SG + 0.0543*SV
R5 <- -0.2193*FS + 0.0736*IB - 0.2326*LG - 0.0537*LV - 0.0902*SG + 0.1731*SV

## 计算期望收益和方差----
R_mean <- (R1 + R2 + R3 + R4 + R5) / 5
variance <- 100*((R1 - R_mean)^2 + (R2 - R_mean)^2 + (R3 - R_mean)^2 + 
             (R4 - R_mean)^2 + (R5 - R_mean)^2) / 5

## 创建年度回报表----
annual_returns <- data.frame(
  Year = 1:5,
  Portfolio_Return = c(R1, R2, R3, R4, R5)  # 收益水平
  )|>  
  # 更改year为character
  mutate(Year = as.character(Year)) |>
  # 最后一行添加平均收益
  bind_rows(
    data.frame(Year = "平均收益R", Portfolio_Return = R_mean)
  )

## 注释掉打印语句----
# print("最优投资组合配置(权重):")
# print(optimal_solution)
# print("\n年度回报:")
# print(annual_returns |> mutate(Portfolio_Return =  scales::percent(Portfolio_Return, accuracy=0.00001)))
# print(paste("期望收益率:", scales::percent(R_mean, accuracy=0.01)))
# print(paste(最优目标函数值(投资组合方差):", scales::percent(variance, accuracy=0.01))) "