【问题标题】:PuLP minimize weighted average of a selection纸浆最小化选择的加权平均值
【发布时间】:2023-03-10 03:40:01
【问题描述】:

我无法设置适当的目标函数来最小化加权平均值。

练习:对于固定收益证券(即债券)的投资组合,找出要出售的能产生最小收益的债券。在该约束范围内,最小化债券选择的加权平均收益率。

相关数据字段为YieldCurrent Face ValueCurrent Profit or Loss。选择的加权平均收益率是YieldCurrent Face Value 的总和除以Current Face Value 的总和。连续或二元决策变量是可以接受的。

这篇文章与我的问题类似...Optimizing A Loan Portfolio On Weighted Average Criteria

我比 Scipy 更快地学会了 PulP,但我可以使用最适合此类问题的任何软件包。

import pandas as pd
from pulp import *

d = {
      'Current Face Value':[173669.3, 219544.4, 253647.88, 256776.38, 264824.02, 348820.44, 415053.58, 475354.13, 643773.24, 781129.21, 866839.35, 866013.93, 974840.18, 1053465.32, 1074261.8, 1097979.35, 1112974.78, 1125646.64, 1216768.1, 1231914.2, 1423300.7, 1462152.67, 1642708.16, 1679005.31, 1625365.08, 1708252.62, 1765860.7, 1763888.76, 1828103.0, 1833238.25, 1796976.58, 1973474.26, 2027289.74, 2058402.54, 2186044.1, 2185605.23, 2222353.6, 2260944.05],
      'Current Profit or Loss':[-1613.81, 6546.25, 1965.83, 431.56, 1653.4, -556.95, 3192.99, 1732.18, -870.51, 16216.16, 140.5, -11624.28, 13347.67, 37106.55, 1638.02, 11903.53, 22179.76, 16074.41, 34904.67, 12146.89, 3976.73, -4810.06, -11510.87, 44416.35, 11475.39, 24260.51, 11766.51, 14648.76, 12272.55, 12255.15, -33461.55, -18799.52, 35814.91, 41468.95, 8442.11, 41645.9, 51555.44, -3333.12],
      'Yield':[2.118191, 3.381024, 3.723284, 3.567963, 3.381002, 3.554571, 1.786467, 3.585767, 2.061981, 3.395873, 1.895965, 1.41617, 2.935917, 3.140995, 3.103661, 2.157629, 2.400065, 2.231383, 2.941482, 2.172782, 2.086372, 2.128788, 2.400682, 3.497868, 2.094667, 2.667469, 2.308526, 2.513017, 2.326085, 2.306328, 2.685972, 2.001348, 2.806967, 3.659145, 2.203806, 3.201562, 2.839683, 1.462699],
    }
data = pd.DataFrame(d)

data_gains = data[data['Current Profit or Loss'] > 0].reset_index(drop=True)    # securities with gains
data_losses = data[data['Current Profit or Loss'] <= 0].reset_index(drop=True)  # securities with losses
print('Secs w/ gains:',str(len(data_gains)),'  Secs w/ losses: '+str(len(data_losses)))

prob = LpProblem('Portfolio Selection',LpMinimize)

# decision variables
decision_variables = []
for rownum, row in data_gains.iterrows():
    variable = pulp.LpVariable(str('x' + str(rownum)), lowBound = 0, upBound = 1, cat= 'Continuous')
    decision_variables.append(variable)
print ('Decision_variables: ' + str(len(decision_variables)))

# objective - minimize weighted avg yield of selection
wa_yield = []
for rownum, row in data_gains.iterrows():
    for i, flag in enumerate(decision_variables):
        if rownum == i:
            wa_yield.append(row['Current Face Value']*row['Yield']*flag)    # numerator of the proper objective
wa_yield = sum(wa_yield)
prob += wa_yield

# create constrains - total gain to be in this range
min_gain, max_gain = 100000, 150000

total_gain = []
for rownum, row in data_gains.iterrows():
    for i, flag in enumerate(decision_variables):
        if rownum == i:
            total_gain.append(row['Current Profit or Loss']*flag)
total_gain = sum(total_gain)

prob += (total_gain >= min_gain)
prob += (total_gain <= max_gain)

prob.solve()
print("Status:", LpStatus[prob.status])

result = []
for v in prob.variables():
    print(v.name, "=", v.varValue)
    result.append(v.varValue)

【问题讨论】:

  • 你遇到了什么问题?你的 wa_fieldtotal_gain 也是字符串。你能分享一下他们的样子吗?

标签: python optimization pulp


【解决方案1】:

尝试像这样使用字符串对象更改两个块。我认为您应该使用可优化的函数,因为您已经有了变量。你也可以使用numpy.sum

wa_yield = []
for rownum, row in data_gains.iterrows():
    for i, flag in enumerate(decision_variables):
        if rownum == i:
            wa_yield.append(row['Current Face Value']*row['Yield']*flag)    # numerator of the proper objective
wa_yield = sum(wa_field)
prob += wa_yield

...

total_gain = []
for rownum, row in data_gains.iterrows():
    for i, flag in enumerate(decision_variables):
        if rownum == i:
            total_gain.append(row['Current Profit or Loss']*flag)

total_gain = sum(total_gain)

【讨论】:

  • 感谢@Buckeye14Guy 我更新了代码,但它产生的结果不是最佳的。结果是 x0 = 1, x9 = 1, x12 = 0.967, x14 = 1。这个选择的增益正好是 100,000 并且满足约束,但是加权平均收益率是 2.86%。我可以找到其他解决方案,它们可以在可接受的范围内以较低的加权平均收益率获得收益。例如x4 = 1, x8 = 1, x12 = 1, x13 = 1, x16 = 1, x18 = 1, x20 = 1, x22 = 1, x26 =1。这产生了 102,728 的收益和 2.27% 的收益率。
  • 目标不是计算加权平均收益率的分母,在解决方案的情况下,脚本找到的将是 x0*Cur Face0 + x9*Cur Face9 + x12*Cur Face12 + x14 *Cur Face14。如何将其纳入目标函数?我认为这篇文章会有所帮助...stackoverflow.com/questions/33929353/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多