100일 이동평균 최적화와 결합된 트리플 표준편차 볼린저 밴드 돌파 양적 거래 전략

MA BB SMA SD
생성 날짜: 2024-12-13 11:20:13 마지막으로 수정됨: 2024-12-13 11:20:13
복사: 3 클릭수: 483
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

100일 이동평균 최적화와 결합된 트리플 표준편차 볼린저 밴드 돌파 양적 거래 전략

개요

이 전략은 부린 띠 돌파구를 기반으로 한 양적 거래 전략으로, 3배의 표준 차이의 상단 궤도와 1배의 표준 차이의 하단 궤도를 사용하며, 100일 이동 평균을 중간 궤도로 결합한다. 이 전략은 주로 가격 돌파구를 감지하여 장기 트렌드를 포착하고, 하단 궤도를 중지 신호로 사용한다. 전략의 핵심 아이디어는 강력한 돌파구 때 진입하고, 가격이 하단 궤도에서 떨어질 때 적시에 손실을 멈추고, 따라서 위험을 통제할 수 있는 트렌드 추적을 구현한다.

전략 원칙

이 전략의 핵심 원칙은 브린 반지의 통계학적 특성에 기반한 것이다. 상반도의 3배 표준 차이는 정규 배포 가설에 따라 가격이 상반도를 돌파할 확률이 0.15%에 불과하기 때문에 돌파구가 발생했을 때 눈에 띄는 추세가 형성되는 것을 암시한다. 중반도는 100일 이동 평균을 사용하며, 이 기간은 단기 시장 소음을 효과적으로 필터링 할 수 있다. 하반도는 1배 표준 차이를 사용하며, 상반대의 상반선을 사용하며, 이 설정은 상대적으로 보수적이며, 상반되는 손실을 막는 데 도움이 된다.

전략적 이점

  1. 트렌드 포착 능력: 표준 차이의 3배의 설정을 통해 중요한 트렌드 돌파 기회를 효과적으로 포착할 수 있다.
  2. 위험 제어 합리적인: 표준 차이의 1배를 중지 라인으로 사용하고, 위험 제어에 대해 보수적이다.
  3. 매개 변수는 조정가능하다: 상하의 표준 차차 배수와 이동 평균 주기들은 시장의 특성에 따라 조정될 수 있다.
  4. 체계성 강: 전략 논리가 명확하고, 역추적 기능이 완성되어, 거래 성과를 정확하게 통계할 수 있다.
  5. 폭넓은 적용성: 주식 시장과 암호화폐 시장 등 여러 분야에 적용할 수 있다.

전략적 위험

  1. 가짜 브레이크 위험: 시장은 짧은 시간 동안의 브레이크 이후 급격한 회귀가 발생할 수 있으며, 이는 가짜 신호로 이어질 수 있습니다.
  2. 큰 회수: 급격한 변동이 있는 시장에서 큰 회수가 발생할 수 있다.
  3. 지연 위험: 100일 평균선에는 지연성이 있으며, 빠른 경로를 놓칠 수 있다.
  4. 시장 환경 의존성: 불안정한 시장에서 과도한 거래 비용이 발생할 수 있습니다.

전략 최적화 방향

  1. 트랜지먼트 확인: 트랜지먼트 브레이크 확인 메커니즘을 추가하여 신호 신뢰성을 향상시킬 수 있다.
  2. 최적화 중지 메커니즘: 추적 중지 또는 ATR 동적 중지를 도입하여 손실을 줄이는 유연성을 고려할 수 있습니다.
  3. 트렌드 필터를 추가: 장기적인 트렌드를 판단하는 지표를 추가할 수 있으며, 주요 트렌드 방향으로만 거래한다.
  4. 포지션 관리를 최적화: 포지션 크기를 돌파 강도에 따라 조정할 수 있다.
  5. 시간 필터를 추가하여 특정 시장을 피할 수 있습니다.

요약하다

이것은 합리적이고 논리적으로 명확하게 설계된 트렌드 추적 전략이다. 브린 띠의 통계학적 특성과 이동 평균의 트렌드 추적 특성으로 시장의 중요한 돌파구를 효과적으로 포착할 수 있다. 약간의 회수 위험이 존재하지만, 합리적인 스톱 스팅과 위험 제어로 여전히 좋은 실용적 가치가 있다.

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

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © MounirTrades007

// @version=6
strategy("Bollinger Bands", overlay=true, initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=200)

// Get user input
var g_bb        = "Bollinger Band Settings"
upperBandSD     = input.float(title="Upper Band Std Dev", defval=3.0, tooltip="Upper band's standard deviation multiplier", group=g_bb)
lowerBandSD     = input.float(title="Lower Band Std Dev", defval=1.0, tooltip="Lower band's standard deviation multiplier", group=g_bb)
maPeriod        = input.int(title="Middle Band MA Length", defval=100, tooltip="Middle band's SMA period length", group=g_bb)
var g_tester    = "Backtester Settings"
drawTester      = input.bool(title="Draw Backtester", defval=true, group=g_tester, tooltip="Turn on/off inbuilt backtester display")

// Get Bollinger Bands
[bbIgnore1, bbHigh, bbIgnore2] = ta.bb(close, maPeriod, upperBandSD)
[bbMid, bbIgnore3, bbLow]      = ta.bb(close, maPeriod, lowerBandSD)

// Prepare trade persistent variables
drawEntry   = false
drawExit    = false

// Detect bollinger breakout
if close > bbHigh and barstate.isconfirmed and strategy.position_size == 0
    drawEntry := true
    strategy.entry(id="Trade", direction=strategy.long)
    alert("Bollinger Breakout Detected for " + syminfo.ticker, alert.freq_once_per_bar_close)

// Detect bollinger sell signal
if close < bbLow and barstate.isconfirmed and strategy.position_size != 0
    drawExit := true
    strategy.close(id="Trade")
    alert("Bollinger Exit detected for " + syminfo.ticker, alert.freq_once_per_bar_close)

// Draw bollinger bands
plot(bbMid, color=color.blue, title="Middle SMA")
plot(bbHigh, color=color.green, title="Upper Band")
plot(bbLow, color=color.red, title="Lower Band")

// Draw signals
plotshape(drawEntry, style=shape.triangleup, color=color.green, location=location.belowbar, size=size.normal, title="Buy Signal")
plotshape(drawExit, style=shape.xcross, color=color.red, location=location.belowbar, size=size.normal, title="Sell Signal")

// // =============================================================================
// // START BACKTEST CODE
// // =============================================================================

// // Prepare stats table
// var table testTable = table.new(position.top_right, 2, 2, border_width=1)
// f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) =>
//     _cellText = _title + "\n" + _value
//     table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor)

// // Draw stats table
// var bgcolor = color.black
// if barstate.islastconfirmedhistory
//     if drawTester
//         dollarReturn = strategy.equity - strategy.initial_capital
//         f_fillCell(testTable, 0, 0, "Total Trades:", str.tostring(strategy.closedtrades), bgcolor, color.white)
//         f_fillCell(testTable, 0, 1, "Win Rate:", str.tostring(strategy.wintrades / strategy.closedtrades * 100, "##.##") + "%", bgcolor, color.white)
//         f_fillCell(testTable, 1, 0, "Equity:", "$" + str.tostring(strategy.equity, "###,###.##"), bgcolor, color.white)
//         f_fillCell(testTable, 1, 1, "Return:", str.tostring((strategy.netprofit / strategy.initial_capital) * 100, "##.##") + "%", dollarReturn > 0 ? color.green : color.red, color.white)

// // =============================================================================
// // END BACKTEST CODE
// // =============================================================================