利用线性规划最大化长期投资:基于问题
这个例子展示了如何使用基于问题的方法来解决在固定年限内具有确定性回报的投资问题T
.问题是如何将你的钱分配到可投资项目中,以最大化你最终的财富。有关基于求解器的方法,请参见利用线性规划最大化长期投资:基于求解器.
问题公式化
假设你有一笔初始的钱Capital_0
在…的一段时间内投资T
年N
零息债券。每只债券支付固定利率,每年对投资进行复利,并在到期日结束时支付本金和复利。目标是使之后的总金额最大化T
年。
你可以设置一个限制条件,即任何一项投资都不能超过投资时总资本的某一部分。
这个例子首先展示了在一个小案例上的问题设置,然后阐述了一般的案例。
你可以把它建模成一个线性规划问题。因此,要优化你的财富,请使用优化问题方法来制定问题。
介绍性的例子
从一个小例子开始:
投资的起始金额
Capital_0
是1000美元。时间段
T
是5年。化学键的数量
N
是4。为了模拟未投资的资金,每年有一个期权B0,期限为1年,利率为0%。
债券1用B1表示,可在第1年购买,期限为4年,利率为2%。
债券2,记为B2,可在第5年购买,期限为1年,利率为4%。
债券3记B3,可在第2年购买,期限为4年,利率为6%。
债券4,记为B4,可在第2年购买,期限为3年,利率为6%。
通过将第一个期权B0拆分为5个期限为1年,利率为0%的债券,这个问题可以等效地建模为总共有9个可用债券,例如k = 1 . . 9
条目
k
的向量PurchaseYears
代表年初的债券k
可供购买。条目
k
的向量成熟
表示到期日 的债券k
.条目
k
的向量MaturityYears
代表这个债券的年底k
可供出售。条目
k
的向量银行利率
表示百分比利率 的债券k
.
通过表示每个债券的可用购买时间和期限的水平条来可视化这个问题。
%以年为单位的时间段T = 5;%键数N = 4;初始金额Capital_0 = 1000;%购买机会总数nPtotal = N+T;%购买次数PurchaseYears = [1;2;3;4;5;1;5;2;2];%债券期限成熟度= [1;1;1;1;1;4;1;4;3];%债券销售次数到期日=购买日+到期日- 1;以百分比表示的利率利息= [0;0;0;0;2;4;6;6];一年后返还rt = 1 +利息/100;plotInvestments (N, PurchaseYears,成熟,利率)
决策变量
用向量表示你的决策变量x
,在那里x (k)
投资金额是债券吗k
,因为K = 1,…,9
.到期后,用于投资的支付x (k)
是
定义
和定义
作为债券的总回报k
:
X = optimvar(“x”nPtotal,下界的, 0);总回报率%r = rt.^成熟度;
目标函数
目标是选择投资,以最大限度地在年底筹集到的钱T
.从图中可以看出,投资是在不同的中间年收集并进行再投资。在年底T
,投资5、7和8的回报可以收集,代表你的最终财富:
创建一个最大化的优化问题,并包括目标函数。
Interestprob = optimproblem(“ObjectiveSense”,“最大化”);interestprob。目标= x(5)*r(5) + x(7)*r(7) + x(8)*r(8);
线性约束:投资不要超过你所拥有的
每年,你都有一定数量的钱可以用来购买债券。从第1年开始,您可以将初始资本投资于购买期权 而且 ,所以:
然后在接下来的几年里,你从到期债券中获得回报,并将它们再投资于新的可用债券,从而得到如下方程组:
investconstr = optimconstr(T,1);investconstr(1) = x(1) + x(6) == Capital_0;investconstr (2) = x (2) + (8) + x (9) = = r (1) * x (1);Investconstr (3) = x(3) == r(2)*x(2);Investconstr (4) = x(4) == r(3)*x(3);investconstr (5) = (5) + x (7) = = r (4) * x (4) + r (6) * x (6) + r (9) * x (9);interestprov . constraints .investconstr = investconstr;
约束条件:不借款
因为投入的每一项都必须是正的,解向量中的每一项 肯定是积极的。通过在解向量上设置一个下界来包含这个约束 .解向量没有明确的上界。
x.LowerBound = 0;
解决问题
解决这个问题时,不限制你在债券上的投资金额。内点算法可用于求解这类线性规划问题。
选项= optimoptions(“linprog”,“算法”,“内点”);[sol,fval,exitflag] = solve(兴趣问题,“选项”选项)
用linprog解决问题。预溶过程中发现的溶液。
索尔=带字段的结构:X: [9x1 double]
Fval = 1.2625e+03
exitflag = OptimalSolution
可视化解决方案
退出标志表示求解器找到了最优解。的值fval
,作为第二个输出参数返回,对应于最终的财富。看看最终的投资总额,以及一段时间内的投资配置。
流('在%d年后,初始$%g的回报为$%g \n',...T Capital_0 fval);
5年后,最初1000美元的回报是1262.48美元
plotInvestments (N, PurchaseYears、成熟度、利率、sol.x)
有限公司最佳投资
为了使你的投资多样化,你可以选择将任何一种债券的投资金额限制在一定的百分比Pmax
占当年总资本的比例(包括目前到期债券的收益)。你会得到以下不等式系统:
投资任何债券的最大百分比Pmax = 0.6;constrlimit = optimconstr(nPtotal,1);constrlimit(1) = x(1) <= Pmax*Capital_0;constrlimit (2) = x (2) < = Pmax * (rt (1) * x (1) + rt (6) * x (6));constrlimit (3) = x (3) < = Pmax * (rt (2) * x (2) + rt (6) ^ 2 * x (6) + rt (8) * * (8) + rt (9) * x (9));constrlimit (4) = x (4) < = Pmax * (rt (3) * x (3) + rt (6) ^ 3 * x (6) + rt (8) ^ 2 * x (8) + rt (9) ^ 2 * x (9));constrlimit (5) = x (5) < = Pmax * (rt (4) * x (4) + rt (6) ^ 4 * x (6) + rt (8) ^ 3 * x (8) + rt (9) ^ 3 * x (9));constrlimit(6) = x(6) <= Pmax*Capital_0;constrlimit (7) = x (7) < = Pmax * (rt (4) * x (4) + rt (6) ^ 4 * x (6) + rt (8) ^ 3 * x (8) + rt (9) ^ 3 * x (9));constrlimit (8) = x (8) < = Pmax * (rt (1) * x (1) + rt (6) * x (6)); constrlimit(9) = x(9) <= Pmax*(rt(1)*x(1) + rt(6)*x(6)); interestprob.Constraints.constrlimit = constrlimit;
解决这个问题的方法是在任何一项资产上的投资不超过60%。画出最终的购买量。注意,你最终的财富比没有这个约束的投资要少。
[sol,fval] = solve(兴趣问题,“选项”、选择);
用linprog解决问题。最小值满足约束条件。优化完成是因为目标函数在可行方向上不递减,在函数公差选定值范围内,约束条件满足在约束公差选定值范围内。
流('在%d年后,初始$%g的回报为$%g \n',...T Capital_0 fval);
5年后,最初1000美元的回报是1207.78美元
plotInvestments (N, PurchaseYears、成熟度、利率、sol.x)
任意尺寸模型
为问题的一般版本创建一个模型。举例说明T
= 30年期,400个随机生成的债券,利率从1到6%不等。这种设置的结果是一个有430个决策变量的线性规划问题。
%用于再现性rng默认的初始金额Capital_0 = 1000;%以年为单位的时间段T = 30;%键数N = 400;%购买机会总数nPtotal = N + T;生成随机的成熟度成熟度= randi([1 T-1],nPtotal,1);债券1的到期日为1年成熟度(1:T) = 1;为每个债券生成随机年利率利息= randi(6,nPtotal,1);%债券1的利率为0(未投资)利息(1:T) = 0;一年后返还rt = 1 +利息/100;计算每只债券到期日结束时的回报率:r = rt.^成熟度;为每个选项生成随机购买年份PurchaseYears = 0 (nPtotal,1);%债券1每年可购买PurchaseYears (1: T) = 1: T;为i = 1: N生成一个随机年份,使债券在年底前到期% T年期间PurchaseYears(i+T) = randi([1 T- maturity (i+T)+1]);结束计算每个债券在年底到期的年份。到期日=购买日+到期日- 1;
计算债券可以买卖的时间。的buyindex
矩阵表示潜在的购买次数,而sellindex
矩阵表示每个债券的潜在销售时间。
buyindex = false(nPtotal,T);分配nPtotal-by-T矩阵为ii = 1:T buyindex(:,ii) = PurchaseYears == ii;结束sellindex = false(nPtotal,T);为ii = 1:T sellindex(:,ii) =到期年份== ii;结束
建立键对应的优化变量。
X = optimvar(“x”nPtotal 1下界的, 0);
建立优化问题和目标函数。
Interestprob = optimproblem(“ObjectiveSense”,“最大化”);interestprob。目标=总和(x (sellindex (:, T))。* r (sellindex (:, T)));
为方便起见,创建一个临时数组xBuy,其列表示我们在每个时间段可以购买的债券。
xBuy = repmat(x,1,T).*double(buyindex);
类似地,创建一个临时数组xSell,其列表示我们在每个时间段可以出售的债券。
xSell = repmat(x,1,T).*double(sellindex);
出售这些边界产生的收益是
xReturnFromSell = xSell.*repmat(r,1,T);
创建一个约束条件,你在每个时间段投资的金额是你在前一个时间段卖出的金额。
interestprobo . constraints . initialinvest = sum(xBuy(:,1)) == Capital_0;interestprobv . constraints . investconstraint = sum(xBuy(:,2:T),1) == sum(xReturnFromSell(:,1:T-1),1);
无持有限制的解决方案
解决问题。
Tic [sol,fval,exitflag] = solve(兴趣问题,“选项”、选择);
用linprog解决问题。最小值满足约束条件。优化完成是因为目标函数在可行方向上不递减,在函数公差选定值范围内,约束条件满足在约束公差选定值范围内。
toc
运行时间为0.175883秒。
这些投资的表现如何?
流('在%d年后,初始$%g的回报为$%g \n',...T Capital_0 fval);
30年后,最初1000美元的回报是5167.58美元
有限公司解决方案
为了限制每种资产的投资比例,可以建立一个矩阵来跟踪每次的活跃债券。表示每个投资必须小于的约束条件Pmax
乘以总价值,建立一个矩阵来跟踪每一项投资在每一时刻的价值。对于这个较大的问题,将可以保持的最大分数设置为0.4。
Pmax = 0.4;
创建一个活跃的
矩阵对应的时间,一个债券可以持有,和一个cactive
矩阵,其中包含每个活动债券的累计持续时间。也就是债券的价值j
在时间t
是x (j) * (rt ^ cactive)
.
Active = double(buyindex | sellindex);为ii = 1:T活跃(:,ii) = double((ii >= PurchaseYears) & (ii <= MaturityYears));结束Cactive = cumsum(active,2);Cactive = Cactive .*active;
创建矩阵,其中元素(j,p)表示债券j在p时期的值:
bondValue = repmat (x 1 T)。*活跃。* (rt ^ (cactive));
确定每个时间间隔的投资总值,以便对有限持股施加约束。mvalue
在每个时间段结束时,钱是否投资于所有债券nPtotal
——- - - - - -T
矩阵。米oneyavailable is the sum over the bonds of the money invested at the beginning of the time period, meaning the value of the portfolio at each time.
constrlimit = optimconstr(nPtotal,T);constrlimit(:,1) = xBuy(:,1) <= Pmax*Capital_0;constrlimit (:, 2: T) = xBuy (:, 2: T) < = repmat (Pmax *总和(bondValue (:, 1: T - 1), 1), nPtotal, 1)。*双(buyindex (:, 2: T));interestprop . constraints .constrlimit = constrlimit;
解决有限持股的问题。
Tic [sol,fval,exitflag] = solve(兴趣问题,“选项”、选择);
用linprog解决问题。最小值满足约束条件。优化完成是因为目标函数在可行方向上不递减,在函数公差选定值范围内,约束条件满足在约束公差选定值范围内。
toc
运行时间为0.781559秒。
流('在%d年后,初始$%g的回报为$%g \n',...T Capital_0 fval);
30年后,最初1000美元的回报是5095.26美元
为了加快求解速度,请尝试双单纯形算法。
选项= optimoptions(“linprog”,“算法”,对偶单纯形的);Tic [sol,fval,exitflag] = solve(兴趣问题,“选项”、选择);
用linprog解决问题。找到最优解。
toc
运行时间为0.238956秒。
流('在%d年后,初始$%g的回报为$%g \n',...T Capital_0 fval);
30年后,最初1000美元的回报是5095.26美元
在这种情况下,双单纯形算法获得相同解的时间更短。
定性结果分析
要对溶液有个感觉,可以把它和溶液的量比较一下fmax
如果你能把你所有的初始资金投资到一个利率为6%(最高利率)的债券上,为期30年。你也可以计算出与你最终财富相对应的等价利率。
最大金额fmax = Capital_0*(1+6/100)^T;百分比(以百分比计)鼠= fval/fmax*100;相当于利率(以百分比计)rsol = ((fval/Capital_0)^(1/T)-1)*100;流(['收集的金额是最大金额$%g的%% '...你可以从投资一种债券中获得。...“你的最终财富相当于%g%% %的利率在%d年”...“。\ n”,鼠,fmax, rsol, T)
所收集的金额是你投资一种债券所能获得的最高金额$5743.49的88.7137%。你最终的财富相当于30年5.57771%的利率。
plotInvestments (N, PurchaseYears、成熟度、利率、sol.x,假)