변동성 압축 브레이크업 전략

저자:차오장, 날짜: 2023년 11월 10일 11:03:25
태그:

전반적인 설명

변동성 압축 브레이크아웃 전략 (Volatility Squeeze Breakout Strategy) 은 볼링거 밴드 (BB) 와 켈트너 채널 (KC) 을 통합하여 브레이크아웃 및 트렌드 신호를 모니터링하여 주요 시장 움직임을 포착하는 거래 시스템입니다. 이 전략은 시장 압축 (저기동성) 과 후속 브레이크아웃 (고기동성) 에 초점을 맞추고 주요 가격 움직임이 시작되기 전에 시장에 진입하는 것을 목표로합니다.

전략 원칙

변동성 압축 브레이크아웃 전략의 핵심은 시장 변동성의 감소와 증가를 식별하는 것입니다. 볼링거 밴드는 가격의 표준 편차를 계산하여 형성되며 켈트너 채널은 평균 진실 범위 (ATR) 를 기반으로합니다. 볼링거 밴드가 켈트너 채널 내에서 압축되면 시장 변동성의 감소를 나타냅니다. 잠재적으로 중요한 가격 브레이크아웃으로 이어질 수 있습니다. 이 전략은 볼링거 밴드가 켈트너 채널 내에 있는지, 가격이 볼링거 밴드 한계를 넘거나 그 아래에 있는지 확인하여 거래 신호를 생성합니다. 또한 전략은 신호의 유효성을 높이기 위해 기하 운동 평균 (EMA) 의 정렬을 고려합니다.

전략 의 장점

이 전략의 주요 장점은 변동성과 트렌드 지표의 조합으로 포괄적인 시장 관점을 제공합니다. 볼링거 밴드와 켈트너 채널을 통합함으로써 전략은 잠재적인 큰 시장 움직임을 효과적으로 식별 할 수 있습니다. 또한 EMA 트렌드 정렬의 사용은 시장 방향을 확인하고 잘못된 신호를 줄이는 데 도움이 될 수 있습니다.

전략 의 위험

변동성 압축 브레이크아웃 전략의 주요 위험은 잘못된 브레이크아웃 신호와 시장 불확실성 (market uncertainty) 에 있다. 높은 변동성의 조건 하에서 볼링거 대역이 자주 깨질 수 있어 잘못된 신호가 발생할 수 있다. 또한 시장 추세가 올바르게 확인되지 않으면 전략이 불리한 거래를 일으킬 수 있다. 이러한 위험을 완화하기 위해, 전략은 매개 변수를 조정하거나 추가 지표를 통합하거나 엄격한 입시 조건을 채택함으로써 최적화될 수 있다.

최적화 방향

이 전략은 여러 가지 방법으로 최적화 될 수 있습니다.

다른 시장 조건에 적응하기 위해 볼링거 밴드 및 켈트너 채널의 매개 변수. 둘째로, 추가 거래 신호 확인을 위해 상대적 강도 지수 (RSI) 또는 이동 평균 회전 격차 (MACD) 와 같은 추가 기술 지표를 도입합니다. 마지막으로이 전략을 다른 유형의 거래 시스템과 결합하여 보다 포괄적이고 다양한 거래 틀을 형성하는 것을 고려합니다.

결론

변동성 압축 브레이크아웃 전략은 볼링거 밴드와 켈트너 채널의 강점을 결합한 강력하고 유연한 거래 시스템이다. 시장 변동성과 트렌드 신호를 모니터링함으로써 주요 시장 움직임을 효과적으로 식별 할 수 있습니다. 전략은 특정 위험을 지니고 있지만 적절한 최적화 및 매개 변수 조정으로 크게 완화 할 수 있습니다. 전반적으로이 전략은 주요 시장 트렌드와 브레이크아웃을 포착하고 활용하기위한 독특한 관점을 제공합니다.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-11-09 00:00:00
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/
// © Bishnu103

//@version=4
strategy(title="Squeeze Breakout using BB and KC [v1.0][Bishnu103]",shorttitle="BB BREAKOUT",overlay=true,calc_on_every_tick=true)

// ***********************************************************************************************************************
// input variables
bbLength            = input(title="BB Length", minval=1, defval=20)
bbStdDev            = input(title="BB StdDev", minval=1, defval=2)
kcLength            = input(title="KC Length", minval=1, defval=20)
kcMult              = input(title="KC Mult", defval=1.5)
atrLength           = input(title="ATR Length", minval=1, defval=20)
entry_distance      = input(title="Entry distance from alert", minval=1, maxval=10, defval=10)
bb_squeeze_switch   = input(title="BB Squeeze Check", type=input.bool, defval=true)
bb_squeeze_width    = input(title="BB Squeeze Width", minval=1.0, defval=3.0)
bb_in_kc_switch     = input(title="BB within KC Check", type=input.bool, defval=false)
ema_trend_switch    = input(title="EMA Trend Check", type=input.bool, defval=false)
show_bb_switch      = input(title="Show BB", type=input.bool, defval=true)
show_kc_switch      = input(title="Show KC", type=input.bool, defval=true)
show_8ema_switch    = input(title="Show 8EMA", type=input.bool, defval=true)
show_emas_switch    = input(title="Show EMAs", type=input.bool, defval=false)

// ***********************************************************************************************************************
// global variables
closed_above_bb     = false
closed_below_bb     = false

// variable values available across candles
var entry_price     = 0.0  
var sl_price        = 0.0
var exit_price_8ema = 0.0
var candle_count    = 0

// ***********************************************************************************************************************
// function to return bollinger band values based on candle poition passed 
getBB(pos) =>
    float basis = sma(close[pos], bbLength)
    float dev = bbStdDev * stdev(close[pos], bbLength)
    [basis, basis + dev, basis - dev]

// function to return Keltner Channel values based on candle poition passed 
getKC(pos) => 
    mKC     = ema(close[pos],kcLength)
    range   = kcMult * atr(atrLength)[pos]
    uKC     = mKC + range
    lKC     = mKC - range
    [mKC,uKC,lKC]

// ***********************************************************************************************************************
// strategy
//
// get current bb value
[mBB_0,uBB_0,lBB_0] = getBB(0)
[mBB_1,uBB_1,lBB_1] = getBB(1)

// if a candle closes above bb and previous candle closed inside bb then it's a bullish signal
if close[0] > uBB_0
    closed_above_bb := true
    entry_price     := high[0]

// if a candle closes above bb and previous candle closed inside bb then it's a bullish signal
if close[0] < lBB_0
    closed_below_bb := true
    entry_price     := low[0]

// check if BB is in squeeze
bb_in_squeeze = bb_squeeze_switch ? ((uBB_1 - lBB_1) < (atr(20)[1] * bb_squeeze_width)) : true

// 6 candle's bb prior to the alert candle, are within keltner channel on either upper side of the bands or on lower side of the bands
// bb
[mBB_2,uBB_2,lBB_2] = getBB(2)
[mBB_3,uBB_3,lBB_3] = getBB(3)
[mBB_4,uBB_4,lBB_4] = getBB(4)
[mBB_5,uBB_5,lBB_5] = getBB(5)
[mBB_6,uBB_6,lBB_6] = getBB(6)
// kc
[mKC_1,uKC_1,lKC_1] = getKC(1)
[mKC_2,uKC_2,lKC_2] = getKC(2)
[mKC_3,uKC_3,lKC_3] = getKC(3)
[mKC_4,uKC_4,lKC_4] = getKC(4)
[mKC_5,uKC_5,lKC_5] = getKC(5)
[mKC_6,uKC_6,lKC_6] = getKC(6)
// check if either side 6 candle's bb are inside kc
lower_squeeze_is_good = uBB_1   < uKC_1 and uBB_2 < uKC_2 and uBB_3 < uKC_3 and uBB_4 < uKC_4 and uBB_5 < uKC_5 and uBB_6 < uKC_6
upper_squeeze_is_good = lBB_1   > lKC_1 and lBB_2 > lKC_2 and lBB_3 > lKC_3 and lBB_4 > lKC_4 and lBB_5 > lKC_5 and lBB_6 > lKC_6
squeeze_is_good                 = bb_in_kc_switch ? (upper_squeeze_is_good or lower_squeeze_is_good) : true

// EMAs (8, 21, 34, 55, 89) should be aligned in sequence
ema_8               = ema(close,8)
ema_21              = ema(close,21)
ema_34              = ema(close,34)
ema_55              = ema(close,55)
ema_89              = ema(close,89)
ema_trend_check1    = ema_trend_switch and closed_above_bb and ema_8 > ema_21 and ema_21 > ema_34 and ema_34 > ema_55 and ema_55 > ema_89
ema_trend_check2    = ema_trend_switch and closed_below_bb and ema_8 < ema_21 and ema_21 < ema_34 and ema_34 < ema_55 and ema_55 < ema_89
ema_trend_check     = ema_trend_switch ? (ema_trend_check1 or ema_trend_check2) : true

// ***********************************************************************************************************************
// entry conditions 
long_entry   = closed_above_bb and bb_in_squeeze and squeeze_is_good and ema_trend_check
short_entry  = closed_below_bb and bb_in_squeeze and squeeze_is_good and ema_trend_check

candle_count := candle_count + 1
if long_entry or short_entry
    candle_count := 0
    
if long_entry or short_entry
    exit_price_8ema := na

if long_entry or short_entry
    sl_price := mBB_0

// ***********************************************************************************************************************
// exit conditions
// long trade - a candle closes below 8ema and in next candle price crosses low of previous candle
// short trade - a candle closes above 8ema and in next candle price crosses high of previous candle
long_exit_8ema    = strategy.position_size > 0 and crossunder(close,ema(close,8))
short_exit_8ema   = strategy.position_size < 0 and crossover(close,ema(close,8))

if long_exit_8ema
    exit_price_8ema := low

if short_exit_8ema
    exit_price_8ema := high

// ***********************************************************************************************************************
// position sizing
price = if close[0] > 25000
    25000
else
    price = close[0]

qty = 25000/price

// ***********************************************************************************************************************
// entry
if long_entry
    strategy.entry("BUY", strategy.long, qty, stop=entry_price, comment="BUY @ "+ tostring(entry_price)) 

if short_entry and candle_count < 11
    strategy.entry("SELL", strategy.short, qty, stop=entry_price, comment="SELL @ "+ tostring(entry_price))

if candle_count > entry_distance 
    strategy.cancel("BUY",true)
    strategy.cancel("SELL",true)

// ***********************************************************************************************************************
// exit
if strategy.position_size > 0 and long_exit_8ema
    strategy.exit("EXIT using 8EMA", "BUY", stop=exit_price_8ema, comment="EXIT @ "+ tostring(exit_price_8ema))

if strategy.position_size < 0 and short_exit_8ema
    strategy.exit("EXIT using 8EMA", "SELL", stop=exit_price_8ema, comment="EXIT @ "+ tostring(exit_price_8ema))

// ***********************************************************************************************************************
// plots    
//
// plot BB
[mBBp,uBBp,lBBp] = getBB(0)
p_mBB = plot(show_bb_switch ? mBBp : na, color=color.teal)
p_uBB = plot(show_bb_switch ? uBBp : na, color=color.teal)
p_lBB = plot(show_bb_switch ? lBBp : na, color=color.teal)
fill(p_uBB,p_lBB,color=color.teal,transp=95)

// plot KC
[mKCp,uKCp,lKCp] = getKC(0)
p_uKC = plot(show_kc_switch ? uKCp : na, color=color.red)
p_lKC = plot(show_kc_switch ? lKCp : na, color=color.red)

// plot 8 ema
plot(show_8ema_switch?ema_8:na,color=color.blue)

// plot EMAs
plot(show_emas_switch ? ema_8  : na, color=color.green)
plot(show_emas_switch ? ema_21 : na, color=color.lime)
plot(show_emas_switch ? ema_34 : na, color=color.maroon)
plot(show_emas_switch ? ema_55 : na, color=color.orange)
plot(show_emas_switch ? ema_89 : na, color=color.purple)

더 많은