SMA RSI & Sudden Buy Sell Strategy

Author: ChaoZhang, Date: 2023-12-20 17:33:04



This strategy mainly uses the average value of RSI and sudden price changes to identify market trend and reversal points. The core idea is to consider establishing positions when RSI is overbought or oversold, and look for reversal opportunities when sudden price changes occur. EMA is also used as a filter.


  1. Calculate the SMA of RSI. When RSI SMA crosses above 60 or falls below 40, it is considered overbought or oversold, and reverse positions will be considered.

  2. When the change of RSI exceeds a certain value, it is regarded as a sudden change. Combined with the actual close price verification, it serves as a signal to establish reverse position.

  3. Use multiple EMAs for filtering. Only when price crosses above shorter period EMA, long position will be considered. Only when price falls below shorter period EMA, short position will be considered.

  4. By combining the use of RSI average, sudden changes and EMA filtering, better entry points can be identified.

Advantage Analysis

  1. Using RSI average can accurately judge overbought and oversold conditions, which is conducive to capturing reversal opportunities.

  2. Sudden changes often signify shifts in price trend and direction, using this signal can improve the timeliness of entries.

  3. Multi-level EMA filtering can further avoid false signals and reduce unnecessary losses.

  4. The combination of multiple parameters as decision criteria can enhance the stability and reliability of the strategy.

Risks and Mitigations

  1. RSI performance may be unstable and SMA hit rate may be low. RSI parameters can be optimized or other indicators can replace it.

  2. Sudden changes could just be short-term fluctuations rather than true reversals. Increase sensing cycle length to improve judgment accuracy.

  3. There is lag in EMA direction filtering. Test shorter period EMAs to improve sensitivity.

  4. In general, this strategy is quite sensitive to parameter tuning. Careful tests are needed to find optimum parameter combinations. Use stop loss to control risks.

Optimization Suggestions

  1. Test other indicators like ADX, MACD combined with RSI to find better entry points.

  2. Increase machine learning algorithms to judge the authenticity and stability of sudden buy/sell signals.

  3. Further enhance EMA direction filtering such as using composite judgment of different period EMAs.

  4. Add adaptive stop loss strategy to dynamically adjust stop loss range based on market volatility.

  5. Continue parameter optimization to find optimum parameter combinations. Evaluation criteria could be Sharpe Ratio etc.


This strategy firstly uses RSI average to determine overbought/oversold conditions. Reverse positions are then established when sudden changes occur. EMA is also used as an auxiliary filter. With proper parameter settings, this strategy can effectively determine market trend shifts. Overall speaking, it has good stability and practical value. There is still room for further improvement, requiring persistent testing and optimization.

start: 2023-12-12 00:00:00
end: 2023-12-19 00:00:00
period: 3m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

// This source code is subject to the terms of the Mozilla Public License 2.0 at
// © samwillington


strategy("sma RSI & sudden buy and sell Strategy v1", overlay=true)
price = close
length = input( 14 )
inst_length = input( 10 )
var rbc = 0
var float rsiBP = 0.0
var rsc = 0
var float rsiSP = 0.0
bars = input(10)

lookbackno2 =
rsi_buy = 0
rsi_sell = 0

//EMA inputs

input_ema20 =
ema20 = ta.ema(price, input_ema20)
input_ema50 =
ema50 = ta.ema(price, input_ema50)
input_ema100 =
ema100 = ta.ema(price, input_ema100)
input_ema200 =
ema200 = ta.ema(price, input_ema200)
input_ema400 =
ema400 = ta.ema(price, input_ema400)
input_ema800 =
ema800 = ta.ema(price, input_ema800)

vrsi = ta.rsi(price, length)

hi2 = ta.highest(price, lookbackno2)
lo2 = ta.lowest(price, lookbackno2)

buy_diff_rsi = vrsi - ta.rsi(close[1], length)
sell_diff_rsi = ta.rsi(close[1],length) - vrsi

//RSI high low

var int sudS = 0
var int sudB = 0
var float sudSO = 0.0
var float sudSC = 0.0
var float sudBO = 0.0
var float sudBC = 0.0
var sudBuy = 0
var sudSell = 0 
var countB = 0
var countS = 0

var co_800 = false
var co_400 = false
var co_200 = false
var co_100 = false
var co_50 = false
var co_20 = false

co_800 := ta.crossover(price , ema800)
co_400 := ta.crossover(price , ema400)
co_200 := ta.crossover(price , ema200)
co_100 := ta.crossover(price , ema100)
co_50 := ta.crossover(price , ema50)
co_20 := ta.crossover(price , ema20)

if(ta.crossunder(price , ema20))
    co_20 := false
if(ta.crossunder(price , ema50))
    co_50 := false
if(ta.crossunder(price , ema100))
    co_100 := false
if(ta.crossunder(price , ema200))
    co_200 := false
if(ta.crossunder(price , ema400))
    co_400 := false
if(ta.crossunder(price , ema800))
    co_800 := false
if((price> ema800) and (price > ema400))
                    strategy.entry("Buy", strategy.long, comment="spl Buy")
                    co_20 := false
                    co_50 := false
                    co_100 := false
                    co_200 := false

// too much rsi

if(vrsi > 90)
    strategy.entry("Sell", strategy.short, comment="RSI too overbuy")
if(vrsi < 10)
    strategy.entry("Buy", strategy.long, comment="RSI too oversold")

var sudbcount = 0  // counting no. of bars till sudden rise
var sudscount = 0  // counting no. of bars till sudden decrease

if(sudB == 1)
    sudbcount := sudbcount + 1
if(sudS == 1)
    sudscount := sudscount + 1

if((buy_diff_rsi > inst_length) and (hi2 > price))
    sudB := 1
    sudBO := open
    sudBC := close
if((sell_diff_rsi > inst_length) )
    sudS := 1
    sudSO := open
    sudSC := close   

if(sudbcount == bars)
    if(sudBC < price)
        strategy.entry("Buy", strategy.long, comment="sudd buy")
        sudbcount := 0
        sudB := 0
    sudbcount := 0
    sudB := 0
if(sudscount == bars) 
    if(sudSC > price)
        strategy.entry("Sell", strategy.short, comment="sudd sell")
        sudscount := 0
        sudS := 0
    sudscount := 0
    sudS := 0

over40 = input( 40 )
over60 = input( 60 )
sma =ta.sma(vrsi, length)
coo = ta.crossover(sma, over60)
cuu = ta.crossunder(sma, over40)

if (coo)
	strategy.entry("Buy", strategy.long, comment="modified buy")
if (cuu)
	strategy.entry("Sell", strategy.short, comment="modefied sell")
//plot(strategy.equity, title="equity",, linewidth=2, style=plot.style_areabr)