볼링거 밴드 및 RSI 조합 전략

저자:차오장, 날짜: 2024-01-30 15:15:32
태그:

img

전반적인 설명

이 전략은 볼링거 밴드와 상대적 강도 지수 (RSI) 를 결합하여 볼링거 밴드가 압축되고 RSI가 상승할 때 기회를 식별하고 위험을 제어하기 위해 손해를 멈추는 것을 추적합니다.

전략 논리

이 전략의 핵심 논리는 RSI가 상승 추세에 있을 때 볼링거 밴드 압축을 식별하고 가격 파장을 예측하는 것입니다. 구체적으로, 20 기간 BB 중간 밴드 표준 편차가 ATR*2보다 작을 때, BB 압축이 발생하는 것을 결정합니다. 한편, 10 기간과 14 기간 RSI가 모두 상승하는 경우, 우리는 가격이 곧 BB 상단 범위를 넘어서 길게 갈 수 있다고 예측합니다.

시장에 진입 한 후, 우리는 ATR 안전 거리 + 적응적 스톱 로스를 사용하여 수익을 차단하고 위험을 관리합니다. 가격이 스톱 로스를 달성하거나 RSI가 과소화되면 포지션은 종료됩니다. (14 기간 RSI 70 이상 및 10 기간 RSI 14 이상).

이점 분석

이 전략의 가장 큰 장점은 BB 압축과 통합 기간을 식별하고 RSI와 브레이크오웃 방향을 예측하는 것입니다. 또한, 고정 스톱 손실보다는 시장 변동성에 기반한 적응 스톱 손실을 사용하면 위험을 제어하면서 이익을 더 잘 차단 할 수 있습니다.

위험 분석

이 전략의 주요 위험은 BB 압축 및 RSI 상승 추세를 잘못 파악하여 잘못된 브레이크오웃으로 이어질 수 있습니다. 또한, 적응 스톱 손실은 높은 변동성 중에 적시에 포지션을 닫지 못할 수 있습니다. 곡선 스톱 손실과 같은 스톱 손실 방법을 개선하면이 위험을 완화 할 수 있습니다.

최적화 지침

이 전략은 다음과 같은 측면에서 더 이상 최적화 될 수 있습니다.

  1. 더 정확하게 압축을 식별하기 위해 BB 매개 변수를 개선

  2. RSI 기간에 대한 다른 값을 테스트합니다.

  3. 곡선 SL 또는 뒤로 돌아보는 SL와 같은 다른 스톱 손실 기술을 검토하십시오.

  4. 기호 특성에 따라 매개 변수를 조정합니다.

결론

이 전략은 BB와 RSI의 상호 보완성을 활용하여 좋은 위험 조정 수익을 달성합니다. 중지 손실 및 매개 변수 조정과 같은 측면에 대한 추가 최적화는 다른 거래 도구에 더 적합 할 수 있습니다.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
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/
// © DojiEmoji
// 

//@version=4
strategy("[KL] BOLL + RSI Strategy",overlay=true,pyramiding=1)

// Timeframe {
backtest_timeframe_start = input(defval = timestamp("01 Apr 2016 13:30 +0000"), title = "Backtest Start Time", type = input.time)
USE_ENDTIME = input(false,title="Define backtest end-time (If false, will test up to most recent candle)")
backtest_timeframe_end = input(defval = timestamp("01 May 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time)
within_timeframe = true
// }

// Bollinger bands (sdv=2, len=20) {
BOLL_length = 20, BOLL_src = close, SMA20 = sma(BOLL_src, BOLL_length), BOLL_sDEV_x2 = 2 * stdev(BOLL_src, BOLL_length)
BOLL_upper = SMA20 + BOLL_sDEV_x2, BOLL_lower = SMA20 - BOLL_sDEV_x2
plot(SMA20, "Basis", color=#872323, offset = 0)
BOLL_p1 = plot(BOLL_upper, "BOLL Upper", color=color.navy, offset = 0, transp=50)
BOLL_p2 = plot(BOLL_lower, "BOLL Lower", color=color.navy, offset = 0, transp=50)
fill(BOLL_p1, BOLL_p2, title = "Background", color=#198787, transp=85)
// }

// Volatility Indicators {
ATR_x2 = atr(BOLL_length) * 2 // multiplier aligns with BOLL
avg_atr = sma(ATR_x2, input(1,title="No. of candles to lookback when determining ATR is decreasing"))
plot(SMA20+ATR_x2, "SMA20 + ATR_x2", color=color.gray, offset = 0, transp=50)
plot(SMA20-ATR_x2, "SMA20 - ATR_x2", color=color.gray, offset = 0, transp=50)
plotchar(ATR_x2, "ATR_x2", "", location = location.bottom)
//}

// Trailing stop loss {
TSL_source = low
var entry_price = float(0), var stop_loss_price = float(0)

trail_profit_line_color = color.green
if strategy.position_size == 0 or not within_timeframe
    trail_profit_line_color := color.black
    stop_loss_price := TSL_source - ATR_x2
else if strategy.position_size > 0
    stop_loss_price := max(stop_loss_price, TSL_source - ATR_x2)
plot(stop_loss_price, color=trail_profit_line_color)

if strategy.position_size > 0 and stop_loss_price > stop_loss_price[1]
	alert("Stop loss limit raised", alert.freq_once_per_bar)

// } end of Trailing stop loss

//Buy setup - Long positions {
is_squeezing = ATR_x2 > BOLL_sDEV_x2
if is_squeezing and within_timeframe and not is_squeezing[1]
	alert("BOLL bands are squeezing", alert.freq_once_per_bar)
else if not is_squeezing and within_timeframe and is_squeezing[1]
	alert("BOLL bands stopped squeezing", alert.freq_once_per_bar)

ema_trend = ema(close, 20)

concat(a, b) =>
	concat = a
	if a != ""
		concat := concat + ", "
	concat := concat + b
	concat
// }

// Sell setup - Long position {
rsi_10 = rsi(close, 10), rsi_14 = rsi(close, 14)
overbought = rsi_14 > input(70,title="[Exit] RSI(14) value considered as overbought") and rsi_10 > rsi_14
// } end of Sell setup - Long position

// MAIN: {
if within_timeframe
	entry_msg = ""
	exit_msg = ""

    // ENTRY {
	conf_count = 0	
    volat_decr = avg_atr <= avg_atr[1]
	rsi_upslope = rsi_10 > rsi_10[1] and rsi_14 > rsi_14[1]

	if volat_decr and rsi_upslope and is_squeezing and strategy.position_size == 0
		strategy.entry("Long",strategy.long, comment=entry_msg)
		entry_price := close
		stop_loss_price := TSL_source - ATR_x2
	// }

    // EXIT	{
	if strategy.position_size > 0
		bExit = false
		if close <= entry_price and TSL_source <= stop_loss_price
            exit_msg := concat(exit_msg, "stop loss [TSL]")
			bExit := true
        else if close > entry_price and TSL_source <= stop_loss_price
            exit_msg := concat(exit_msg, "take profit [TSL]")
            bExit := true
		else if overbought
			exit_msg := concat(exit_msg, "overbought")
			bExit := true

        strategy.close("Long", when=bExit, comment=exit_msg)
	// }
// }

// CLEAN UP:
if strategy.position_size == 0 and not is_squeezing
	entry_price := 0
	stop_loss_price := float(0)


더 많은