이 전략은 통합 구역과 브레이크아웃 신호를 식별하기 위해 이중 볼링거 밴드를 사용하여 낮은 구매-높은 판매 거래 전략을 구현합니다. 가격이 중립 구역을 통과하면 새로운 트렌드의 시작과 긴 지점에 들어가는 시간을 신호합니다. 가격이 중립 구역 아래로 넘어지면 트렌드의 끝과 포지션을 닫는 시간을 신호합니다.
이 전략은 두 개의 볼링거 밴드를 사용한다. 내부 BB는 20SMA ± 1 표준 편차의 상부/하부 밴드를 가지고 있다. 외부 BB는 20SMA ± 2 표준 편차의 상부/하부 밴드를 가지고 있다. 두 BB 사이의 영역은 중립 구역으로 정의된다.
가격이 두 개의 연속적인 중립 구역 촛불에서 중립 구역 내에 머무르면 통합으로 간주됩니다. 두 개의 연속적인 중립 구역 촛불 후에 가격이 내부 BB의 상단 위에 닫을 때 긴 신호가 생성됩니다.
장래에 들어가면 최저 가격 - 2xATR로 수익을 차단하고 위험을 제어합니다. 가격이 내부 BB의 상단 이하로 떨어지면 포지션은 닫습니다.
이 전략은 통합 구역을 식별하고 트렌드 시작을 결정하기 위해 지표와 트렌드를 결합하여 큰 수익 잠재력을 가진 낮은 구매-대 판매 거래를 허용합니다. 스톱 로스 전략은 수익을 차단하고 안정성을 향상시킵니다.
이 전략은 허위 브레이크오웃으로 판명될 수 있는 브레이크오웃 신호에 의존하며, 이로 인해 트레이드를 잃게 됩니다. 또한, 너무 긴 스톱은 조기 청산될 위험이 있습니다.
해결책은 BB 매개 변수를 최적화하고, 잘못된 신호를 줄이기 위해 필터를 추가하고, 더 넓은 정지를 허용하는 것을 포함한다.
이 전략은 이중 BB와 트렌드 전략을 통합하여 큰 수익 잠재력을 가진 낮은 구매-고량 판매 거래를 수행합니다. 스톱 로스 전략은 또한 안정성을 향상시킵니다. 추가 최적화는 라이브 거래에 대한 전략 성능을 향상시킬 수 있습니다.
/*backtest start: 2022-12-06 00:00:00 end: 2023-12-12 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/ // © DojiEmoji //@version=4 strategy("[KL] Double BB Strategy",overlay=true,pyramiding=1) ENUM_LONG = "LONG" // Timeframe { backtest_timeframe_start = input(defval = timestamp("01 Apr 2020 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("19 Apr 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time) within_timeframe = true // } // Bollinger bands BOLL_length = 20, BOLL_src = close, SMA20 = sma(BOLL_src, BOLL_length) BOLL_sDEV = stdev(BOLL_src, BOLL_length) BOLL_upper1 = SMA20 + BOLL_sDEV, BOLL_lower1 = SMA20 - BOLL_sDEV BOLL_upper2 = SMA20 + BOLL_sDEV*2, BOLL_lower2 = SMA20 - BOLL_sDEV*2 SMA_20_plot = plot(SMA20, "Basis", color=#872323, offset = 0) BOLL_upper1_plot = plot(BOLL_upper1, "BOLL Upper1", color=color.navy, offset = 0, transp=50) BOLL_lower1_plot = plot(BOLL_lower1, "BOLL Lower1", color=color.navy, offset = 0, transp=50) BOLL_upper2_plot = plot(BOLL_upper2, "BOLL Upper2", color=color.navy, offset = 0, transp=50) BOLL_lower2_plot = plot(BOLL_lower2, "BOLL Lower2", color=color.navy, offset = 0, transp=50) fill(BOLL_upper2_plot, BOLL_upper1_plot, title = "Background", color=#198787, transp=85) fill(BOLL_upper1_plot, SMA_20_plot, title = "Background", color=#198787, transp=75) fill(SMA_20_plot, BOLL_lower1_plot, title = "Background", color=#198787, transp=75) fill(BOLL_lower1_plot, BOLL_lower2_plot, title = "Background", color=#198787, transp=85) // Trailing stop loss { ATR_X2_TSL = atr(input(14,title="Length of ATR for trailing stop loss")) * input(2.0,title="ATR Multiplier for trailing stop loss",type=input.float) TSL_source = low var stop_loss_price = float(0) TSL_line_color = color.green, TSL_transp = 100 if strategy.position_size == 0 or not within_timeframe TSL_line_color := color.black stop_loss_price := TSL_source - ATR_X2_TSL else if strategy.position_size > 0 stop_loss_price := max(stop_loss_price, TSL_source - ATR_X2_TSL) TSL_transp := 0 plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp)) // } // Signals for entry is_neutral = close < BOLL_upper1 and close > BOLL_lower2 is_consol = is_neutral and is_neutral[2] entry_signal = is_consol[1] and close > BOLL_upper1 // MAIN: if within_timeframe // EXIT :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit" end_of_rally = close < BOLL_upper1 and strategy.position_avg_price > stop_loss_price // also detects false breakouts if strategy.position_size > 0 and (TSL_source <= stop_loss_price or end_of_rally) strategy.close(ENUM_LONG, comment=exit_msg) // ENTRY ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: if (strategy.position_size == 0 or (strategy.position_size > 0 and close > stop_loss_price)) and entry_signal entry_msg = strategy.position_size > 0 ? "adding" : "initial" strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg) // CLEAN UP: if strategy.position_size == 0 stop_loss_price := float(0)