RSI Strategy : Mistake on my algo

Hi guys,

I wanted to test a simple RSI 2 periods strategy :
- Buy when the RSI is below 10 and the price > its SMA 200
- Sell when the RSI is above 80

I just tested that on the SPY

The problem is that when I checked the logs, I invest even when the RSI is above 10 for example on the 2011-02-24, the RSI was at 12.8929842633 and I invested in the asset.

Please find the backtest attached, does anyone knows what is wrong with my code?
Thank you so much for the help

2
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
import talib
import quantopian.pipeline.factors as Factors

#-------------------------------------------------------------------------------

asset = symbol('SPY'); M=21 ;D=2; Buy=10; Sell=80; SMA=200

#-------------------------------------------------------------------------------

def initialize(context):

price = data.history(asset, 'close', SMA+5, '1d')
rsi = talib.RSI(price, D)
sma200 = price.rolling(SMA).mean().fillna(0)
print(rsi[-1])

if (rsi[-1] < Buy) & (price[-1]>sma200[-1]) & (sma200[-1]>0) :
order_target_percent(asset, 1)

if rsi[-1] > Sell :
order_target_percent(asset, 0)

cpp = context.portfolio.positions
log.info(cpp)

cpp_symbols = map(lambda x: x.symbol, cpp)
log.info(cpp_symbols)
There was a runtime error.
2 responses

haven't stepped through the code, but, if i had to guess, i'd say that it's in this line:

if (rsi[-1] < Buy) & (price[-1]>sma200[-1]) & (sma200[-1]>0)

you're using bitwise and operator, not the logical and. first and foremost, this won't cause a breakout condition when rsi >= Buy - it'll always evaluate all 3 sub-clauses. but try the algorithm saying

if rsi[-1] < Buy and price[-1] > sma200[-1] and sma200[-1] > 0:

also you might want to make that second if statement an elif, makes it a bit easier to read

lastly, no reason to do your rolling SMA here. just grab your 200 days of prices and take the mean(). you're grabbing more data than you need and computing 4 extra SMA values that you don't need. the rolling function is useful for when you're graphing, or when you're concerned with trend analysis, which you aren't doing here

Thanks for your message and advice on my code, I changed it and it now works