Back to Community
SPY Master - RSI2 Mean-Reversion Strategy for SPY

Note: Up to 4 consecutive entry orders in the same direction are allowed. Maximum leverage allowed = 2

  • If RSI2 crosses under 40, buy SPY with 50% of capital next day at open
  • If RSI2 crosses above 65, sell all shares next day at open
  • If RSI2 crosses above 65 and RSI5 < 50 and price < SMA200, short SPY with 50% of capital next day at open
  • If RSI2 crosses under 40, cover all shares next day at open

Comments and improvements are welcome. Would be interested to see if someone can transfer this strategy to E-minis.

Clone Algorithm
60
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 594144cb0a059969efde1fc2
There was a runtime error.
9 responses

Tearsheet

Loading notebook preview...
Notebook previews are currently unavailable.

So I've been noticing a weird issue. When I set initial capital as $100,000,000, I get a higher return but when I set it to $10,000, my return is lower... Anybody know why this is? Below is the $10,000 backtest.

Clone Algorithm
60
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 594455d3e0f6406e5dba06fe
There was a runtime error.

I can answer that, it is sort of an illusion, works like this: At 100M there are many more partial fills. When buys go thru and sells do not (everybody's trying to sell), the algorithm dips into margin. Returns are calculated based on starting capital so margin is not considered. As a result, margin looks like profit

See this 4 line backtest illustrating the point. Also on that page various solutions to protect yourself from the problem. Or just run this:

def initialize(context):  
    schedule_function(trade, date_rules.every_day(), time_rules.market_open())  
def trade(context, data):  
    order(sid(8554), 3)  
    #record(cash = context.portfolio.cash)    # uncomment to reveal the margin  

I haven't looked at your code, I'm saying this because it has always been the pattern. Besides the links on that page above, https://www.quantopian.com/posts/margin is easy to use for charting overnight margin for visibility into what margin in your algorithm is up to.

If that tool reveals margin jumping at a particular point and you would like to find out why and see about handling something differently, use https://www.quantopian.com/posts/track-orders and set one or more start dates (and/or stop dates) in its options section, copy the logging output, make your change, run again, and diff the two, I like CompareIt for that.

I made a notebook to see if RSI2 lead a statistically significant return. The t-value is only 0.108608.

Loading notebook preview...
Notebook previews are currently unavailable.

@John, I am overseas currently and wifi is not very good. I am unable to view the notebook because it's not loading on my end. Would you mind explaining your process to come to that result?

Also, the RSI2 is extremely powerful. I wouldn't disregard it so fast if I were you. If I was only allowed to use 1 indicator in trading, it would be the RSI2.

Kory, thanks for posting this. I hadn't realized RSI2 was so consistently right. I've just played with RSI with a typical period of 14 and found it really hit or miss. I haven't had a chance yet to play around with tweaking your algo, but here are my observations:

I see the appeal of this algo is that there are no long major drawdown periods. It handles 2008 and 2011 beautifully.

But outside of those events (particularly 2008) it underperforms SPY by quite a bit. Also, it doesn't react in the same way to 2015 and 2016 pullbacks. So what's the big difference between Sept '11 and Sept '15 dips? I also wonder why the entire time period Sept 2014 - Feb 2016 is such a wash.

If RSI2 crosses above 65 and RSI5 < 50 and price < SMA200, short SPY
with 50% of capital next day at open

It appears the shorting aspect only pays off during the 2008 crash and otherwise consistently loses tiny bits of money. Is it worth it?

Lets suppose a hypothetical scenario in which the next 10 years we have a continued bull market with minor pullbacks to keep it in check and no major crash, then this algo probably simply underperforms SPY by a bit. It seems it really needs a big crash to perform.

Ok, so what I noticed is that your algo only beats market during periods where it's getting extreme signals, but otherwise you'd be better off long SPY (as far as returns are concerned). Please excuse my sloppy hacky code, but this was just a quick proof of concept. Basically, if your signal has recently exceeded the 0-1 range via both its upper and lower bounds then it trust your algo's signals, and otherwise just long SPY.

Since my combination signal only more or less occurs three times, and only two of them are really in the green, I'd say there's not enough data to go on. Quite likely it's an overfit. So I tried some other ETFs. It doesn't reliably catch the 2008 crash every time, but despite that typically leads to bigger returns, and beating SPY, nonetheless. (Other stats not so great.)

Improvements that come to mind:
- Long spy isn't a great strategy as far as stats go (pulldown, etc.), but maybe somebody can build on the idea of in addition to using RSI2 as a buy-sell indicator also using it as an indicator for when to switch strategies that shine in different market conditions.
- My combination signal is derivative from your allocation signal, but perhaps something more sophisticated and more reliable signal could be derived directly from RSI2.

Clone Algorithm
11
Loading...
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 595f02b64029b84ddf2a4b17
There was a runtime error.

Again though, it could just be the gradual nature of the 2008 crash, and 2011, that RSI2 works to beautifully with it. Doesn't handle 2015/2016 pullbacks so well. We don't know what kind of crash happens next.

Advantage of going down less than the bear markets is that you may use a leverage multiplier. Eek out extra gains with same or less risk profile than buy and hold.