The RSI breakout strategy is a quantitative trading strategy

Author: ChaoZhang, Date: 2023-12-22 14:06:45



The RSI breakout strategy is a quantitative trading strategy based on the Relative Strength Index (RSI) indicator. The strategy generates trading signals when the RSI breaks through preset overbought and oversold threshold values, i.e. go long when RSI is below 30 and go short when RSI is above 70.

Strategy Logic

The core idea of the RSI breakout strategy is to utilize the RSI indicator to determine overbought and oversold conditions in the market. The RSI calculates the ratio of average price gains and losses over a period of time to reflect the recent strength or weakness of a stock. Generally, RSI below 30 is considered oversold and RSI above 70 overbought.

The strategy first sets the oversold and overbought threshold values for RSI, with default values of 30 and 70. It then monitors the RSI line in real time. When the RSI crosses below the 70 threshold from top to bottom, a sell signal is generated. This indicates the market has entered the overbought zone and is likely to reverse downwards, so a short position is taken. Conversely, when the RSI breaks above the 30 threshold, a buy signal is generated, indicating the oversold market is likely to bounce back up, so a long position is taken.

In this way, the strategy attempts to capture price reversal points during stock fluctuations and adjust positions accordingly to “buy low and sell high”.


The RSI breakout strategy has the following advantages:

  1. Simple and clear trading signals. The RSI indicator is easy to calculate and interpret by merely observing if the indicator line breaks the threshold values. Trades can be taken promptly when signals occur without complex rules.

  2. Fully automatable with good backtest results. Trades are generated by the RSI indicator without human interference. At the same time, RSI overbought and oversold signals tend to be effective, leading to decent strategy returns in backtests.

  3. Highly customizable. Traders can flexibly tune RSI parameters like the overbought/oversold thresholds to suit different stock and market dynamics.


The RSI breakout strategy also carries some risks:

  1. Prone to whipsaws. Frequent crossover of the indicator threshold values can lead to excessive ineffective trades, hampering steady profits. Parameters can be tuned to filter some whippy signals.

  2. No trend judgment. RSI only produces signals based on overbought/oversold levels without judging the overall trend well. The strategy tends to get stuck in choppy markets. Trend filters can be added to avoid counter-trend trades.

  3. High drawdown risks. RSI often exhibits bullish divergence where price continues up while RSI trends down. Short trades will face huge losses in such cases.

Enhancement Areas

The RSI breakout strategy can be enhanced in the following ways:

  1. Incorporate multiple indicators to overcome RSI’s limitations, e.g. moving averages to determine market trend, strength indicators and volume filters to confirm signals.

  2. Optimize RSI parameters for higher stability, including tuning overbought/oversold thresholds, setting signal duration filter etc through rigorous testing. This filters ineffective signals.

  3. Implement stop loss and take profit to control risks. For example, set percentage or point stops. Avoid oversized single-trade losses on overall profits. Also consider trend and technical points for profit taking.


The RSI breakout strategy is a mean reversion quantitative strategy based on overbought and oversold signals. It has simple and clear signals, full automation capabilities and high customizability but suffers whipsaw and drawdown risks. By optimizing with indicator combos and risk controls, it can be tuned into a stable strategy.

start: 2023-11-21 00:00:00
end: 2023-12-21 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

// @version=4
// This source code is subject to the terms of the Mozilla Public License 2.0 at
// © Bunghole 2021

strategy(title="My New Strategy", initial_capital = 100000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, pyramiding = 0, currency = 'USD', overlay=true)

//// Stoploss and Take Profit Parameters
// Enable Long Strategy
enable_long_strategy = input(true, title="Enable Long Strategy", group="SL/TP For Long Strategy",inline="1")
long_stoploss_value = input(defval=50, title='Stoploss %', type=input.float, minval=0.1, group="SL/TP For Long Strategy",inline="2")
long_stoploss_percentage = (close * (long_stoploss_value / 100)) / syminfo.mintick
long_takeprofit_value = input(defval=50, title='Take Profit %', type=input.float, minval=0.1, group="SL/TP For Long Strategy",inline="2")
long_takeprofit_percentage = (close * (long_takeprofit_value / 100)) / syminfo.mintick

// Enable Short Strategy
enable_short_strategy = input(true, title="Enable Short Strategy", group="SL/TP For Short Strategy",inline="3")
short_stoploss_value = input(defval=50, title='Stoploss %', type=input.float, minval=0.1, group= "SL/TP For Short Strategy",inline="4")
short_stoploss_percentage = (close * (short_stoploss_value / 100)) / syminfo.mintick
short_takeprofit_value = input(defval=50, title='Take Profit %', type=input.float, minval=0.1, group="SL/TP For Short Strategy",inline="4")
short_takeprofit_percentage = (close * (short_takeprofit_value / 100)) / syminfo.mintick

// Plot Stoploss & Take Profit Levels
long_stoploss_price = strategy.position_avg_price * (1 - long_stoploss_value/100)
long_takeprofit_price = strategy.position_avg_price * (1 + long_takeprofit_value/100)
short_stoploss_price = strategy.position_avg_price * (1 + short_stoploss_value/100)
short_takeprofit_price = strategy.position_avg_price * (1 - short_takeprofit_value/100)
plot(enable_long_strategy and not enable_short_strategy ? long_stoploss_price: na, color=#ff0000, style=plot.style_linebr, linewidth=2, title="Long SL Level")
plot(enable_long_strategy and not enable_short_strategy ? long_takeprofit_price: na, color=#008000, style=plot.style_linebr, linewidth=2, title="Long TP Level")
plot(enable_short_strategy and not enable_long_strategy ? short_stoploss_price: na, color=#ff0000, style=plot.style_linebr, linewidth=2, title="Short SL Level")
plot(enable_short_strategy and not enable_long_strategy ? short_takeprofit_price: na, color=#008000, style=plot.style_linebr, linewidth=2, title="Short TP Level")

// Date Range
start_date = input(title="Start Date", type=input.integer, defval=1, minval=1, maxval=31, group="Date Range")
start_month = input(title="Start Month", type=input.integer, defval=1, minval=1, maxval=12, group="Date Range")
start_year = input(title="Start Year", type=input.integer, defval=1804, minval=1800, maxval=3000, group="Date Range")
end_date = input(title="End Date", type=input.integer, defval=1, minval=1, maxval=3, group="Date Range")
end_month = input(title="End Month", type=input.integer, defval=1, minval=1, maxval=12, group="Date Range")
end_year = input(title="End Year", type=input.integer, defval=2077, minval=1800, maxval=3000, group="Date Range")
in_date_range = (time >= timestamp(syminfo.timezone, start_year, start_month, start_date, 0, 0)) and (time < timestamp(syminfo.timezone, end_year, end_month, end_date, 0, 0))

//// Inputs   **This is where you enter your indicators for your strategy. For example, I added the RSI indicator.**
rsi = rsi(close, 14)
rsi_over_sold = rsi < 30
rsi_over_bought = rsi > 70

//// Strategy  **This is where you create your strategy. For example, We have or buy and sell signals.**
// Creating Long and Short Strategy
buy_signal = rsi_over_sold
sell_signal = rsi_over_bought

// Long Strategy
if buy_signal and in_date_range and enable_long_strategy == true
    strategy.entry("Long", true, when=buy_signal, alert_message="Open Long Position")
    strategy.exit("Long  SL/TP", from_entry="Long", loss=long_stoploss_percentage, profit=long_takeprofit_percentage, alert_message="Your Long SL/TP Limit As Been Triggered.")
    strategy.close("Long", when=sell_signal, alert_message="Close Long Position")
// Short Strategy
if sell_signal and in_date_range and enable_short_strategy == true
    strategy.entry("Short", false, when = sell_signal, alert_message="Open Short Position")
    strategy.exit("Short SL/TP", from_entry="Short", loss=short_stoploss_percentage, profit=short_takeprofit_percentage, alert_message="Your Short SL/TP Limit As Been Triggered.")
    strategy.close("Short", when=buy_signal, alert_message="Close Short Position")