Hi QC community,
I got into quantitative trading and QuantConnect about a month ago and I’m excited to share my first algorithm.
Fundamental reason: Imagine having two assets with zero return and high volatility. If we buy just one, we are not going to earn anything. However, buying both and periodically rebalancing forces us to buy the asset that has decreased in relative value and sell the asset that has appreciated (thus taking profit) in relative value (as measured by their weights in the portfolio). As a result, we earn a so-called “rebalancing premium” or “diversification return.” (more details on Quantpedia).
Universe: Take all USD pairs on FTX, filter those that are showing a mean-reversion pattern (using bollinger bands), and select the top 25 by daily trading volume. Refresh the universe weekly. We filter for mean-reverting assets as assets showing momentum are less likely to earn a rebalancing premium (we'd be better off to buy-and-hold those).
Strategy: Equal weighting across all assets in our universe, rebalanced daily. Every day, we buy the assets that have decreased in value and sell the assets that have appreciated, thus obtaining the “rebalancing premium”.
Drawdown protection: Don't let the portfolio overall or any individual cryptos in our portfolio drop by more than 30% on a single day.
The backtesting results for this algo seem decent. That said, I’m new to QC, and would love feedback from the community on:
1) Any thoughts on coding style / am I using the correct QC patterns?
2) Are there any pitfalls I have not taken into account that might make the algorithm perform poorly during live trading?
3) Setting the drawdown limit at 30% seems arbitrary, so I'm curious whether there's a more elegant way to minimize drawdown without impacting performance.
Huge thank you to Alexandre Catarino for showing me how to construct a scheduled crypto universe in QuantConnect, and to Fred Painchaud for providing feedback on my code and helping me better understand the LEAN API.
Emi
Jared Broad
Awesome share thank you Emi
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.
Vladimir
Emi Gal
Thank you for sharing.
It's good to know that selling winners and buying losers someone called a "rebalancing premium".
Other notes:
Daily rebalancing of 25 instruments over 2 years should create a lot more than 331 trades.
What if we rewrite line 100 like this?
Emi Gal
Vladimir - thanks for the comments.
If the assets are mean-reverting, selling winners and buying losers should generate profits, as the assets will be reverting back to the mean. At least in theory.
Great point regarding the number of trades. Seems this algo gets killed by fees when I make the change you suggested.
Emi
Vladimir
Emi Gal
Here is a modification of your algorithm, mainly related to risk protection in DailyRebalance(self).
Hope you will enjoy “rebalancing premium”.
Emi Gal
Vladimir that’s a great improvement, thank you.
Karamazov
This is an interesting idea. I re-ran this and it looks like after the recent general crypto market downturn, this algorithm still does a lot better than a buy-and-hold BTC strategy (468% vs roughly 317% for BTC).
A few things I noticed:
- during market downturns the algo seems to suffer significantly more drawdown compared to BTC (37% vs 35% from May 6-21 2021, 34% vs 23% from Dec 19 2021-Jan 26 2022, and most recently 54% vs 37% from March 28-May 11 2022)
- during longer uptrends in the market the algo seems to outperform BTC (322% vs 278% from Nov 2 2020-Feb 19 2021, 136% vs 29% from June 30-Sept 6 2021, and 49% vs 46% from Sept 20-Nov 8 2021)
I wonder if trying to find a risk-off condition based on long term trends would help to mitigate some of the drawdown?
Jack Pizza
probably add a simple MA parameter don't trade under 100 200 50 ect
Emi Gal
karamazov - I was planning to run the algo on Q1-22 to see how it does under a significant market drawdown. Thanks for doing that, and glad to see it did well!
In terms of drawdown - Elsid Aliaj is right, a SMA does the trick. I've actually built a version that lowers drawdown to ~34% by not trading under SMA. Ran an Optimizer on it and seems the 40-day SMA provides the best CAR / DD ratio. Will try to polish it up & publish this weekend.
Karamazov
Indeed it does Elsid Aliaj . Performance improves significantly when using a simple 25-50 EMA crossover indicator.
Also interesting is that the algo actually performs a little better and has slightly less drawdown without using the 30% stop loss condition.
Jack Pizza
Emi Gal maybe also test, selling winners only when below MA, only buy losers when above MA, and vice versa to see what sort of implications it has. Not buying and selling at the same time.
Jack Pizza
Also realistically 2.7 sharpe is probably unsustainable if you need to lower drawdown cut your account size by 50-75% and target what drawdown you want.
Vladimir
Emi Gal
Here is another less expensive version.
Emi Gal
Hi everyone,
Attaching a new version that only trades if benchmark price (BTCUSD) is > 40-day SMA. Performance is lower than Vladimir's version, but with significantly lower drawdown (32% vs. 66%).
Emi
Anton Kiselev
I have tried replacing BTC with ETH, it produces higher results. Downsides - somewhat higher drawdown and way higher fees.
Lars Klawitter
hi Emi,
I'm new to QC and have found your algorithm very insightful.
When replicating it I cam across two observations, which might or might not be down to my lack of experience with QC:
2. I removed a few further pairs from the universe (GBPUSD and EURUSD pairs as I felt these are not suitable for what the algorithm intends to do) as well as any pairs with BTC and ETH (to see how small cap coins would fare without these two),
but noticed that the BTCUSD pair is immediately added back into to Universe during the warm up period despite not being in self.tickers. The algorithm would then start trading for a while with a universe only consisting of BTCUSD
So I played around in DailyRebalance a little bit and found that using self.UniverseManager.Values[1].Members.get_Keys() instead of both self.ActiveSecurities and self.Portfolio.Keys to get the active members of the Universe seems to remedy both these issues - the algorithm won't use a symbol before it's got the price feed and BTCUSD won't enter the universe despite being blacklisted.
I'm sure that I'm probably misunderstanding something and my lack of knowledge of QC's Universes surely doesn't help.
Do the changes I've made make sense?
Amended version attached.
Derek Melchin
Hi Lars,
BTCUSD is added because the algorithm subscribes to it with this line:
The FTX Crypto universe is empty at the start of the algorithm because the algorithm starts trading in January 2020 but the FTX dataset doesn't start until February 2020. The algorithm gets the BTCUSD data at the start of the backtest because the default Crypto market of the DefaultBrokerageModel is Market.GDAX (Coinbase Pro), which has a start date of 2015.
Yes, if we want to limit the algorithm to just trade the Crypto pairs in the universe, the changes achieve that. Alternatively, we could use the SymbolData pattern and just skip over the Symbol if it's the self.BenchmarkCrypto.
Best,
Derek Melchin
Want to invest in QuantConnect as we build the Linux of quant finance? Check out our Wefunder campaign to join the revolution.
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.
Lars Klawitter
Thanks Derek,
that makes a lot of sense. I hadn’t appreciated that the benchmark symbol would itself become part of the universe.
thanks for clearing that up.
best
Lars
Emi Gal
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!