볼린저 밴드 브레이크아웃 트레이딩 전략


생성 날짜: 2023-09-12 16:23:12 마지막으로 수정됨: 2023-09-12 16:23:12
복사: 0 클릭수: 815
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

이 전략은 가격의 부린 띠 통로의 돌파 상황을 판단하여 거래한다. 이 전략은 가격의 돌파 통로로 형성되는 트렌드 거래 기회를 잡기 위해 만들어진 통로 돌파 전략의 일종이다.

전략적 원칙:

  1. 브린 벨트 통로를 계산하면, 중도선은 n일 간소 이동 평균선이며, 상하도선은 중도선의 상하도선의 몇 배 표준차이다.

  2. 가격이 위아래로 하향을 돌파할 때, 단위 입장을 취한다. 가격이 아래아래로 상향을 돌파할 때, 다수 입장을 취한다.

  3. 스톱 라인을 반대 방향으로 궤도 라인 바깥으로 설정하여 위험 통제를 수행한다.

  4. 최대 철수 상황에 따라 통로 대역폭을 조정하고, 파라미터를 최적화한다.

  5. 거래량 필터링과 함께 가짜 돌파구를 방지하기 위한 판단

이 전략의 장점:

  1. 통로를 돌파하는 것은 트렌드 전환점을 판단하는 데 효과적입니다.

  2. 브린 대수변수 최적화는 간단하고 실용적이며, 최적화하기가 쉽지 않다.

  3. 거래량과 함께 가짜 브레이크를 필터링하여 품질을 향상시킬 수 있습니다.

이 전략의 위험은:

  1. 브린은 지연 문제로 인해 가장 좋은 입구를 놓칠 수 있습니다.

  2. 파격 후 반전이 발생하기 쉽다. 합리적인 스톱 피해를 설정해야 한다.

  3. 최적화 과정에서 낮은 주파수 거래를 추구하는 것은 기회를 놓칠 수 있습니다.

요약하자면, 이 전략은 부린 띠의 돌파 상황을 판단하여 거래하고, 전형적인 통로 돌파 전략이다. 상대적으로 간단한 규칙은 파라미터를 최적화하는데 도움이 되지만, 지연과 스톱 손실 설정 문제는 여전히 경계해야 하며, 장기적으로 안정적인 수익을 얻을 수 있다.

전략 소스 코드
/*backtest
start: 2023-08-12 00:00:00
end: 2023-09-11 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2
// strategy("ChannelBreakOutStrategyV2.1", commission_type = "percent", commission_value = 0.1, calc_on_order_fills = true, overlay=true)

length = input(title="Length",  minval=1, maxval=1000, defval=40)
maxR = input(title = "R",  minval = 1.0, maxval = 10, defval = 3, step = 0.1)
adoptR = input(title = "Auto Adjust R",  defval = false)
stepR = input(title = "Step in R",  minval = 0.01, maxval = 0.1, step = 0.01, defval = 0.02)
baseYear = input(title = "Base Year",  minval = 2000, maxval = 2016, defval = 2000)
volumeTh = input(title = "Volume Threadhold",  minval = 100.0, maxval = 200, defval = 120, step = 5)
hasLong = input(title = "Include Long",  defval = true)
hasShort = input(title = "Include Short",  defval = true)
usePositionSizing = input(title = "Enable Position Sizing",  defval = true)

getTrailStop(val, current) => 
    s = val > 1.6 ? 0.8 : val >= 1.4 ? 0.85 : val >= 1.3 ? 0.9 : 0.93
    s * current


upBound = highest(high, length)
downBound = lowest(low, length)
hasVol = (volume / sma(volume, length) * 100 >= volumeTh) ? 1 : 0

hasPos = strategy.position_size != 0 ? 1 : 0

trailstop = atr(length) * 3
ptvalue = syminfo.pointvalue
equity = strategy.openprofit > 0 ? strategy.equity - strategy.openprofit : strategy.equity
curR = adoptR == false ? maxR : n == 0 ? maxR : hasPos == 1 ? curR[1] : (rising(equity,1) > 0? curR[1] + stepR : falling(equity, 1) > 0 ? curR[1] <= 2.0 ? 2.0 : curR[1] - stepR : curR[1])
contracts = usePositionSizing == false ? 20 : floor(equity / 100 * curR / (trailstop * ptvalue))

realbuystop = close - trailstop
realsellstop = close + trailstop

isPFst = (hasPos[1] == 0 and hasPos == 1) ? 1 : 0
isPOn = (hasPos[1] + hasPos == 2) ? 1 : 0
largestR = hasPos == 0 or isPFst == 1 ? -1 : nz(largestR[1]) < close ? close : largestR[1]
pctRise =  largestR / strategy.position_avg_price

rbs = strategy.position_size <= 0 ? realbuystop : isPFst ? strategy.position_avg_price - trailstop : pctRise >= 1.3 ? getTrailStop(pctRise, largestR) : (isPOn and realbuystop > rbs[1] and close > close[1]) ? realbuystop : rbs[1]
rss = strategy.position_size >= 0 ? realsellstop : isPFst ? strategy.position_avg_price + trailstop : (isPOn and realsellstop < rss[1] and close < close[1]) ? realsellstop : rss[1]

isStart = na(rbs) or na(rss) ? 0 : 1
buyARun = close - open > 0 ? 0 : open - close
sellARun = open - close > 0 ? 0 : close - open

if (strategy.position_size > 0 and buyARun >= trailstop / 3 * 2 and pctRise < 1.3)
    strategy.close("buy")
    strategy.cancel("exit")
if (strategy.position_size < 0 and sellARun >= trailstop / 3 * 2)
    strategy.close("sell")
    strategy.cancel("exit")

strategy.cancel("buy")
strategy.cancel("sell")
conLong = hasLong == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("buy", strategy.long, qty = contracts, stop=upBound + syminfo.mintick * 5, comment="BUY", when = conLong)
if (rbs > high)
    strategy.close("buy")
strategy.exit("exit", "buy", stop = rbs, when = hasPos == 1 and isStart == 1)

conShort = hasShort == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("sell", strategy.short, qty = contracts, stop=downBound - syminfo.mintick * 5, comment="SELL", when = conShort)
if (rss < low)
    strategy.close("sell")
strategy.exit("exit", "sell", stop = rss, when = hasPos == 1 and isStart == 1)

plot(series = rbs, color=blue)
plot(series = realbuystop, color=green)
plot(series = rss, color=red)
plot(series = realsellstop, color=yellow)