Skip to content

Latest commit

 

History

History
419 lines (302 loc) · 18.3 KB

多因子RSI反转策略multiple-auxiliary-RSI-indicator-strategy.md

File metadata and controls

419 lines (302 loc) · 18.3 KB

Name

多因子RSI反转策略multiple-auxiliary-RSI-indicator-strategy

Author

ChaoZhang

Strategy Description

IMG

[trans]

概述

本策略运用RSI指标识别超买超卖现象,结合多种辅助因子如MACD、Stochastic指标等入场。该策略旨在捕捉短期反转机会,属于反转策略。

策略原理

本策略主要利用RSI指标判断市场是否处于超买或超卖状态。当RSI指标超过设定的超买线时,表明市场可能处于超买状态,这时策略选择做空;当RSI指标低于设定的超卖线时,表明市场有可能处于超卖状态,策略此时选择做多。这样通过捕捉行情由一个极端状态切换到另一个极端状态的反转过程中产生的短期交易机会获利。

另外,策略还引入了MACD、Stochastic等多个辅助因子。这些辅助因子的作用是过滤掉一些可能出现的假阳性交易信号。只有当RSI指标发出信号、并且辅助因子也支持该信号时,策略才会采取真正的交易行动。这种多因子配合的方式可以提高策略信号的可靠性,从而也提高了策略的稳定性。

优势分析

这套策略最大的优势在于捕捉效率高,实现了多因子验证提高了信号质量。具体来说主要体现在以下几个方面:

  1. RSI指标本身对市场 regimes 的识别能力较强,可以有效识别超买超卖现象。
  2. 借助多种辅助工具进行多因子验证,提高了信号质量,过滤了大量假阳性。
  3. 策略对参数不敏感,容易优化。

风险及解决方法

该策略也面临一定的风险,主要集中在两个方面:

  1. 反转失败风险。反转信号本身依赖的就是统计套利机会,不排除个别反转失败的概率。可以通过降低仓位,或设置止损来控制风险。
  2. 多头行情下的亏损风险。策略整体上仍以逆市操作为主,在多头行情下难免会出现一定亏损。这需要我们对大趋势判断要准确,必要时通过人工干预来跳过不利的行情环境。

优化方向

本策略后续需要从以下几个方面进行优化:

  1. 测试不同品种,寻找最佳参数组合。策略对参数并不敏感,但仍建议针对不同品种寻找最优参数。
  2. 增加自适应退出机制。可以测试加入动态止损、时间退出等方式,使策略更适应市场的变化。
  3. 引入机器学习算法。可以尝试让模型学习判断反转成功的概率,从而提高策略胜率。

总结

本策略整体而言是一个短线反转策略。利用RSI指标判断超买超卖的能力,同时借助多种辅助工具进行多因子验证,从而提高了信号的质量。该策略捕捉效率高,稳定性也较好。值得进一步测试和优化,最终实现盈利。

||

Overview

This strategy uses the RSI indicator to identify overbought and oversold conditions, and enters trades combining multiple auxiliary factors such as MACD, Stochastic indicators, etc. The goal of this strategy is to capture short-term reversal opportunities. It belongs to mean reversion strategies.

How it Works

The core logic of this strategy relies mainly on the RSI indicator to determine whether the market is in an overbought or oversold state. When the RSI indicator exceeds the set overbought threshold, it is a sign that the market may be overbought. The strategy will choose to short at this time. When the RSI falls below the oversold threshold, it indicates the market may be oversold. The strategy will go long in such cases. By capturing the short-term trading opportunities during the transition from one extreme condition to another, the strategy hopes to profit.

In addition, the strategy also incorporates multiple auxiliary factors such as MACD, Stochastic indicators. The role of these auxiliary factors is to filter out some potentially false positive trading signals. Only when the RSI indicator triggers a signal, and the auxiliary factors also endorse that signal, will the strategy take actual trading actions. Such collaborations between multiple factors can improve the reliability of the trading signals generated by the strategy, thus enhancing its stability.

Advantage Analysis

The biggest advantage of this strategy is its high capturing efficiency realized through a multi-factor confirmation mechanism to improve signal quality. Specifically, it is reflected in the following aspects:

  1. The RSI indicator itself has strong capabilities of identifying market regimes and overextended conditions.
  2. With the help of multiple auxiliary tools for multi-factor confirmation, the signal quality is improved and large amounts of false positives are filtered out.
  3. The strategy is not sensitive to parameters and is easy to optimize.

Risks and Solutions

There are still some risks associated with this strategy, which are mainly concentrated in two aspects:

  1. Failed reversal risk. Reversal signals themselves rely on statistical arbitrage opportunities, and there is still probability for individual failed reversals. We can control risks by reducing position sizes or setting stop losses.
  2. Loss risk in uptrends. The strategy is still mainly contrarian, inevitably leading to certain losses in upward trending markets. This requires us to accurately judge the major trend. If necessary, manual intervention can be introduced to skip unfavorable market environments.

Optimization Directions

The following aspects need to be optimized for this strategy going forward:

  1. Test on different products to find the optimal parameter combinations. Although not very sensitive, it is still advisable to search for the best parameters for different products.
  2. Introduce adaptive exit mechanisms. Approaches like dynamic stops, timed exits etc. can be tested to make the strategy more adaptive to evolving markets.
  3. Incorporate machine learning models. Models can be trained to estimate reversal success probabilities in order to improve the strategy's winning rate.

Conclusion

In conclusion, this is a short-term mean reversion strategy. By leveraging RSI’s capabilities of gauging overbought/oversold conditions, and combining multiple auxiliary tools for multi-factor confirmation, the signal quality is improved. The strategy has high capturing efficiency and good stability. It deserves further testing and optimization for eventual profitability.

[/trans]

Strategy Arguments

Argument Default Description
v_input_1 timestamp(01 April 2021 00:00 -0500) Start Time
v_input_2 timestamp(31 December 2021 00:00 -0600) Start Time
v_input_3 0 Strategy: Long/Short
v_input_4 10 Stop Loss %
v_input_5 20 Target Profit %
v_input_6 14 RSI Length
v_input_7 52 Overbought Lookback Minimum Value
v_input_8 25 Overbought Lookback Bars
v_input_9 50 Oversold Lookback Minimum Value
v_input_10 35 Oversold Lookback Bars
v_input_11_close 0 Source: close
v_input_12 62 Overbought
v_input_13 35 Oversold
v_input_14 9 Look Back Bars
v_input_15_high 0 High Source: high
v_input_16_low 0 Low Source: low
v_input_17 Curernt or Higher time frame only
v_input_18 3 K
v_input_19 3 D
v_input_20 0 K Mode: SMA
v_input_21 5 EMA Fast Length
v_input_22 10 EMA Slow Length
v_input_23 true Show Bullish/Bearish Zones
v_input_24 true Show Stochastic Overlays
v_input_25 true Show RSI Buy Sell Zones
v_input_26 true Show MACD
v_input_27 true Color Bars
v_input_28 false Use RSI crossing back, select only one
v_input_29 false Use MACD Only, select only one
v_input_30 false Use Tweaked Connors RSI, select only one

Source (PineScript)

/*backtest
start: 2022-12-05 00:00:00
end: 2023-03-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=4

strategy(shorttitle='Ain1',title='All in One Strategy', overlay=true, initial_capital = 1000, process_orders_on_close=true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type=strategy.commission.percent, commission_value=0.18, calc_on_every_tick=true)

kcolor = #0094FF
dcolor = #FF6A00



// -----------------  Strategy Inputs -------------------------------------------------------------
//Backtest dates with auto finish date of today
start = input(defval = timestamp("01 April 2021 00:00 -0500"), title = "Start Time", type = input.time)
finish = input(defval = timestamp("31 December 2021 00:00 -0600"), title = "Start Time", type = input.time)
window()  => true


// Strategy Selection - Long, Short, or Both
strat = input(title="Strategy", defval="Long/Short", options=["Long Only", "Long/Short", "Short Only"])
strat_val = strat == "Long Only" ? 1 : strat == "Long/Short" ? 0 : -1

// Risk Management Inputs
sl= input(10.0, "Stop Loss %", minval = 0, maxval = 100, step = 0.01)
stoploss = sl/100
tp = input(20.0, "Target Profit %", minval = 0, maxval = 100, step = 0.01)
TargetProfit = tp/100

// RSI and Stochastic Inputs
length = input(14, "RSI Length", minval=1)
ob_min = input(52, "Overbought Lookback Minimum Value", minval=0, maxval=200)
ob_lb = input(25, "Overbought Lookback Bars", minval=0, maxval=100)
os_min = input(50, "Oversold Lookback Minimum Value", minval=0, maxval=200)
os_lb = input(35, "Oversold Lookback Bars", minval=0, maxval=100)
source = input(title="Source", type=input.source, defval=close)
RSI = rsi(source, length)

// Define f_print function to show key recommendations for RSI
// f_print(_text) =>
//     // Create label on the first bar.
//     var _label = label(na),
//     label.delete(_label), 
//     _label := label.new(
//      time + (time-time[1]), 
//      ohlc4,
//      _text,
//      xloc.bar_time,
//      yloc.price,
//      color(na),
//      label.style_none,
//      color.gray,
//      size.large,
//      text.align_left
//      )
    

    
// Display highest and lowest RSI values

AvgHigh(src,cnt,val) =>
    total = 0.0
    count = 0
    for i = 0 to cnt
        if src[i] > val
            count := count + 1
            total := total + src[i]
    round(total / count)
    
RSI_high = AvgHigh(RSI, ob_lb, ob_min)

AvgLow(src,cnt,val) =>
    total = 0.0
    count = 0
    for i = 5 to cnt by 5
        if src[i] < val
            count := count + 1
            total := total + src[i]
    round(total / count)

RSI_low = AvgLow(RSI, os_lb, os_min)


// f_print("Recommended RSI Settings:" + "\nOverbought = " + tostring(RSI_high) + "\nOversold = " + tostring(RSI_low))


overbought= input(62, "Overbought")
oversold= input(35, "Oversold")


// Price Movement Inputs
look_back = input(9,"Look Back Bars")
high_source = input(high,"High Source")
low_source= input(low,"Low Source")
HTF = input("","Curernt or Higher time frame only", type=input.resolution)

// EMA and SMA Background Inputs
smoothK     = input(3, "K", minval=1)
smoothD     = input(3, "D", minval=1)
k_mode      = input("SMA", "K Mode", options=["SMA", "EMA", "WMA"])

// MACD Inputs
fastLength = input(5, minval=1, title="EMA Fast Length")
slowLength = input(10, minval=1, title="EMA Slow Length")

// Selections to show or hide the overlays
showZones = input(true, title="Show Bullish/Bearish Zones")
showStoch = input(true, title="Show Stochastic Overlays")
showRSIBS = input(true, title="Show RSI Buy Sell Zones")
showMACD = input(true, title="Show MACD")
color_bars=input(true, "Color Bars")
useXRSI = input(false, "Use RSI crossing back, select only one")
useMACD = input(false, "Use MACD Only, select only one")
useCRSI = input(false, "Use Tweaked Connors RSI, select only one")


// ------------------ Background Colors based on EMA Indicators -----------------------------------
// Uses standard lengths of 9 and 21, if you want control delete the constant definition and uncomment the inputs
haClose(gap) => (open[gap] + high[gap] + low[gap] + close[gap]) / 4
rsi_ema = rsi(haClose(0), length)
v2 = ema(rsi_ema, length)                                                
v3 = 2 * v2 - ema(v2, length)  
emaA = ema(rsi_ema, fastLength)                                     
emaFast = 2 * emaA - ema(emaA, fastLength)
emaB = ema(rsi_ema, slowLength)                                     
emaSlow = 2 * emaB - ema(emaB, slowLength)  

// bullish signal rule: 
bullishRule =emaFast > emaSlow
// bearish signal rule: 
bearishRule =emaFast < emaSlow

// current trading State
ruleState = 0
ruleState := bullishRule ? 1 : bearishRule ? -1 : nz(ruleState[1])
bgcolor(showZones ? ( ruleState==1 ? color.blue : ruleState==-1 ? color.red : color.gray ) : na , title=" Bullish/Bearish Zones", transp=95)


// ------------------  Stochastic Indicator Overlay -----------------------------------------------

// Calculation
// Use highest highs and lowest lows
h_high = highest(high_source ,look_back)
l_low = lowest(low_source ,look_back)

stoch = stoch(RSI, RSI, RSI, length)
k =
 k_mode=="EMA" ? ema(stoch, smoothK) :
 k_mode=="WMA" ? wma(stoch, smoothK) :
 sma(stoch, smoothK)
d = sma(k, smoothD)
k_c = change(k)
d_c = change(d)
kd = k - d

// Plot
signalColor = k>oversold and d<overbought and k>d and k_c>0 and d_c>0 ? kcolor : 
 k<overbought and d>oversold and k<d and k_c<0 and d_c<0 ? dcolor : na
kp = plot(showStoch ? k : na, "K", transp=80, color=kcolor)
dp = plot(showStoch ? d : na, "D", transp=80, color=dcolor)
fill(kp, dp, color = signalColor, title="K-D", transp=88)
signalUp = showStoch ? not na(signalColor) and kd>0 : na
signalDown = showStoch ? not na(signalColor) and kd<0 : na
plot(signalUp ? kd : na, "Signal Up", color=kcolor, transp=90, style=plot.style_columns)
plot(signalDown ? (kd+100) : na , "Signal Down", color=dcolor, transp=90, style=plot.style_columns, histbase=100)


// -------------- Add Price Movement to Strategy for better visualization -------------------------
// Calculations
h1 = vwma(high, length)
l1 = vwma(low, length)
hp = h_high[1]
lp = l_low[1]

// Plot
var plot_color=#353535
var sig = 0
if (h1 >hp)
    sig:=1
    plot_color:=color.lime
else if (l1 <lp)
    sig:=-1
    plot_color:=color.maroon
plot(1,title = "Price Movement Bars", style=plot.style_columns,color=plot_color)
plot(sig,title="Signal 1 or -1",display=display.none)



// --------------------------------------- RSI Plot ----------------------------------------------
// Plot Oversold and Overbought Lines
over = hline(oversold, title="Oversold", color=color.green)
under = hline(overbought, title="Overbought", color=color.red)
fill(over, under, color=#9915FF, transp=90, title="Band Background")


// Show RSI and EMA crosses with arrows and RSI Color (tweaked Connors RSI)
// Improves strategy setting ease by showing where EMA 5 crosses EMA 10 from above to confirm overbought conditions or trend reversals
// This shows where you should enter shorts or exit longs

// Tweaked Connors RSI Calculation
connor_ob = 80
connor_os = 20
ma3 = sma(close,3)
ma20 = sma(close, 20)
ma50 = sma(close, 50)
erection = ((((close[1]-close[2])/close[2]) + ((close[0]-close[1])/close[1]))/2)*100

// Buy Sell Zones using tweaked Connors RSI (RSI values of 80 and 20 for Crypto as well as ma3, ma20, and ma50 are the tweaks)
RSI_SELL = ma20 > ma50 and open > ma3 and RSI >= connor_ob and erection <=4 and window()
RSI_BUY = ma20 < ma50 and ma3 > close and RSI <= connor_os and window()

// Color Definition
col = useCRSI ? (close > ma20 and close < ma3 and RSI <= connor_os ? color.lime : close < ma20 and close > ma3 and RSI <= connor_ob ? color.red : color.yellow ) : color.yellow

// Plot colored RSI Line
plot(RSI, title="RSI", linewidth=3, color=col)


// Shape Plots
plotshape(showRSIBS ? RSI_BUY: na, title = "RSI Buy", style = shape.arrowup, text = "RSI Buy", location = location.bottom, color=color.green, textcolor=color.green, size=size.small)
plotshape(showRSIBS ? RSI_SELL: na, title = "RSI Sell", style = shape.arrowup, text = "RSI Sell", location = location.bottom, color=color.red, textcolor=color.red, size=size.small)


// MACD as another complement to RSI strategy
[macdLine, signalLine, _] = macd(close, fastLength, slowLength, length)

bartrendcolor = macdLine > signalLine and k > 50 and RSI > 50 ? color.teal : macdLine < signalLine and k < 50 and RSI < 50 ? color.maroon : macdLine < signalLine ? color.yellow : color.gray
barcolor(color = color_bars ? bartrendcolor : na)


MACDBuy = crossover(macdLine, signalLine) and macdLine<0 and RSI<RSI_low and window()
MACDSell = crossunder(macdLine, signalLine) and macdLine>0 and RSI>RSI_high and window()

plotshape(showMACD ? MACDBuy: na, title = "MACD Buy", style = shape.arrowup, text = "MACD Buy", color=color.green, textcolor=color.green, size=size.small)
plotshape(showMACD ? MACDSell: na, title = "MACD Sell", style = shape.arrowdown, text = "MACD Sell", color=color.red, textcolor=color.red, size=size.small)
bgcolor(showMACD ? (MACDBuy ? color.teal : MACDSell ? color.maroon : na) : na, title ="MACD Signals", transp=50)


// -------------------------------- Entry and Exit Logic ------------------------------------


// Entry Logic
XRSI_OB = crossunder(RSI, overbought) and window()
RSI_OB = crossover(RSI, overbought) and window()
XRSI_OS = crossover(RSI, oversold) and window()
RSI_OS = crossunder(RSI, oversold) and window()


// Strategy Entry and Exit with built in Risk Management
GoLong = strat_val > -1 ? (useXRSI ? XRSI_OS : useMACD ? MACDBuy : useCRSI ? RSI_BUY : RSI_OS) : false

GoShort = strat_val < 1 ? (useXRSI ? XRSI_OB : useMACD ? MACDSell : useCRSI ? RSI_SELL : RSI_OB) : false

convert_percent_to_points(percent) =>
    strategy.position_size != 0 ? round(percent * strategy.position_avg_price / syminfo.mintick) : float(na)
    
setup_percent(percent) =>
    convert_percent_to_points(percent)


if (GoLong)
    strategy.entry("LONG", strategy.long)
    strategy.exit(id="Exit Long", from_entry = "LONG", loss=setup_percent(stoploss), profit=setup_percent(TargetProfit))

CloseLong = strategy.position_size > 0 ? (useXRSI ? XRSI_OB : useMACD ? MACDSell : useCRSI ? RSI_SELL : RSI_OB) : false

if(CloseLong)
    strategy.close("LONG")



if (GoShort) 
    strategy.entry("SHORT", strategy.short)
    strategy.exit(id="Exit Short", from_entry = "SHORT", loss=setup_percent(stoploss), profit=setup_percent(TargetProfit))
        
CloseShort = strat_val < 1 and strategy.position_size < 0 ? (useXRSI ? XRSI_OS : useMACD ? MACDBuy : useCRSI ? RSI_BUY : RSI_OS) : false

if(CloseShort)
    strategy.close("SHORT")



Detail

https://www.fmz.com/strategy/434435

Last Modified

2023-12-06 11:57:29