Scipy Optimizer - SLSQP优化方法

问题描述 投票:0回答:1

我正在尝试通过此功能实现投资组合优化(旨在最小化跟踪误差):

def portfolio_optimization(target_volatility=target_volatility, weights_cap = weights_cap, target_scope_1_2 = target_scope_1_2, 
                       target_scope_3 = target_scope_3, target_esg_score = target_esg_score):

n = len(benchmark_weights) # number of assets to determine initial weights

def volatility(weights):
    return np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))*260/5)
    
def esg_score_function(weights):
    return (weights*ESG_score).sum()
def scope_1_2_function(weights):
    return (weights*scope_1_2).sum()
def scope_3_function(weights):
    return (weights*scope_3).sum()

def tracking_error_squared(weights):
    return np.dot((weights.reshape(-1,1)-reshaped_benchmark_weights).T, np.dot(cov_matrix, (weights.reshape(-1,1)-reshaped_benchmark_weights)))*260/5
    
def objective(weights):
    return tracking_error_squared(weights)

# constraints
weights_sum_cons = {'type': 'eq', 'fun': lambda weights: np.sum(weights) - 1}
weights_cap_cons = {'type': 'ineq', 'fun': lambda weights: weights_cap - weights}
vol_cons = {'type' : 'ineq', 'fun': lambda weights: target_volatility - volatility(weights)}
esg_score_cons = {'type' : 'ineq', 'fun': lambda weights: esg_score_function(weights) - target_esg_score}
scope_1_2_cons = {'type' : 'ineq', 'fun': lambda weights: target_scope_1_2 - scope_1_2_function(weights)}
scope_3_cons = {'type' : 'ineq', 'fun': lambda weights: target_scope_3 - scope_3_function(weights)}

constraints = [weights_sum_cons, weights_cap_cons, vol_cons, esg_score_cons, scope_1_2_cons, scope_3_cons]

bounds = tuple((0, 1) for _ in range(n))  # weights check to be between 0 and 1 (no short-selling)
initial_guess = opt_weights  # initial guess for weights: equally weighted 

method = 'SLSQP'

result = sco.minimize(objective, initial_guess, method=method, 
                      constraints=constraints, bounds=bounds) # we get optimal weigths

# output
if result.success:
    optimal_weights = result.x
    detected_volatility = volatility(optimal_weights)
    optimized_tracking_error = tracking_error_squared(optimal_weights)
    return {
        'Optimal Weights': optimal_weights.round(4),
        'Volatility': (detected_volatility).round(5),
        "Tracking Error": np.sqrt(optimized_tracking_error),
        "ESG Score": esg_score_function(optimal_weights),
        "Scope 1-2": scope_1_2_function(optimal_weights),
        "Scope 3": scope_3_function(optimal_weights),
        'Optimization Status': "Success"            
    }
else: #if optimization not possible, switch to equally weighted portfolio
    return {
        'Optimal Weights': np.ones(n) / n,
        'Volatility': volatility(np.ones(n) / n),
        'Optimization Status': "Failed"            
    }

# Optimize the portfolio
optimized_portfolio = portfolio_optimization()

# Print the results
print("Optimized portfolio:")
print(optimized_portfolio)

我认为这段代码非常可靠,应该可以工作,因为我无法检测到其中的任何缺陷...但是我的同事正在 Excel 上对相同数据进行另一次优化,我们得到了两个不同的结果(他得到 1.43%,我得到 1.43%)得到 1.84% 的跟踪误差)。这种优化是否存在某种缺陷?我考虑过将方法从 SLSQP 更改为 trust-constr,但几乎没有任何变化(跟踪误差变化了 0.01%),而且我不知道是否应该更改代码以实现更彻底的优化,或者这个是否可靠。

谢谢你。

python optimization scipy scipy-optimize
1个回答
0
投票

我的代码有效,我的老板错了。

© www.soinside.com 2019 - 2024. All rights reserved.