Intro
Superior algo returns can be thought of as being the result of two components: a great strategy regarding ‘what stocks to buy’ (the stock selection component, SEL) and a ‘clever timing’ (the in & out component, I/O) regarding when we are ‘in’ the market and hold the stocks versus when we are ‘out’ of the market and hold alternative assets such as bonds. We often focus on optimizing SEL and tend to neglect I/O; thus, for an important discussion of recent I/O tactics, see here.
Focus of this thread: Optimal SEL + I/O combinations
It is worthwhile to separately optimize SEL and I/O. However, the ultimate total return will also be determined by a certain synergy or dissonance between the two components. So, it seems that we won’t get around the arduous task of individually testing (all possible) combinations to identify optimal SEL + I/O pairs, which is the eventual focus of this thread. I reckon a preparatory step can be to dig up all the hidden SEL and I/O treasures from this forum and beyond to see what inputs are available for the combinations.
Ultimate objective
Let's get rich together, why not?
Peter Guenther
Just something to check with our European friends, Primoz Golle, Dimitar Dimitrov and Davidii111: I understand that trading US-based ETFs is not possible due to regulations. I just wanted to check: Could you trade call options, e.g. on TLT, instead of trading the actual ETF (assuming you have successfully requested the trading permission for options on IB)?
For instance, here is a Yahoo Finance list of options for TLT: list. Could you for instance trade the first option in the list, TLT210604C00110000?
If yes, it might just be a question of creating a version where we do not trade TLT but a corresponding call option, or a basket of suitable call options.
Frederik Schöller
If options are not a possibility, wouldn't it be possible to trade an EU equivalent ETF if running LEAN as a local instance? e.g IDTL
Ton86
When running live, the algo intermittently does not pick stocks when starting algo or going back in. Just had in signal Monday and no stocks were picked again. Starting the algo 5 minutes after open instead of exactly at open just in case launching for the first time and warm up needs to happen. Anyone else encountering this?
Peter Guenther
Thanks for sharing the issue, Ton86. I am wondering whether adding “not self.Portfolio.Invested” as an additional condition for refreshing the universe and rebalancing the ‘in’ and ‘out’ side might help address the issue.
Peter Guenther
Just one quick additional thought, Ton86: Not sure whether you consistently use minute resolution for all algo components. Using minute resolution might also help address issues in Live trading, see the earlier post by Alexandre Catarino.
Let me/us know how you go. When you have figured out what is going (or someone else does), I think that these will definitely be interesting lessons learned for many, so feel free posting these here in this thread.
Ton86
Thank you Peter Guenther. I have been running “res = Resolution.Minute” since going live. I will try adding “not self.Portfolio.Invested” next week as an additional condition and provide feedback. Best.
Narendra Kulkarni
Hi, My understanding is that there are two variants:
a) SEL[QualUp] + I/O[In & Out]
b) SEL[Earnings Rockets] + I/O[The Distilled Bear]
does anyone have the correlation between the two strategies. If the correlation is low then it might be worthwhile to run both in parallel.
Peter Guenther
That is a valid thought, Narendra Kulkarni!
Technically, there are more possible combinations, which we get by mapping the full factorial of the stock selection strategies that were discussed in this thread ([TQQQ], [ValuationRockets], [QualUp], and [F-Score]) and the in & out strategies discussed here ([InOut] and [DistilledBear]). So, this gives you 4 x 2 = 8 possible combinations.
In terms of the correlation idea, what you could be doing is to run the backtests for the two combos you have listed and, in the backtest results (you may have these already available from your earlier tests), copy the monthly returns (select: Total Net Profit) from the results' Overview tab into an Excel sheet to calculate the correlation using Excel's correl function. If you are happy to share, it would be interesting to see what comes out of this calculation.
Narendra Kulkarni
Thanks you Peter. I can do what you suggest, however I would prefer to do using code. Is there any way to compute strategy correlations using quantconnect code? If someone can give me any pointers, I am happy to code. Secondly, my thought was that if the correlations between the different variants are low enough, we could simply combine them using some formula. Maybe risk parity, or equal weighting. More importantly if the strategies are overfit, hopefully these errors will somewhat cancel out and we wont get burnt in live trading.
Narendra Kulkarni
My understanding of the quantconnect platform is that for us to run multiple algos in parallel we need to use the multiple alpha models. So should we first focus on converting some of the existing code to the multiple alpha framework? This will allows us to combine the different versions of in and out and run them in parallel.
Peter Guenther
Fantastic idea, Narendra Kulkarni! I remember that a few months ago Zicai Feng has translated Strongs's Piotrosky F-score algo version into an Algo Framework (link to the post). So this might be the perfect base to build the Multi-Algo Framework from.
The suggested quick-and-dirty correlation test using the Backtest returns of the individual strategies could be an initial face-value assessment regarding the likely gains of combining the strategies in a multi-algo framework. However, the multi-algo framework will provide a more precise picture.
Peter Guenther
Implementation re Live trading recovery
vidal boreal correctly noted elsewhere that the self.dcount and self.outday variables reset to zero when live trading is interrupted, meaning that the algo effectively ‘forgets’ that it went out of the market and wanted to stay out for some time.
The attached backtest uses the ObjectStore to save the dcount and outday as important state information of the algorithm that can be recovered in case of an interruption. To illustrate the approach, I am using the old (p. 2 of this thread) [In & Out / Distilled Bear] + [QualUp] code. The important lines are:
Lines 298-301: Tries to retrieve dcount and outday from the ObjectStore if they are zero (i.e. the algo restarted) and the info exists in the ObjectStore.
Line 334: If running live, a function to save dcount and outday is called on a daily basis.
Lines 416-418: This is the function that actually saves dcount and outday to the ObjectStore.
Feel free to copy and paste these lines into your algo version.
Spacetime
hmm… I am receiving the following error stated below when I ran the algo attached in the post: :Implementation re Live trading recovery. I remember solving something like this before. Let me see if I can find a solution for this.
Error Message:Runtime Error: Trying to retrieve an element from a collection using a key that does not exist in that collection throws a KeyError exception. To prevent the exception, ensure that the SHY key exist in the collection and/or that collection is not empty.
at _validate_read_indexer
key=key in indexing.py: line 1176
Stacktrace:
Trying to retrieve an element from a collection using a key that does not exist in that collection throws a KeyError exception. To prevent the exception, ensure that the SHY key exist in the collection and/or that collection is not empty.
at _validate_read_indexer
key=key in indexing.py: line 1176
Peter Guenther
Thanks for sharing this bug, spacetime. Second try. I have made the following additions/changes:
1. Line 297: check for whether self.history actually has data. Only proceed if it does.
2. Line 245-246: saved the benchmarks for the debt and tips basis differently, without requiring that dcount is 0.
3. Line 255-258: removed a bunch of double squared brackets which are not required.
Let me know in case the bug persists and I'll have another look.
Spacetime
tested it from self.SetStartDate(2015, 1, 1) and have not received any errors
Jon Bailey
Disregard…Cloned the wrong one
Peter Guenther I'm trying your last posted Algo and getting a runtime error, any idea why?
Peter Guenther
Given the current equity market uncertainties (esp. regarding inflation expectations driving up bond yields), this might not be the best time to make risky leveraged investments in Tech. Anyway, I could not help it and had to try out the new In & Out v8 algo with one of the ‘old classics’ of this thread: holding the TQQQ :)
Peter Guenther
Somewhat relevant for the TQQQ holding strategy in the previous post and discussed earlier in this thread, I found this paper on SSRN (by Lewis A. Glenn). Title and abstract below.
Title: Long-Term Investing in Triple Leveraged Exchange Traded Funds
Abstract:
The phrase long-term investing in triple leveraged ETFs is somewhat of an anathema for investment academicians. As a result of daily rebalancing and so-called beta slippage or “the constant leverage trap” it is highly likely over the long term to significantly deviate from the targeted leverage and, in so doing, generate wipeout losses. In fact, the data show that many 3X leveraged ETFs have performed poorly over the long term in the period of their existence. However, there are some significant exceptions. The 3X leveraged Nasdaq ETF, TQQQ, for example has delivered a total return exceeding 10,000% (CAGR of 54.4%) over the 10+ years of its existence, more than 13 times the total return of its underlying ETF (QQQ). Similar, but less impressive numbers have been achieved with triple leveraged ETFs that target the S&P 500 and the Dow Industrials.
These results, however, are accompanied by excessive volatility and very large maximum end-of-month (EOM) draw downs, in excess of 49% for TQQQ, and with maximum daily drawdown of almost 70%. Many retail investors would be unwilling to sustain such (paper) losses. Here we propose a strategy to mitigate these large draw downs while still retaining much of the upside performance of triple leveraging. We show that by simply establishing a portfolio consisting of an equal dollar amount of TQQQ and TMF (the triple leveraged ETF linked to the 20+ year treasury bond), and performing bimonthly rebalancing, a total return, after transaction costs, in excess of 5,800% (CAGR of 44.9%) would have been achieved over the 10+ years of TQQQ existence, with the maximum EOM draw down less than 25%.
JSO 2045
Hello everyone.
I'm pretty much a beginner with QuantConnect (just started to vaguely understand how to create and use a Dynamic Universe). I have read through this thread and just wanted to say it is awesome, I hope I can get to the level of detail and complexity that you lads are dealing in at some point.
Peter Guenther, is the most recent version of the algo you posted updated with the changes you made for “Implementation re Live Trading Recovery?” I tried having a look but in all honesty got a bit lost.
Also, is this version suitable for live trading. Alexandre Catarino gave a couple recommendations, including to use Resolution,Minute. Has anyone tried it out live and if so, does the algo make the trades we would expect it to make. I am happy to try this out myself but I fear I would not have the know-how to really grasp whether it was working or not, or suggest any changes.
Forgive my ignorance :)
Peter Guenther
No worries, JSO 2045, thanks for joining the discussion!
Regarding your questions:
(1) Does the algo have Live Trading recovery?
It does. The key variable for the in & out decision is the density of the number of signals saying out (see the black line discussed and illustrated in this post; the corresponding variable in the code is self.signal_dens). In Live Trading, this variable is saved every day that the code runs to the ObjectStore after the variable has been updated. See line 139 (if self.LiveMode: self.SaveData()) which calls the function SaveData that saves self.signal_dens. For the SaveData function, see lines 190-191 in the code. On the next day, if Live Trading, the code loads the saved variable from the ObjectStore before running its other daily checks and routines. See lines 98-102. So, if the code get interrupted, it would not matter much since it would pull the most recent critical information from the ObjectStore before it does anything else. This means that it has a recovery mechanism in place for live trading interruptions.
(2) Does the algo use Resolution.Minute?
It does. See line 27, where the variable res is defined which is then used for all equity tickers that are added (e.g. in line 31).
(3) How would I assess whether the algo performs the trades that it's supposed to perform?
One approach could be to run it live for a certain period of time and then run a backtest for the same period of time, comparing the trades.
Peter Guenther
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!