Weights given volatility target
Hi,
Thank you for developing this package. I was playing a bit with it and I am wondering how to increase the number of points computed to draw the efficient frontier? With my input, only 9 points are computed, which is too low to achieve my goal of finding the optimal weights for a given volatility target (let say 10%). Is there a way to achieve what I am looking for?
Hi @HedgeShot ! Many thanks for the feedback (and opening issue 1 :tada: ) ! Very good point, currently, the algorithm only returns the critical points, i.e. all other points on the efficient frontiers are only linear combinations of the two adjacent portfolio weights. I am planning to add some convenience functions in the next weeks (weights for specific return/vola target, max sharpe ratio, sample n points for plotting, ...) and also push a version to PyPI.
Until then, the below snippet finds the optimal weights for a volatility target of 1.7 for the example from the README.
from scipy.optimize import brentq
def vola_bisection_root(lower_vola_weights, higher_vola_weights, C, x, vola_target):
weight_combination = x * lower_vola_weights + (1-x) * higher_vola_weights
return np.sqrt(weight_combination.T @ C @ weight_combination) - vola_target
weights = [i['X'][:n_sec] for i in pycla.output]
std = np.array([i['std'] for i in pycla.output])
lower_vola_idx = np.argmax(std < 1.7)
higher_vola_idx = lower_vola_idx - 1
lower_vola_weights = weights[lower_vola_idx]
higher_vola_weights = weights[higher_vola_idx]
f = lambda x: vola_bisection_root(lower_vola_weights, higher_vola_weights, C, x, 1.7)
x_star = brentq(f, 0, 1)
optimal_weights = x_star * lower_vola_weights + (1-x_star) * higher_vola_weights
print(np.sqrt(optimal_weights.T @ C @ optimal_weights))
Thanks a lot!