我的目标是优化40只股票的投资组合中的权重,回报和风险都在一个40行2列的df数据框架中。
对于这个优化,我使用了scipy的minimize函数。
资产的权重不能大于0.1(10%)(界限)。还有两个限制(缺点):
- 第1个约束条件:权重和等于1
- 第二个约束:权重大于0.05的资产的权重总和不得超过0.4(即投资组合总权重的40%)
我的问题是在第二个约束上,我试图找到一种方法来将其表示为不等式,但没有成功:
第一个月
这个不等式对我来说很好,但当我优化时它不起作用。大于或等于0.05(5%)的权重之和始终大于0.4(40%)
import pandas as pd
import numpy as np
from scipy.optimize import minimize, Bounds, LinearConstraint
# Set the number of rows in the DataFrame (here we put 40)
n = 40
# Generate 40 random codes as a list
codes = [''.join(np.random.choice(list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 2)) + str(np.random.randint(10, 100)) for _ in range(n)]
# Generate 40 random returns between 0.05 and 0.2
returns = np.random.uniform(0.05, 0.2, n)
# Generate 40 random risks between 0.15 and 0.39
risks = np.random.uniform(0.15, 0.39, n)
# Create the DataFrame using a dictionary
data = {"Code_title": codes, "Return": returns, "Risk": risks}
df = pd.DataFrame(data)
# Set parameters
guess = np.full((df.shape[0],1), 1.0/df.shape[0]) # initial weights for iterations
bounds = tuple((0,0.1) for x in range(df.shape[0])) # set assets weight between 0 and 0.1
cons = (# sum of weights = 1
{"type":"eq", "fun": lambda x: np.sum(x)-1},
**#5 10 constraints
{"type": "ineq", "fun": lambda x: -np.sum(x[x>=0.05]) + 0.4})**
def function_obj(W) :
#objective function extended maximum sharpe ration model
W = np.array(W)
fund_return = np.array(df['Return']) @ W # portfolio return
fund_risk = np.array(df['Risk']) @ W # portfolio risk
return fund_return/fund_risk # objective function
result = minimize(function_obj, guess, method = "SLSQP", bounds=bounds, constraints=cons)
np.set_printoptions(suppress=True)
result['x']
np.sum(result['x'][result['x']>=0.05]) # calculate the sum of weights greater than 0.05
字符串
1条答案
按热度按时间m2xkgtsf1#
正如我在评论中提到的,第一种方法是用线性目标代替你的目标。有几种可能的形式,每一种看起来都像是某个常数向量与决策权重的点积。这个常数向量可以是按元素(而不是按总和)的风险收益比,也可以是风险和收益的(潜在加权)差。
构造一个混合整数线性规划:
个字符
这将 * 不 * 等同于你最初写的目标,但如果你没有一些严格的理论需要,那么也许这是可以的。
解决原始非线性目标的其他选项(软S形约束、差分进化MINLP)将在计算上更加复杂。