如何在cplexpython中设置包含指示符函数的目标函数?

2024-06-10 10:24:24 发布

您现在位置:Python中文网/ 问答频道 /正文

目标如下:

这个想法是,均值-方差优化已经在一系列证券上进行过。这给了我们目标投资组合的权重。现在假设投资者已经持有一个投资组合,并且不想将整个投资组合更改为目标投资组合。在

设w_0=[w_0(1),w_0(2),…,w_0(N)]是初始投资组合,其中w_0(i)是投资组合的分数 股票i=1,…,N。设w_t=[w_t(1),w_t(2),…,w_t(N)]为目标投资组合,即投资组合 在重新平衡之后拥有它是可取的。这个目标投资组合可以使用二次优化技术,如方差最小化。在

目标是确定最终的投资组合w_f=[w_f(1),w_f(2),…,w_f(N)],满足 以下特点:

  • (1) 最终投资组合接近我们的目标投资组合
  • (2) 我们最初投资组合中的交易数量非常少
  • (3) 最终投资组合的回报率很高
  • (4) 最终的投资组合没有我们最初的投资组合持有更多的证券

通过将特征项1到4相加来创建最小化的目标函数。在

第一项是通过将最终投资组合和目标投资组合的权重绝对差相加得到的。在

第二项是指标函数乘以用户指定惩罚的总和。指标函数是y{transactions}(i),如果初始投资组合和最终投资组合的证券权重i不同,则为1,否则为0。在

由于目标是最小化,因此第三项是由最终投资组合总回报乘以负的用户指定惩罚来获得的。在

最后一项是最终投资组合中的资产计数(即,计算最终投资组合中正权重数量的指标函数之和)乘以用户指定的惩罚。在

假设我们已经将目标权重作为目标,那么如何在docplex python库中设置这个优化问题?或者,如果任何人熟悉NAG中的混合整数编程,那么知道如何在那里设置这样的问题会很有帮助。在

`
final_w = [0.]*n
final_w = np.array(final_w)
obj1 = np.sum(np.absolute(final_w - target_w)) 

pen_trans = 1.2
def ind_trans(final,inital):
    list_trans = []
    for i in range(len(final)):
        if abs(final[i]-inital[i]) == 0:
            list_trans.append(0)
        else:
            list_trans.append(1)
    return list_trans
obj2 = pen_trans*sum(ind_trans(final_w,initial_w))

pen_returns = 0.6
returns_np = np.array(df_secs['Return'])
obj3 = (-1)*np.dot(returns_np,final_w)

pen_count = 1.
def ind_count(final):
    list_count = []
    for i in range(len(final)):
        if final[i] == 0:
            list_count.append(0)
        else:
            list_count.append(1)
    return list_count
obj4 = sum(ind_count(final_w))

objective = obj1 + obj2 + obj3 + obj4

Tags: 函数用户目标transcountnp指标list
1条回答
网友
1楼 · 发布于 2024-06-10 10:24:24

代码中的主要问题是final_w不是一个变量数组,而是一个数据数组。所以没有什么可以优化的。要在docplex中创建变量数组,必须执行以下操作:

from docplex.mp.model import Model
with Model() as m:
    final = m.continuous_var_list(n, 0.0, 1.0)

它创建的n变量的值可以在0和1之间。有了它你就可以开始做事了。例如:

^{pr2}$

对于下一个目标,事情变得更加困难,因为你需要指标约束。为了简化这些约束的定义,首先定义一个辅助变量delta,它给出股票之间的绝对差异:

    delta = m.continuous_var_list(n, 0.0, 1.0)
    m.add_constraints(delta[i] == m.abs(initial[i] - final[i]) for i in range(n))

接下来,如果需要一个交易来调整股票i,则需要一个指示符变量,即1:

    needtrans = m.binary_var_list(n)
    for i in range(n):
        # If needtrans[i] is 0 then delta[i] must be 0.
        # Since needtrans[i] is penalized in the objective, the solver will
        # try hard to set it to 0. It will only set it to 1 if delta[i] != 0.
        # That is exactly what we want
        m.add_indicator(needtrans[i], delta[i] == 0, 0)

这样你就可以定义第二个目标:

    obj2 = pen_trans * m.sum(needtrans)

定义完所有目标后,可以将它们的总和添加到模型中: m、 最小化(obj1+obj2+obj3+obj4) 然后求解模型并显示其解决方案:

    m.solve()
    print(m.solution.get_values(final))

如果您还不清楚上面的任何一个,那么我建议您看看docplex附带的许多示例以及(参考)文档。在

相关问题 更多 >