I've seen a lot of people are posting their algos to get feedback or are collaborating publically. I wanted to share mine and join the effort.
The attached algo finds stocks with a 4 day EMA twice the 30 day EMA, and shorts them. Other values such as 10/50 and 2/25 also work well. Other parameters are also configurable.
Unfortunately, I've struggled to get this algo to a point I like. The biggest issue is that a big move against you leads to a margin call, forfeiting all gains. This has happened in other backtests. I've tried to manage this with position sizing and portfolio rebalancing, but it isn't as robust as I'd like.
I'm open to all ideas. Some alternatives I've considered to shorting (but not yet implemented) are bear call spreads, long puts, and bear put spreads. All benefit from defined maximum losses and some also benefit from high IV.
Stephen Hyer
One idea comes to mind to trigger a boolean or something when the threshold is initially met and then to model an entry point sometime afterwards. For example the price rises and your 4/30 threshold is met so cross = True then at some point in the future the price is trending down and the 4/30 threshold is met again and thats when you enter your trade. You may not always time the top perfectly but ideally you would have momentum on your side on the way down.
Andres Arroyo
Another idea could be trading with a buffer so you always have something like 20% of your portfolio in bonds or cash to liquidate to cover margin calls. There's a setting you can use so you never have all of your money in equities, I modified it a bit from what is in the Buy and Hold Futures tutorial in the bootcamp:
#1. Widen the free portfolio percentage to 20% to avoid margin calls self.Settings.FreePortfolioValuePercentage = 0.2
Andres Arroyo
I'll also try to do the opposite for big companies: buy when the stock dips, and sell later. I'll also try breaking up the code into more files so it can be easier to view each class separately.
Andrey Chertok
Hi, AK M
Interesting strategy. Additional ideas:
self.AddData(QuandlFINRA_ShortVolume, 'FINRA/FNSQ_' + symbol, Resolution.Daily)
AK M
Hey all,
I've incorporated some of your suggestions and have seen improvements. I set the FreePortfolioValuePercentage to 0.2 and made the algorithm more cautious by rebalancing more frequently. I also allocate a variable portion of my portfolio to an index fund such as QQQ during strong markets.
These changes mitigate some of the risk from margin calls I was facing earlier.
Andrey Chertok
Hi, AK M
Great! Could you please share your backtest, I'll try to implement idea with short interest.
Thank you
AK M
Here ya go!
AK M
Above is a run with TQQQ. Attached is a run with QQQ.
Frank Schikarski
Hi AK M
thanks a lot for sharing, very much appreciated! I have some ideas for additions. Do you have an updated version? Then I can shere these in your most recent version. Otherwise, I can share in the QQQ version above.
Happy Easter,
Frank
AK M
Hey Frank,
I haven't made any changes to this algo since the update with the Qs. Interested in seeing what you have!
LorenzoZC
Hey AK,
thanks a lot for sharing. I'm new to the community, so studying the logic behind your code is highly instructive. I can't help but wonder a few things
1) To what extent has the performance of this strategy been driven by the performance of a simple long QQQ, and whether we can quantify the edge (I'd like to test this myself but admittedly having started recently the best I can think of is to add a benchmark = QQQ * weight at each day)
2) After such a long-lasting run-up in the index, I wonder how would this behave in a downturn & what's the best way to protect the index from staying in QQQ if it were to nosedive. What would be a reasonable trigger to switch the % of portfolio allocated to it onto holding another index - such as, for the sake of simplicity, bonds?
Frank Schikarski
Dear AK M, please find attached the backtest after some tweaking over the week-end. CAGR is now 115% which seems to be beautiful. However, this is not a tradeable strategy for various reasons, one of them beeing the capacity of the strategy which is evaluated at only $ 4.800. As I am posting this in my coffe-break, only short explanation. But - do you have a github or any other way of contacting you?
Dear LorenzoZC, welcome to QC!! I had implemented a "use bull" switch which is set to "False".
Have fun cloning ;)
AK M
Frank, this is great work. It seems that decaying trailing stop losses really increase the profitability. This is something I'll start to incorporate into other strategies. Also, you're very right that the strategy is difficult to trade. It is not scalable to large accounts. I've reached out to support and asked them pass my contact information to you.
Lorenzo, good question. The original strategy doesn't allocate any capital to QQQ. It performs okay, outside of the problems outlined in the OP. The quantify the edge, I think measures such as the Information Ratio, Alpha, Sharpe, and Sortino are your best bet. Also, I think your second point is interesting and worth exploring. In my experience, bonds, currencies, and metals are good havens during market downturns.
Frank Schikarski
AK M, thanks for the nice words ;).
LorenzoZC, another hint to your 2nd question regarding a reasonable trigger to switch QQQ: there is some impressive work if you search for "in out" in the forum, e.g. In-Out continued or quite similar Dual Momentum with out days. Of course, the triggers mentioned there are created from past experiences, but include really interesting macro points of views and structural stock market info.
ZingerB
AK M Frank Schikarski I was curious and decided flip the code from "short the bubble" to "buy the dip". Attached is my backtested result without QQQ or SPY.
As u can see the results are pretty ok, assuming that the code is bug free.
If it works as intended, I suppose this strategy is more like an EMA crossover buy/sell?
Sergey Kolpakov
Hi everyone!
I tried to test the strategy in Live and constantly got invalid orders with “There is insufficient <papername> available for short sale..” (BSQR and MRIN today for example)
That's ok in general but backtests in QC don't provide information about short availability of the symbol here.
I wonder how backtests and real launches differ in case of this strategy because it doesn't seem to be tradable on some big amount of cash
Tom Penrose
First, not sure if you saw Alexandre Catarino's post about short availability:
but that should fix that issue.
Aside from that, the only danger I see with this strategy is if a stock is up heavily for good reason i.e. a merger or acquisition. If the 4 day EMA is twice the 30 day EMA you need to find out why. You could run the strategy semi-manually and just trade on signals, or alternatively you could use Tiingo analysis to flag words like “merger” that would tell the algo to stay away.
Just some ideas
Will Urban
I have expanded on Frank Schikarski 's version, thanks for the clean code I had a lot of fun and learned a lot playing with it.
(I am not a python developer, I might no be following the language's best practices and followed Frank's code style as much as possible)
I added the following to the existing code, which I am not sure if is overrfitting:
And the results were pretty good:
Will Urban
I noticed a lot of my orders were being rejected by my broker because the stock wasn't available for short sale. So I have implemented Alexandre Catarino's suggestion about short availability, and this is the result with the exact same parameters as before.
Not so good, huh? Also I am not sure how good is Areyu's data. At least one stocks that in the backtest were not available were in fact available in live trading and my order was filled.
At this point I am not sure about the viability of this strategy. I am specially concerned about being victim again of a short squeeze and considering using WallStreetBets dataset to avoid that.
Also, any tips on how to make this strategy's backtest run faster?
Varad Kabade
Hi Will Urban,
For issues with live trading, please contact support@quantconnect.com with the live deployment attached.We were able to bring the backtest time of the above algorithm down to 21 minutes by doing the following changes:
For improving the backtest time further, we recommend some changes in the strategy logic. We are calling CheckForShortSqueeze and CheckForExits every 3 and 5 minutes, and respectively we can try to check both conditions in the same Scheduled event. Refer to the attached backtest.
Best,
Varad Kabade
AK M
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!