이중 채널 추적 역전 전략

저자:차오장, 날짜: 2023-11-02 16:31:50
태그:

img

전반적인 설명

듀얼 채널 추적 역전 전략 (Dual Channel Tracking Reversal strategy) 은 볼링거 밴드, 켈트너 채널 및 추진력 지표를 결합한 역전 거래 전략이다. 볼링거 밴드 및 켈트너 채널의 합성을 통해 가격 압축 구역을 식별하고 진입 및 출구에 대한 역전 신호를 결정하기 위해 추진력 지표를 사용합니다.

전략 논리

  1. 볼링거 밴드의 중간, 상위 및 하위 대역을 계산합니다.

    • 중간 대역은 가까운 SMA를 사용합니다.
    • 상단 및 하단 대역은 중간 대역 ± 조절 가능한 표준편차 배수
  2. 켈트너 채널의 중간, 상위 및 하위 대역을 계산

    • 중간 대역은 가까운 SMA를 사용합니다.
    • 상단 및 하단 대역은 중간 대역 ± 조절 가능한 ATR 복수
  3. 볼링거 대역이 켈트너 채널 안에 있는지 확인합니다.

    • 낮은 BB > 낮은 KC와 높은 BB < 높은 KC 때 압축
    • 그렇지 않으면 꺼져
  4. BB와 KC 중점에 대한 닫는 선형 회귀 기울기 밸브를 계산

    • val > 0은 닫는 것이 증가한다는 것을 나타냅니다. val < 0은 감소한다는 것을 의미합니다.
  5. ROC의 ROC와 EMA를 계산합니다.

    • 변동률이 조정 가능한 임계값을 초과하는지 결정합니다.
    • 임계 이상은 현행 경향을 나타냅니다.
  6. 압축 상태에서, val > 0과 ROC가 임계값을 초과할 때 길다

    • 반대로 짧게는
  7. 스톱 로스 및 영업 조건 설정

장점

  1. 역전용으로 이중 채널 시스템을 결합함으로써 정확도가 향상되었습니다.

  2. 선형 회귀와 변화율을 사용하여 잘못된 신호를 피합니다.

  3. 제품 간 최적화를 위한 유연한 조정 가능한 매개 변수

  4. 스톱 로스/프로피트 취득으로 거래별로 효과적인 리스크 관리

  5. 전략의 실행 가능성을 검증하기 위한 충분한 백트테스트 데이터

위험 과 해결책

  1. 압축 하는 것 은 항상 효과적 인 역행 을 가져오지 않는다

    • 매개 변수를 최적화하고 압축 기준을 강화
  2. 가짜 탈출은 잘못된 신호를 생성합니다.

    • 트렌드 방향을 결정하기 위해 선형 회귀를 추가
  3. 너무 넓은 스톱 손실로 인해 과도한 단일 손실이 발생합니다.

    • 거래 손실에 대한 중지 손실 포인트 및 제어 최적화
  4. 불충분한 시험 기간

    • 장기적 생존성을 증명하기 위해 더 많은 기간으로 테스트를 확장

더 나은 기회

  1. 더 많은 제품에 대한 매개 변수 최적화

  2. 지원/저항 식별을 위한 기계 학습을 추가

  3. 분산 유효성을 향상시키기 위해 부피 변경을 포함합니다.

  4. 트렌드 지속성을 위해 여러 시간 프레임 분석을 수행

  5. 동적 스톱 로스/이익 취득을 최적화

결론

이중 채널 추적 역전 전략은 역전 거래를 위해 볼린거 밴드 및 켈트너 채널과 같은 지표를 사용합니다. 매개 변수 최적화로 인해 일정 범위에서 브레이크아웃 유효성을 식별하기 위해 다른 제품에서 적응 할 수 있습니다. 그러나 역전 거래는 여전히 본질적인 위험을 지니고 있으며 지속적인 초과 수익을 위해 정확성을 향상시키기 위해 기계 학습 등을 추가로 통합해야합니다.


/*backtest
start: 2023-10-02 00:00:00
end: 2023-11-01 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Credit for the initial Squeeze Momentum code to LazyBear, rate of change code is from Kiasaki
strategy("Squeeze X BF 🚀", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0)

/////////////// Time Frame ///////////////
testStartYear = input(2012, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

/////////////// Squeeeeze ///////////////
length = input(20, title="BB Length")
mult = input(2.0,title="BB MultFactor")
lengthKC=input(22, title="KC Length")
multKC = input(1.5, title="KC MultFactor")
 
useTrueRange = input(true, title="Use TrueRange (KC)")
 
// Calculate BB
source = close
basis = sma(source, length)
dev = mult * stdev(source, length)
upperBB = basis + dev
lowerBB = basis - dev

// Calculate KC
ma = sma(source, lengthKC)
range = useTrueRange ? tr : (high - low)
rangema = sma(range, lengthKC)
upperKC = ma + rangema * multKC
lowerKC = ma - rangema * multKC

sqzOn  = (lowerBB > lowerKC) and (upperBB < upperKC)
sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC)
noSqz  = (sqzOn == false) and (sqzOff == false)

val = linreg(source - avg(avg(highest(high, lengthKC), lowest(low, lengthKC)),sma(close,lengthKC)), lengthKC,0)

///////////// Rate Of Change ///////////// 
roclength = input(30, minval=1), pcntChange = input(7, minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

/////////////// Strategy ///////////////
long = val > 0 and isMoving()
short = val < 0 and isMoving()

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

sl_inp = input(100.0, title='Stop Loss %') / 100
tp_inp = input(5000.0, title='Take Profit %') / 100
 
take_level_l = strategy.position_avg_price * (1 + tp_inp)
take_level_s = strategy.position_avg_price * (1 - tp_inp)

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution ///////////////
if testPeriod()
    strategy.entry("Long",  strategy.long, when=long)
    strategy.entry("Short", strategy.short, when=short)
    strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0)
    strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0)
    
/////////////// Plotting ///////////////
bcolor = iff(val > 0, iff(val > nz(val[1]), color.lime, color.green), iff(val < nz(val[1]), color.red, color.maroon))
plot(val, color=bcolor, linewidth=4)
bgcolor(not isMoving() ? color.white : long ? color.lime : short ? color.red : na, transp=70)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=50)
hline(0, color = color.white)

더 많은