볼링거 웨이브 전략 (Bollinger Wave Strategy) 은 볼링거 밴드와 이동 평균을 결합한 양적 거래 전략이다. 이는 시장 추세와 과잉 구매/ 과잉 판매 영역을 결정하기 위해 볼링거 밴드의 표준편차와 이동 평균의 크로스오버를 계산하여 거래 신호를 생성한다.
이 전략은 먼저 기준으로 지정된 기간 동안 기하급수적인 이동 평균 (EMA) 을 계산합니다. 상단 (EMA + n × 표준편차) 및 하단 (EMA - n × 표준편차) 는 이 EMA를 기반으로 계산됩니다. 상단 이상의 파업은 과소매 신호를 나타냅니다. 하단단 아래의 파업은 과소매 신호를 나타냅니다.
가격이 상위 및 하위 대역 사이에 있을 때, 그것은 주식의 정상적인 가격 변동 범위입니다. 또한, 전략은 RSI와 같은 다른 지표를 결합하여 거래 신호를 필터하고 불필요한 손실을 최소화하기 위해 거래 빈도를 줄입니다.
특히 거래 신호 규칙은 다음과 같습니다.
위의 거래 신호가 나타나면 고정량 또는 계정 비율로 포지션을 취합니다. 가격이 반역으로 다시 이동하거나 반대 신호가 나타나면 출구 포지션을 취합니다.
이 전략은 유행 결정과 과잉 구매/ 과잉 판매 판단을 결합하여 범위 제한 시장에서 잘못된 거래를 피합니다. 단일 지표 전략에 비해 불필요한 포지션 개척을 줄이고 위험을 효과적으로 제어 할 수 있습니다.
간단한 이동 평균 전략에 비해 볼링거 밴드는 현재의 시장 변동성과 위험 수준을 더 잘 반영합니다. 밴드 폭이 작을 때 거래 신호가 더 신뢰할 수 있습니다. 밴드 폭이 크면 거래 빈도가 자동으로 감소합니다. 이러한 적응 조정은 다른 시장 조건에 따라 전략 위험을 제어 할 수 있습니다.
또한, RSI 및 다른 지표의 이중 확인은 일부 잘못된 신호를 필터링하고 트렌드 전환점에 대한 잘못된 거래를 피하는 데 도움이됩니다. 이것은 또한 전략의 승률을 향상시킵니다.
이 전략의 주요 위험은 다음과 같습니다.
매개 변수 최적화 위험. 이동 평균 또는 표준 편차 매개 변수가 부적절하게 설정되면 더 시끄러운 거래를 생성하거나 거래 기회를 놓칠 수 있습니다. 이러한 매개 변수는 반복 테스트 및 최적화가 필요합니다.
잘못된 브레이크오웃 신호 위험. 가격이 간략하게 범위를 넘어서거나 그 아래로 넘어서 빠르게 역전되면 잘못된 신호를 생성 할 수 있습니다. 그 신호에 맹목적으로 거래하면 손실이 증가 할 것입니다. 이동 평균 기간을 증가시키거나 스톱 로스를 설정함으로써 제어 할 수 있습니다.
높은 거래 빈도 위험. 간격이 매우 좁으면 거래 수와 지불 된 수수료가 증가하여 최종 수익성에 영향을 줄 수 있습니다. 이동 평균 기간을 적당히 증가시킴으로써 완화 될 수 있습니다.
전략의 더 많은 최적화를 위한 여지가 있습니다.
스톱 로스 메커니즘을 추가합니다. 후속 스톱 로스 또는 시간 스톱 로스를 사용하면 시간으로 손실을 실현하고 단일 거래 손실 금액을 제어 할 수 있습니다.
포지션 사이즈링 규칙을 추가합니다. 예를 들어, 상거래에서 승리하고 패자를 줄이는 피라미딩. 이것은 전략 수익을 향상시킬 수 있습니다.
신호 필터링을 위해 다른 지표와 결합하십시오. KDJ 및 MACD와 같은 지표는 보조 판단 도구로 사용될 수 있습니다. 이것은 전략 수익성을 더욱 향상시키는 데 도움이됩니다.
매개 변수 설정을 최적화합니다. 유전 알고리즘과 같은 더 체계적인 방법은 다른 매개 변수 조합을 테스트하고 더 나은 설정을 찾을 수 있습니다.
볼링거 웨이브 전략은 이동 평균의 트렌드 결정과 과잉 구매 / 과잉 판매 판단을 통합합니다. 그것은 다른 시장 조건에 적응하기 위해 대역 너비 변화에 따라 거래 주파수를 조정합니다. 한편, RSI 및 기타 지표에 의한 신호 필터링은 잘못된 거래를 피합니다. 전략은 시장 트렌드를 추적하고 위험을 제어하는 것을 모두 고려합니다. 지속적인 최적화로 안정적으로 수익성이 높은 양적 거래 전략이 될 수 있습니다.
/*backtest start: 2023-01-08 00:00:00 end: 2024-01-14 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 //@FiboBuLL strategy(shorttitle='FB Wave', title='FiboBuLL Wave', overlay=true, pyramiding=1, currency=currency.NONE, initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=100) src = input(close, title='Source') length = input.int(55, minval=1, title='EMA length') // 20 for classis Bollinger Bands SMA line (basis) mult = input.float(1., minval=0.236, maxval=2, title='Standard Deviation') //2 for Classic Bollinger Bands //Maxval = 2 as higher the deviation, higher the risk basis = ta.sma(src, length) dev = mult * ta.stdev(src, length) Show = input.string('Both', options=['Longs Only', 'Shorts Only', 'Both'], title='Trade Type') CC = input(true, 'Color Bars') upper = basis + dev lower = basis - dev //Conditions for Long and Short - Extra filter condition can be used such as RSI or CCI etc. short = src < lower // and rsi(close,14)<40 long = src > upper // and rsi(close,14)>60 L1 = ta.barssince(long) S1 = ta.barssince(short) longSignal = L1 < S1 and not (L1 < S1)[1] shortSignal = S1 < L1 and not (S1 < L1)[1] //Plots and Fills ////Long/Short shapes with text // plotshape(S1<L1 and not (S1<L1)[1]?close:na, text = "sᴇʟʟ", textcolor=#ff0100, color=#ff0100, style=shape.triangledown, size=size.small, location=location.abovebar, transp=0, title = "SELL", editable = true) // plotshape(L1<S1 and not (L1<S1)[1]?close:na, text = "ʙᴜʏ", textcolor = #008000, color=#008000, style=shape.triangleup, size=size.small, location=location.belowbar, transp=0, title = "BUY", editable = true) // plotshape(shortSignal?close:na, color=#ff0100, style=shape.triangledown, size=size.small, location=location.abovebar, transp=0, title = "Short Signal", editable = true) // plotshape(longSignal?close:na, color=#008000, style=shape.triangleup, size=size.small, location=location.belowbar, transp=0, title = "Long Signal", editable = true) p1 = plot(upper, color=color.new(#ff0000, 75), display=display.all, title='Upper Band') p2 = plot(lower, color=color.new(#008000, 75), display=display.all, title='Lower Band') p = plot(basis, color=L1 < S1 ? #008000 : S1 < L1 ? #ff0000 : na, linewidth=2, editable=false, title='Basis') fill(p, p1, color=color.new(color.teal, 85), title='Top Fill') //fill for basis-upper fill(p, p2, color=color.rgb(217, 161, 161), title='Bottom Fill', transp=85) //fill for basis-lower //Barcolor bcol = src > upper ? color.new(#8ceb07, 0) : src < lower ? color.new(#ff0000, 0) : src > basis ? color.green : src < basis ? color.red : na barcolor(CC ? bcol : na, editable=false, title='Color Bars') // //Alerts ---- // Use 'Once per bar close' // alertcondition(condition=longSignal, title="Long - BB Filter", message='BB Filter Long @ {{close}}') // Use 'Once per bar close' // alertcondition(condition=shortSignal, title="Short - BB Filter", message='BB Filter Short @ {{close}}') // Use 'Once per bar close' Notestart1 = input(true, '╔═══ Time Range to BackTest ═══╗') // === INPUT BACKTEST RANGE === FromMonth = input.int(defval=1, title='From Month', minval=1, maxval=12) FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31) FromYear = input.int(defval=2018, title='From Year', minval=2015) ToMonth = input.int(defval=1, title='To Month', minval=1, maxval=12) ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31) ToYear = input.int(defval=9999, title='To Year', minval=2010) // === FUNCTION EXAMPLE === start = timestamp(FromYear, FromMonth, FromDay, 00, 00) // backtest start window finish = timestamp(ToYear, ToMonth, ToDay, 23, 59) // backtest finish window window() => time >= start and time <= finish ? true : false if window() and (Show == 'Longs Only' or Show == 'Both') strategy.entry('AL', direction=strategy.long, when=longSignal) strategy.close('LongAL', when=shortSignal, comment='AL KAPA') if window() and (Show == 'Shorts Only' or Show == 'Both') strategy.entry('SAT', direction=strategy.short, when=shortSignal) strategy.close('SAT', when=longSignal, comment='SAT KAPA')