gpt4 book ai didi

python - 使用 Sympy 和 Scipy 求解欠定方程组和约束

转载 作者:行者123 更新时间:2023-12-01 09:07:35 24 4
gpt4 key购买 nike

我正在编写一个 Python 脚本,它将有助于年度投资组合重新平衡。对于那些不熟悉这个概念的人来说,它基本上意味着每年购买/出售已经增值/损失值(value)的 Assets ,以便您的投资组合构成实际上与您想要的 Assets 配置相匹配。如果在 1 月 1 日,您的投资组合的股票/债券比例为 50/50,并且股市今年表现出色,那么到同年 12 月 31 日,您将在投资组合中增持股票,这意味着您将需要出售一些股票来购买债券才能使比例回到 50/50。如果所有 Assets 都在一个账户中,那么弄清楚如何做到这一点是非常容易的,但如果您在多个账户中进行投资,则可能会变得复杂,特别是如果它们是您在退休之前不应该提取的退休账户。

对于重新平衡步骤,我建立了一个由 8 个简单线性方程组成的系统。它们看起来大致像这样(请参阅第二个代码块中的增强矩阵):

Asset1 + Asset2 + ... = us_bonds_target 
Asset1 + Asset2+ ... = total_401k_value
...and so on

然后我按以下方式使用 Sympy 的solve_linear_system 函数:

from sympy import Matrix, symbols, solve_linear_system

Assets_Matrix = Matrix([[1, 0, 0, 0, 1, 0, 0, 1, 9571165],
[0, 1, 0, 0, 0, 0, 0, 0, 7298011],
[0, 0, 0, 1, 0, 0, 0, 0, 4665941],
[0, 0, 1, 0, 0, 1, 0, 0, 7178371],
[0, 0, 0, 0, 0, 0, 1, 0, 7178371],
[1, 1, 1, 1, 0, 0, 0, 0, 22550494],
[0, 0, 0, 0, 1, 0, 0, 0, 7200311],
[0, 0, 0, 0, 0, 1, 1, 1, 6141054]])

Asset1, Asset2, Asset3, Asset4, Asset5, Asset6, Asset7, Asset8 = symbols('Asset1, Asset2, Asset3, Asset4, Asset5, Asset6, Asset7, Asset8', nonnegative = True)
solution = solve_linear_system(Assets_Matrix, Asset1, Asset2, Asset3, Asset4, Asset5, Asset6, Asset7, Asset8)

运行此代码会产生如下输出:

{Asset5: 7200311,
Asset6: -Asset8 - 1037317,
Asset7: 7178371,
Asset3: Asset8 + 8215688,
Asset4: 4665941,
Asset2: 7298011,
Asset1: -Asset8 + 2370854}

这非常接近我想要的,即 Assets 及其重新平衡目标值的列表。但是,有一些限制:

  1. 有时它会给我负面的解决方案,这在这种情况下没有用。现实生活中 Assets 值(value)不能小于0。

  2. 这是一个更大的问题:我无法指定任何变量的约束。这些 Assets 大多数是共同基金,保持每项 Assets 一定的最低值(value)是有利的,因为一些共同基金有不同的“类别”,如果您满足一项投资,其费用比率(每年持有投资的成本)较低最低限度。对于大多数这些 Assets ,我希望每项投资不少于 1 万美元。我意识到有时这会导致系统无法求解,但我至少想首先尝试用这些约束来解决它,然后在求解器失败时放松它们。

在研究了堆栈溢出和谷歌之后,我了解到这个问题的解决应该可以使用线性编程来解决。因此,我将问题设置如下(请注意,我还没有将 Assets 的最低值要求纳入代码中 - 除了它们需要是积极的 - 我只是想证明这种方法将产生有用的解决方案) :

from scipy.optimize import linprog

A = [[1, 0, 0, 0, 1, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1]]
B = [9571165, 7298011, 4665941, 7178371, 7178371, 22550494, 7200311, 6141054]
C = [0, 0, 0, 0, 0, 0, 0, 0]

linprog(c = C, A_eq = A, b_eq = B, bounds = (0, None), method = 'interior-point')

但是,当我运行此代码时,我得到以下输出:

     con: array([  2370852.29007765,         0.        ,         0.        ,
7178369.8786112 , 0. , 10586541.29564287,
0. , -1037319.12695402])
fun: 0.0
message: 'The algorithm terminated successfully and determined that the problem is infeasible.'
nit: 4
slack: array([], dtype=float64)
status: 2
success: False
x: array([ 3.97865052e-02, 7.29801100e+06, 6.64570623e-01,
4.66594100e+06, 7.20031100e+06, 4.56818174e-01,
7.17837100e+06, 1.67013585e+00])

出于某种原因,linprog 似乎不喜欢我的方程。我的问题非常适合 linprog 函数吗?如果是这样,我做错了什么?或者我应该以不同的方式解决这个问题?

最佳答案

The algorithm terminated successfully and determined that the problem is infeasible.

这意味着该问题在限制范围内是不可能解决的。要理解原因,让我们仔细看看 sympy 结果:

Asset5: 7200311
Asset6: -Asset8 - 1037317
Asset7: 7178371
Asset3: Asset8 + 8215688
Asset4: 4665941
Asset2: 7298011
Asset1: -Asset8 + 2370854
  • Assets 2、4、5、7 是唯一定义的。
  • Assets 1、3、6、8 共享一个自由度

这意味着我们可以为 Assets 1、3、6 或 8 之一选择任何值,其他值都从中派生。现在应用 Assets 不能为负的约束。

  • 来自 Asset1 >= 0接下来是Asset8 <= 2370854
  • 来自 Asset3 >= 0接下来是Asset8 >= -8215688
  • 来自 Asset6 >= 0接下来是Asset8 <= -1037317 ...这与 Asset8 >= 0 不兼容.

综上所述,如果所有 Assets 都必须为正,则问题无法解决。

关于python - 使用 Sympy 和 Scipy 求解欠定方程组和约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51923465/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com