볼링거 비율 대역 거래 전략

저자:차오장, 날짜: 2023-12-11 11:14:53
태그:

img

전반적인 설명

이 전략은 단기 브레이크아웃 시스템을 구현하기 위해 이동 평균과 ATR 기술 지표와 결합된 볼링거 밴드 지표에 기반합니다. 이 전략은 거래 신호를 생성하기 위해 새로운 최고와 최저 브레이크아웃과 결합한 과반 구매 및 과반 판매 상황을 판단하기 위해 볼링거 밴드 채널 내의 가격의 상대적 비율 위치를 계산합니다.

전략 논리

  1. 볼링거 밴드 채널을 계산하고 채널 내의 가격의 상대적 비율 위치를 계산합니다.
  2. 오픈, 클로즈, 하위 및 하위 가격의 이동 평균을 별도로 계산합니다.
  3. ATR 지표를 계산하고 ATR과 결합한 스톱 손실 라인을 설정합니다.
  4. 가격이 새로운 최고 또는 새로운 최저에 가깝는지 판단하십시오.
  5. 더 큰 시간 프레임 트렌드를 판단하기 위해 연간 최고와 최저를 결합
  6. 볼링거 밴드 비율 및 새로운 최고/하위 변화에 기초한 거래 신호를 생성합니다.

이 전략은 시장의 변동성을 판단하기 위해 볼링거 밴드 채널을 사용하며, 채널 너비는 표준 편차에 의해 결정됩니다. 가격이 하위 밴드 아래로 넘어갈 때 구매 신호가 생성되고, 가격이 상위 밴드 위로 넘어갈 때 판매 신호가 생성됩니다. 이동 평균은 볼링거 변동을 부드럽게하고 거짓 브레이크오웃을 줄일 수 있습니다. ATR 지표는 스톱 로스 스케일을 고정하기 위해 후속 스톱 로스와 결합됩니다. 새로운 최고 / 하락은 정상을 추격하고 하락을 제한하는 것을 피하는 데 도움이됩니다. 연간 최고 / 하락은 더 큰 시간 프레임 통합을 필터링합니다. 요약하면이 전략은 시장 리듬과 진입 시기를 판단하기 위해 다양한 기술 분석 도구를 결합합니다.

장점

  1. 엄격한 볼링거 밴드 브레이크아웃 필터는 잘못된 신호를 줄이는 데 도움이 됩니다.
  2. 이동 평균은 평탄한 가격과 진정한 경향을 식별
  3. ATR 지표가 동적으로 스톱 손실을 추적하고 단일 거래 손실을 제한합니다.
  4. 새로운 고도/하수와 연간 고도/하수가 신호를 더 신뢰할 수 있게 합니다.
  5. 여러 지표의 효과적인 조합은 효율성을 향상시킵니다.

위험 과 해결책

  1. 부적절한 볼링거 밴드 매개 변수는 과도한 거짓 파열을 일으킬 수 있습니다. 최상의 결과를 위해 다른 매개 변수 조합을 테스트해야합니다.
  2. 마감 가격 기준은 ATR 설정된 스톱 로스 범위를 초과하는 마감값으로 이어질 수 있습니다. 비율 계산에 더 변동적인 높은/저한 가격을 사용하는 것을 고려하십시오.
  3. 엄격한 볼링거 필터링은 장기적인 트렌드 기회를 놓칠 수 있습니다. 필터와 보유 기간을 적절히 느슨하게하십시오.
  4. ATR 지표는 큰 가격 변동을 느리게 추적합니다. 진정한 범위와 같은 더 높은 주파수 변동성을 고려하십시오.
  5. 새로운 고도/하위 파업은 단기 소음으로 쉽게 방해됩니다. 통계적 의미와 트렌드 지속 가능성을 평가합니다.

최적화 방향

  1. 최적의 볼링거 매개 변수와 이동 평균 길이를 결정하기 위해 다른 매개 변수 조합을 테스트합니다.
  2. 다른 볼링거 매개 변수 또는 이동 평균을 포함하는 모델 조합을 사용하십시오.
  3. 다양한 기간과 제품에 대한 견고성 테스트, 적응력을 향상
  4. 일일 볼린저 신호 또는 계절 요인 같은 더 높은 시간 프레임 신호를 포함
  5. 트렌드를 따라 전략 커버 및 수익성을 확장 할 수있는 기회를 평가합니다.

결론

이 전략은 상대적으로 엄격하고 효율적인 단기 브레이크아웃 거래 시스템을 구축하기 위해 볼링거 비율 대역, 이동 평균, ATR 지표, 새로운 최고/하위 및 연간 최고/하위 등을 효과적으로 결합합니다. 그것의 탁월한 장점은 잡음을 줄이고 진정한 트렌드 신호를 식별하기 위해 다양한 도구를 사용하는 데 있습니다. 물론 전략은 또한 엄격한 조건 하에서 몇 가지 매개 변수 조정 어려움과 놓친 기회를 직면합니다. 전반적으로 그것은 더 많은 연구와 실제 거래 데이터에 대한 검증을 보장하는 독특한 거래 스타일과 고효율의 볼링거 브레이크아웃 전략을 나타냅니다.


/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Bollinger %B Candles Strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

BBLength = input(100, minval=1, step=1)
StdDev = 10
useMovingAverage = input(true)
MAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
lookbackPeriod = input(22, minval=10, step=10)
colorByPreviousClose = input(true)

AtrMAType = input(title="Moving Average Type", defval="hma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(10)
AtrMult = input(4)
wicks = input(false)

considerYearlyHighLow = input(false)
considerNewLongTermHighLows = input(false)
shortHighLowPeriod = 100
longHighLowPeriod = 200
tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])

backtestYears = input(10, minval=1, step=1)


//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
    newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
    newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
    [newHigh,newLow]

//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
    yhigh = security(syminfo.tickerid, '12M', high[1]) 
    ylow = security(syminfo.tickerid, '12M', low[1]) 
    yhighlast = yhigh[365]
    ylowlast = ylow[365]
    yhighllast = yhigh[2 * 365]
    ylowllast = ylow[2 * 365]
    
    yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
    yearlyHighCondition = (  (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
    yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
    yearlyLowCondition = (  (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
    
    label_x = time+(60*60*24*1000*1)
    [yearlyHighCondition,yearlyLowCondition]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

inDateRange = true
[yearlyHighCondition,yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHighS,newLowS] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)
[middleclose, upperclose, lowerclose] = bb(close, BBLength, StdDev)
[middleopen, upperopen, loweropen] = bb(open, BBLength, StdDev)
[middlehigh, upperhigh, lowerhigh] = bb(high, BBLength, StdDev)
[middlelow, upperlow, lowerlow] = bb(low, BBLength, StdDev)

percentBClose = (close - lowerclose)*100/(upperclose-lowerclose)
percentBOpen = (open - loweropen)*100/(upperopen-loweropen)
percentBHigh = (high - lowerhigh)*100/(upperhigh-lowerhigh)
percentBLow = (low - lowerlow)*100/(upperlow-lowerlow)

percentBMAClose = f_getMovingAverage(percentBClose, MAType, lookbackPeriod)
percentBMAOpen = f_getMovingAverage(percentBOpen, MAType, lookbackPeriod)
percentBMAHigh = f_getMovingAverage(percentBHigh, MAType, lookbackPeriod)
percentBMALow = f_getMovingAverage(percentBLow, MAType, lookbackPeriod)

newOpen = useMovingAverage? percentBMAOpen : percentBOpen
newClose = useMovingAverage? percentBMAClose : percentBClose
newHigh = useMovingAverage? percentBMAHigh : percentBHigh
newLow = useMovingAverage? percentBMALow : percentBLow

truerange = max(newHigh, newClose[1]) - min(newLow, newClose[1])

averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
atr = averagetruerange * AtrMult

longStop = newClose - atr
longStopPrev = nz(longStop[1], longStop)
longStop := (wicks ? newLow[1] : newClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop

shortStop = newClose + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := (wicks ? newHigh[1] : newClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and (wicks ? newHigh : newClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? newLow : newClose) < longStopPrev ? -1 : dir

trailingStop = dir == 1? longStop : shortStop

candleColor = colorByPreviousClose ?
                 (newClose[1] < newClose ? color.green : newClose[1] > newClose ? color.red : color.silver) : 
                 (newOpen < newClose ? color.green : newOpen > newClose ? color.red : color.silver)
plotcandle(newOpen, newHigh, newLow, newClose, title='PercentBCandle', color = candleColor, wickcolor=candleColor)
plot(trailingStop, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= dir == 1 ? color.green : color.red)

buyCondition = dir==1 and yearlyHighCondition and newHighS
exitBuyCondition = dir == -1
sellCondition = dir == -1 and yearlyLowCondition and newLowS
exitSellCondition = dir == 1
strategy.risk.allow_entry_in(tradeDirection)

barcolor(buyCondition? color.lime : sellCondition ? color.orange : color.silver)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca_buy")
strategy.close("Buy", when=exitBuyCondition)

strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca_sell")
strategy.close("Sell", when=exitSellCondition)

더 많은