볼링거 웨이브 전략 (영어: Bollinger Wave Strategy) 은 볼링거 웨이브와 이동 평균을 결합한 양적 거래 전략이다. 이 전략은 볼링거 웨이브의 표준 격차와 이동 평균의 교차 신호를 계산하여 시장의 추세와 오버 바이 오버 셀 영역을 판단하여 거래 신호를 생성한다.
이 전략은 먼저 지정된 주기 내의 지수 이동 평균 ((EMA) 을 기준선으로 계산한다. 그리고 이 EMA를 기반으로 상도선 ((EMA + n배 표준차) 과 하도선 ((EMA - n배 표준차) 을 계산한다. 가격이 상도선을 돌파할 때 오버 바이 신호로, 가격이 하도선을 넘어갈 때 오버 셀 신호로 사용한다.
가격이 상도선과 하도선 사이에 있을 때, 주식의 정상적인 가격 변동 영역이다. 또한, 이 전략은 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')