最大化长期投资
导言
这个例子提出了优化长期固定收益投资组合的任务。 目标是通过将不同期限和利率的债券的收入再投资,在给定的规划范围内最大化最终资本。 该研究演示了使用线性规划方法来形式化和解决这个问题。
设置任务
让我们考虑一个投资模型,在给定的时间范围内,固定的初始资本分布在具有确定性回报的债券之间。 每种债券的特点是年资本化的固定利率和到期时累积利息收入的名义价值支付。 该模型的目标函数旨在使投资期结束时的总资本最大化。
此外,该模型可能包括对投资组合多样化的限制,该限制设定了单笔投资在配售时资本总额中的最大份额。
研究方法涉及一步一步地考虑这个问题:从一个有限的工具集的特殊情况到一个广义的公式。 问题的数学形式化是在线性规划装置的框架内实现的,这使得可以制定和解决最大化最终福祉的相应优化问题。
介绍性例子
让我们来看一个初始资本为1,000卢布,投资期限为5年的演示示例。 该模型包括四种不同特征的债券:债券1在第一年购买,期限为4年,收益率为2%;债券2在第五年购买,期限为1年,收益率为4%;债券3和4在第二年购买,
为了模拟非投资基金,引入了五种一年期零收益债券,形成了九种投资工具的等价模型。
添加必要的库和可视化功能:
import Pkg
Pkg.add(["JuMP", "HiGHS"])
using Plots, Random, JuMP, HiGHS
include("plotInvest.jl")
我们使用表示每个债券可用购买期限的水平矩形来可视化此任务。 利率债券的数量沿着这条线排列。 以年为单位的投资期列于各栏中。
# 年的时间段
Период = 5
# 债券数目
КоличествоОблигаций = 4
# 初始金额
Сумма_0 = 1000
# 购买选项总数
ВсегоВозможностейПокупки = КоличествоОблигаций + Период
# 购买期限
ГодыПокупки = [1; 2; 3; 4; 5; 1; 5; 2; 2]
# 债券期限
СрокПогашения = [1; 1; 1; 1; 1; 4; 1; 4; 3]
# 债券发售期
ГодыПогашения = ГодыПокупки .+ СрокПогашения .- 1
# 利率百分比
Проценты = [0; 0; 0; 0; 0; 2; 4; 6; 6]
# 一年后收益率,包括利息
ДоходностьЗаГод = 1 .+ Проценты ./ 100
# 任务可视化
p1 = plotInvest(КоличествоОблигаций, ГодыПокупки, СрокПогашения, Проценты)
display(p1)
可变解决方案
让我们用向量x来表示解变量,其中 -投资于债券k的卢布金额,对于k=1,。..,9. 偿还后,投资的付款 等于:
# 创建优化模型
модель = Model(HiGHS.Optimizer)
# 可变解决方案-投资金额
@variable(модель, x[1:ВсегоВозможностейПокупки] >= 0)
# 总回报
ОбщаяДоходность = ДоходностьЗаГод .^ СрокПогашения
目标功能
优化的目的是使可赎回债券的收入再投资所产生的总资本最大化。 正如图形可视化所示,在过渡期间收到的现金流量被再投资,并有助于形成最终的福利。
让我们创建一个目标函数和一个任务来最大化。
# 创建优化任务(最大化)
@objective(модель, Max, x[5] * ОбщаяДоходность[5] + x[7] * ОбщаяДоходность[7] + x[8] * ОбщаяДоходность[8])
线性约束
该模型假设每年在投资工具之间分配可用资本。 在初始阶段,种子资本被放置,在随后的时期,可赎回债券的现金流量被再投资。
让我们做一个方程组:
# 投资限制
@constraint(модель, ограничение_инвестиции1, x[1] + x[6] == Сумма_0)
@constraint(модель, ограничение_инвестиции2, x[2] + x[8] + x[9] == ДоходностьЗаГод[1] * x[1])
@constraint(модель, ограничение_инвестиции3, x[3] == ДоходностьЗаГод[2] * x[2])
@constraint(модель, ограничение_инвестиции4, x[4] == ДоходностьЗаГод[3] * x[3])
@constraint(модель, ограничение_инвестиции5, x[5] + x[7] == ДоходностьЗаГод[4] * x[4] + ОбщаяДоходность[6] * x[6] + ОбщаяДоходность[9] * x[9])
决定
我们将解决这个问题,不限制可以投资于一个债券的金额。
optimize!(модель)
решение = value.(x)
значение_целевой_функции = objective_value(модель)
解决方案的可视化
让我们展示投资回报的价值。
println("После $Период лет, доход с начальных $(Сумма_0) ₽ составит $(round(значение_целевой_функции, digits=2)) ₽")
可视化解决方案:
p2 = plotInvest(КоличествоОблигаций, ГодыПокупки, СрокПогашения, Проценты, решение)
display(p2)
有限的最佳投资
为确保投资组合多样化,该模型对单个资产的投资相对于本期总资本(包括可赎回证券的收益)的最大份额提出了限制。
# 为具有约束的问题创建模型
модель_с_ограничениями = Model(HiGHS.Optimizer)
# 约束模型的决策变量
@variable(модель_с_ограничениями, x2[1:ВсегоВозможностейПокупки] >= 0)
# 目标功能
@objective(модель_с_ограничениями, Max, x2[5] * ОбщаяДоходность[5] + x2[7] * ОбщаяДоходность[7] + x2[8] * ОбщаяДоходность[8])
# 基本投资限制
@constraint(модель_с_ограничениями, инвестиции1, x2[1] + x2[6] == Сумма_0)
@constraint(модель_с_ограничениями, инвестиции2, x2[2] + x2[8] + x2[9] == ДоходностьЗаГод[1] * x2[1])
@constraint(модель_с_ограничениями, инвестиции3, x2[3] == ДоходностьЗаГод[2] * x2[2])
@constraint(модель_с_ограничениями, инвестиции4, x2[4] == ДоходностьЗаГод[3] * x2[3])
@constraint(модель_с_ограничениями, инвестиции5, x2[5] + x2[7] == ДоходностьЗаГод[4] * x2[4] + ОбщаяДоходность[6] * x2[6] + ОбщаяДоходность[9] * x2[9])
# 投资于任何债券的最高利率
МаксПроцент = 0.6
让我们创建一个不平等的系统:
# 最大投资额的限制
@constraint(модель_с_ограничениями, лимит1, x2[1] <= МаксПроцент * Сумма_0)
@constraint(модель_с_ограничениями, лимит2, x2[2] <= МаксПроцент * (ДоходностьЗаГод[1] * x2[1] + ДоходностьЗаГод[6] * x2[6]))
@constraint(модель_с_ограничениями, лимит3, x2[3] <= МаксПроцент * (ДоходностьЗаГод[2] * x2[2] + ДоходностьЗаГод[6]^2 * x2[6] + ДоходностьЗаГод[8] * x2[8] + ДоходностьЗаГод[9] * x2[9]))
@constraint(модель_с_ограничениями, лимит4, x2[4] <= МаксПроцент * (ДоходностьЗаГод[3] * x2[3] + ДоходностьЗаГод[6]^3 * x2[6] + ДоходностьЗаГод[8]^2 * x2[8] + ДоходностьЗаГод[9]^2 * x2[9]))
@constraint(модель_с_ограничениями, лимит5, x2[5] <= МаксПроцент * (ДоходностьЗаГод[4] * x2[4] + ДоходностьЗаГод[6]^4 * x2[6] + ДоходностьЗаГод[8]^3 * x2[8] + ДоходностьЗаГод[9]^3 * x2[9]))
@constraint(модель_с_ограничениями, лимит6, x2[6] <= МаксПроцент * Сумма_0)
@constraint(модель_с_ограничениями, лимит7, x2[7] <= МаксПроцент * (ДоходностьЗаГод[4] * x2[4] + ДоходностьЗаГод[6]^4 * x2[6] + ДоходностьЗаГод[8]^3 * x2[8] + ДоходностьЗаГод[9]^3 * x2[9]))
@constraint(модель_с_ограничениями, лимит8, x2[8] <= МаксПроцент * (ДоходностьЗаГод[1] * x2[1] + ДоходностьЗаГод[6] * x2[6]))
@constraint(модель_с_ограничениями, лимит9, x2[9] <= МаксПроцент * (ДоходностьЗаГод[1] * x2[1] + ДоходностьЗаГод[6] * x2[6]))
通过有限的多样化(每个资产的最大资本的60%)解决问题表明,与无限优化相比,最终盈利能力下降。 由此产生的投资组合的可视化显示了投资流的重新分配。
# 用约束解决问题
optimize!(модель_с_ограничениями)
решение2 = value.(x2)
значение_целевой_функции2 = objective_value(модель_с_ограничениями)
让我们在考虑到限制的情况下显示收入值:
println("После $Период лет, доход с начальных $(Сумма_0) ₽ составит $(round(значение_целевой_функции2, digits=2)) ₽")
可视化解决方案:
# 具有约束的解决方案的可视化
p3 = plotInvest(КоличествоОблигаций, ГодыПокупки, СрокПогашения, Проценты, решение2)
display(p3)
自定义大小的模型
让我们继续讨论这个问题的广义表述,将模型扩展到30年的投资期限,400债券的投资组合随机回报在1-6%的范围内。 这种配置形成了具有430个变量的线性规划问题,证明了该方法对实际投资问题的适用性。
Random.seed!(123)
# 初始金额
Сумма_0_большая = 1000
# 年的时间段
Период_большой = 30
# 债券数目
КоличествоОблигаций_большое = 400
# 购买选项总数
ВсегоВозможностейПокупки_большое = КоличествоОблигаций_большое + Период_большой
# 产生随机还款期限
СрокПогашения_большой = rand(1:(Период_большой-1), ВсегоВозможностейПокупки_большое)
# 债券的到期日为1年
СрокПогашения_большой[1:Период_большой] .= 1
# 我们为每个债券生成随机年利率
Проценты_большие = rand(1:6, ВсегоВозможностейПокупки_большое)
# 债券的利率为0(未投资)
Проценты_большие[1:Период_большой] .= 0
# 一年后收益率,包括利息
ДоходностьЗаГод_большая = 1 .+ Проценты_большие ./ 100
# 计算每只债券在到期期结束时的收益率
ОбщаяДоходность_большая = ДоходностьЗаГод_большая .^ СрокПогашения_большой
# 为每个选项创建随机购买年份
ГодыПокупки_большие = zeros(Int, ВсегоВозможностейПокупки_большое)
# 这些债券每年都可以购买
ГодыПокупки_большие[1:Период_большой] = 1:Период_большой
for i in 1:КоличествоОблигаций_большое
# 生成随机年份以在T年期结束前偿还债券
ГодыПокупки_большие[i+Период_большой] = rand(1:(Период_большой - СрокПогашения_большой[i+Период_большой] + 1))
end
# 计算每只债券在年底到期的期限
ГодыПогашения_большие = ГодыПокупки_большие .+ СрокПогашения_большой .- 1
让我们形成一个投资操作的临时模型,其中矩阵 индексы_покупки_большие 和 индексы_продажи_большие 每种金融工具的开仓和平仓可接受的期限都已设定。
# 采购指数矩阵
индексы_покупки_большие = falses(ВсегоВозможностейПокупки_большое, Период_большой)
for ii in 1:Период_большой
индексы_покупки_большие[:, ii] = ГодыПокупки_большие .== ii
end
# 销售指数矩阵
индексы_продажи_большие = falses(ВсегоВозможностейПокупки_большое, Период_большой)
for ii in 1:Период_большой
индексы_продажи_большие[:, ii] = ГодыПогашения_большие .== ii
end
我们设置了对应于债券的优化变量。
модель_большая = Model(HiGHS.Optimizer)
# 可变解决方案
@variable(модель_большая, x_большой[1:ВсегоВозможностейПокупки_большое] >= 0)
让我们创建一个优化目标函数。
# 最大化的任务
@objective(модель_большая, Max, sum(x_большой[индексы_продажи_большие[:, Период_большой]] .* ОбщаяДоходность_большая[индексы_продажи_большие[:, Период_большой]]))
# 限制
@constraint(модель_большая, НачальнаяИнвестицияБольшая,
sum(x_большой[i] for i in 1:ВсегоВозможностейПокупки_большое if индексы_покупки_большие[i, 1]) == Сумма_0_большая)
for t in 2:Период_большой
@constraint(модель_большая,
sum(x_большой[i] for i in 1:ВсегоВозможностейПокупки_большое if индексы_покупки_большие[i, t]) ==
sum(x_большой[i] * ОбщаяДоходность_большая[i] for i in 1:ВсегоВозможностейПокупки_большое if индексы_продажи_большие[i, t-1]))
end
让我们解决问题:
@time optimize!(модель_большая)
решение_большое = value.(x_большой)
значение_целевой_функции_большое = objective_value(модель_большая)
投资效果如何?
println("После $Период_большой лет, доход с начальных $(Сумма_0_большая) ₽ составит $(round(значение_целевой_функции_большое, digits=2)) ₽")
有限股份的解决方案
让我们创建一个具有约束的优化问题:
# 为具有约束的问题创建模型
модель_большая_с_ограничениями = Model(HiGHS.Optimizer)
@variable(модель_большая_с_ограничениями, x_большой_с[1:ВсегоВозможностейПокупки_большое] >= 0)
@objective(модель_большая_с_ограничениями, Max,
sum(x_большой_с[i] * ОбщаяДоходность_большая[i] for i in 1:ВсегоВозможностейПокупки_большое if индексы_продажи_большие[i, Период_большой]))
# 具有约束的模型的约束
@constraint(модель_большая_с_ограничениями, НачальнаяИнвестицияБольшаяС,
sum(x_большой_с[i] for i in 1:ВсегоВозможностейПокупки_большое if индексы_покупки_большие[i, 1]) == Сумма_0_большая)
for t in 2:Период_большой
@constraint(модель_большая_с_ограничениями,
sum(x_большой_с[i] for i in 1:ВсегоВозможностейПокупки_большое if индексы_покупки_большие[i, t]) ==
sum(x_большой_с[i] * ОбщаяДоходность_большая[i] for i in 1:ВсегоВозможностейПокупки_большое if индексы_продажи_большие[i, t-1]))
end
比例模型使用多样化标准,将单一债券在投资组合中的份额限制为0.4。
МаксПроцент_большой = 0.4
多样化约束的形式化需要构建两个数据结构:债券活动矩阵和当前价值矩阵,在此基础上确定投资组合中单个资产份额的上限。
активные_большие = falses(ВсегоВозможностейПокупки_большое, Период_большой)
for ii in 1:Период_большой
активные_большие[:, ii] = (ii .>= ГодыПокупки_большие) .& (ii .<= ГодыПогашения_большие)
end
我们将对最大投资设定限制。:
# 最大投资额的限制
for i in 1:ВсегоВозможностейПокупки_большое
for t in 1:Период_большой
if индексы_покупки_большие[i, t]
if t == 1
@constraint(модель_большая_с_ограничениями, x_большой_с[i] <= МаксПроцент_большой * Сумма_0_большая)
else
@constraint(модель_большая_с_ограничениями, x_большой_с[i] <= МаксПроцент_большой *
sum(x_большой_с[j] * (ДоходностьЗаГод_большая[j] ^ sum(активные_большие[j, 1:(t-1)]))
for j in 1:ВсегоВозможностейПокупки_большое if активные_большие[j, t-1]))
end
end
end
end
解决问题:
@time optimize!(модель_большая_с_ограничениями)
решение_большое_с_ограничениями = value.(x_большой_с)
значение_целевой_функции_большое_с_ограничениями = objective_value(модель_большая_с_ограничениями)
println("\nПосле $Период_большой лет, доход с начальных $(Сумма_0_большая) ₽ составит $(round(значение_целевой_функции_большое_с_ограничениями, digits=2)) ₽")
结果的定性分析
为了评估最佳投资组合的有效性,最好将其盈利能力与理论最大值进行比较-在整个30年期间,所有资本投资于最高利率为6%的债券。 分析的另一个指标可以是计算与所达到的最终福利水平相对应的等效年率。
# 最大可能金额
максимальная_сумма = Сумма_0_большая * (1 + 6/100)^Период_большой
# 比率(百分比)
отношение = значение_целевой_функции_большое_с_ограничениями / максимальная_сумма * 100
# 等值利率
эквивалентная_ставка = ((значение_целевой_функции_большое_с_ограничениями / Сумма_0_большая)^(1/Период_большой) - 1) * 100
println("\nПолученная сумма составит $(round(отношение, digits=2))% от максимальной суммы $(round(максимальная_сумма, digits=2)) ₽,")
println("这可以通过投资一个债券来获得。")
println("\nВаш доход соответствует $(round(эквивалентная_ставка, digits=2))% годовой ставке за $(Период_большой)-летний период.")
# 可视化结果
p4 = plotInvest(КоличествоОблигаций_большое, ГодыПокупки_большие, СрокПогашения_большой, Проценты_большие, решение_большое_с_ограничениями, false)
display(p4)
图表显示了有限制的投资组合的时间结构:
*水平绿线-选定债券
*行首为购买年份,行尾为还款年份
*大括号{i}中的数字是键标识符
*自上而下的位置-投资优先
该图表显示了一个多元化的投资组合,其中投资按照每项资产不超过60%的限制分布在不同的年份和时期。
结论
所进行的研究证明了线性规划方法优化长期投资组合的有效性。 开发的模型可以确定在给定时间范围内最大限度地提高最终福祉的资本配置策略。
实验计算证实了多样化和盈利能力之间存在折衷:对一种资产份额的60%限制的引入与无限优化相比,最终收益率降低了4.3%。 该方法的可扩展性在具有30年期限和400债券组合的任务上得到验证。
未来研究的方向是考虑到盈利能力的不确定性,并在不断变化的市场条件下创建动态投资组合优化算法。
.png)
.png)
.png)
.png)