Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weights given volatility target #1

Open
HedgeShot opened this issue Oct 24, 2021 · 2 comments
Open

Weights given volatility target #1

HedgeShot opened this issue Oct 24, 2021 · 2 comments

Comments

@HedgeShot
Copy link

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?

@phschiele
Copy link
Owner

phschiele commented Oct 24, 2021

Hi @HedgeShot !
Many thanks for the feedback (and opening issue 1 🎉 ) !
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))

@HedgeShot
Copy link
Author

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants