Hi All,
I just wrote a blog post on Portfolio Optimization using QuantConnect (link here). The purpose of this project is to provide the community with a useful workflow in which to perform research with powerful visualizations and then backtest conclusions back and forth between the Notebook and the Algorithm Framework.
The Notebook is divided into several sections covering some preliminary analysis and walk-forward optimizations with multiple lookback periods. Some interesting stuff in the code:
- You can test multiple optimization techniques by simply changing the objective function: Maximize Portfolio Return (disregard volatility), Minimize Portfolio Volatility (disregard return), Maximize Portfolio Sharpe Ratio (assuming a risk-free rate of 0%), Maximize Portfolio Sortino Ratio, Risk Parity Portfolio. Also, you can choose the lookback period for optimization and different date rules for the rebalancing logic (Expiry.EndOfWeek, Expiry.EndOfMonth, etc.).
- The implementation of Risk Parity using Spinu convex formulation.
- In the Notebook, several interesting visualizations are provided (efficient frontier, monthly weights, relative risk contributions, risk-reward profiles, etc.).
- In the Notebook, you can run all the walk-forward optimizations on multiple lookback periods at the same time and visualize the performance of the different combinations.
Eugene
Hello Emilio,
thanks for sharing this masterpiece!
I am surprised how well the risk parity portfolio performes compared to the sharpe ratio portfolio.
In the walk forward test it seems that theory and actual performace are opposite.
My guess for the reason is that the use of mean returns (momentum) got very "unreliable/unstable" during the last 2 decades, which makes every stratagy based on this indicator also unstable.
An idea would be to introduce a factor for the risk partity weights calculation which allows tunning the weights more toward risk or risk aversion. A plot from "0 to 1" would give the more realistic and actually achievable efficient frontier compared to the calculations based on Markowitz.
Cu
Eugene
Eugene
Hi all,
can anyone help realising this part in c#
opt = minimize(lambda weights: self.ObjectiveFunction(objFunction, dailyReturnsDf, covariance, covarianceNegativeReturns, weights), x0 = self.initWeights, bounds = bounds, constraints = constraints, method = 'SLSQP') elif objFunction == 'riskParity': f = self.CalculateRiskParityFunction(covariance, weights) return f def CalculateRiskParityFunction(self, covariance, weights): ''' Spinu formulation for risk parity portfolio ''' assetsRiskBudget = self.initWeights portfolioVolatility = self.CalculateAnnualizedPortfolioStd(covariance, weights) x = weights / portfolioVolatility riskParity = (np.dot(x.T, np.dot(covariance, x)) / 2) - np.dot(assetsRiskBudget.T, np.log(x)) return riskParity
I was not able to find a suitable solver for this problem in c#
Maybe using AlgLib would be an option, but I couldn't try because it gives the error: The type or namespace name 'AlgLib' could not be found (are you missing a using directive or an assembly reference?)
Cu
Eugene
.ekz.
Such quality. Thanks for this.
Sharing the new link to the blog post, for anyone else that may need it --it's a great read!
Mislav Sagovac
Hi Emilio Freire ,
I have found another version of your Portfolio optimization module here:
From the description it seems it is enough to insert this code in existing algo framework:
But, when I do this, I got an error:
I tried to find email on the InnoQuantivity site site, but without success.
Louis Szeto
Hi Mislav
The reason for getting this error is that the variable size = 0, meaning the rank in the return dataframe is 0 (the universe does not have any tickers or none of the tickers has any close price data in the requested period). A check of variable size should be able to get this solve:
Best
Louis Szeto
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
.ekz.
I'm adopting this for crypto, and adding volatility skewness as an optimization objective. The attached backtest shows my progress so far.
I've introduced the crypto tickers and set the brokerage accordingly --now I'm seeing the weights for crypto assets allocated correctly and the insights emitted. However, no trades are being opened.
Any thoughts on why this would be happening? I have very little experience working w/the LEAN model framework.
Emilio Freire
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!