동적 가격 통로 돌파 전략은 Donchian 가격 통로 지표에 기반한 양적 거래 전략이다. 이 전략은 가격 통로의 상한선과 하한선에 따라 시장 추세 방향을 판단하고, 가격 통로 돌파 시 상장 또는 상하 입장을 수립한다.
이 전략의 주요 아이디어는 Donchan 가격 채널의 브레이커웃을 사용하는 것입니다. 가격이 채널 상한을 돌파 할 때, 다중 수다를 찾는 트렌드를 구축합니다. 가격이 채널 하한을 넘어갈 때, 다중 수다를 찾는 트렌드를 구축합니다.
가격 통로는 다음과 같은 공식으로 계산됩니다.
상한선 = 최고값의 N주기 최고값
하위선 = 최저값의 N주기 최저값
중간선 = (상한선 + 하한선) /2
여기서 N은 통로 주기 길이를 나타내고, 이 전략에서는 50을 기본으로 한다.
최신 K 라인의 최고 가격이 통로의 상한선을 돌파할 때, 더 많은 포지션을 설정합니다.
최신 K 라인의 최저 가격이 통로의 하위 경계를 넘어갈 때, 코스 포지션을 설정한다.
예를 들어:
K 선의 가장 높은 지점은 통로의 상한을 넘지 않습니다. 현재 K선 고점은 통로의 상한을 뚫고 있다. === 다중 포지션 구축 ===
두 가지 출전 규칙이 있습니다.
핑도: 통로의 최하위치인 스톱로스 가격.
평평한 상태: 정지 가격은 통로의 상한입니다.
다수점 포지션과 빈점 포지션 모두, 가격이 통로 중선 아래로 다시 떨어지면 모든 포지션을 청산한다.
리스크 제어는 비율 상쇄 방식을 채택하고, 통로 폭과 설정의 견딜 수 있는 위험 비율에 따라 구체적인 상쇄 거리를 계산한다.
더 많은 스톱 라인즈 = 입시 가격 * (1 - 위험을 감당할 수 있는 비율)
공중에서 막는 손실 거리 = 입시 가격 * (1 + 위험을 감당할 수 있는 비율)
예를 들어, 2%의 리스크를 설정하고, \(10,000의 엔트리 가격을 설정하고, \)10,000 * (1 - 2%) = $9,800의 리스크를 설정합니다.
가격이 통로의 상하계를 돌파했을 때, 새로운 방향성 추세가 시작될 가능성이 높습니다. 이 때 입장은 더 큰 가격 변화를 잡을 수 있습니다.
비율 상실을 적용하면 일회성 손실을 감당할 수 있는 범위 내에서 통제할 수 있다.
통로 주기의 길이, 위험 비율, 손해 방지 방식과 같은 파라미터는 더 많은 시장 환경에 적합하도록 최적화 할 수 있습니다.
가격의 채널 상하계를 뚫는 것은 반드시 트렌드를 형성한다는 것을 의미하지 않으며, 실패한 뚫림의 확률이 존재하며, 이때 손해가 발생할 수 있다.
시장이 폭 폭이 흔들릴 때, 가격이 채널 상하계를 자주 유발할 수 있으며, 이는 거래가 너무 자주 거래되어 거래비용과 슬라이드 포인트가 손실됩니다.
가격 채널의 길이를 변수로 고려하여 시장의 변동에 따라 자동으로 조정할 수 있습니다. 시장의 흔들림이 있을 때 채널 길이를 늘리고, 추세가 명확할 때 채널 길이를 줄일 수 있습니다.
다른 지표의 필터링 시점과 결합하여, 예를 들어, 양 에너지 지표, 이동 평균 등으로, 충격적인 상황에서 무효 돌파를 피한다.
더 많은 역사적 데이터를 사용하여 파라미터 조합을 테스트 최적화하여 보다 광범위한 시장 상황에 맞는 최적의 파라미터를 결정합니다.
동적 가격 통로 전략은 전반적으로 더 간단하고 직관적인 트렌드 추적 전략이다. 그것의 장점은 표시가 명확하고 이해하기 쉽다는 데 있다. 위험 통제는 상대적으로 합리적이다. 그러나 실패한 돌파구 및 충격 시장의 처리와 같은 추가적으로 최적화되어야 할 몇 가지 문제도 있다. 이 전략은 트렌드 거래의 보조 도구로 더 적합하며 다른 기술 지표 또는 모델의 조합으로 더 효과적입니다.
/*backtest
start: 2022-12-06 00:00:00
end: 2023-12-12 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//Noro
//@version=4
strategy(title = "Noro's RiskChannel Strategy", shorttitle = "RiskChannel str", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, pyramiding = 0, commission_value = 0.1)
//Settings
needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
risklong = input(2.0, minval = 0.0, maxval = 99.9, title = "Risk size for long, %")
riskshort = input(2.0, minval = 0.0, maxval = 99.9, title = "Risk size for short, %")
stoptype = input(defval = "Center", options = ["Channel", "Center"], title = "Stop-loss type")
lotsize = input(100, defval = 100, minval = 1, maxval = 10000, title = "Lot, %")
pclen = input(50, minval = 1, title = "Price Channel Length")
showll = input(true, defval = true, title = "Show lines")
showof = input(true, defval = true, title = "Show offset")
showdd = input(true, defval = true, title = "Show label (drawdown)")
showbg = input(false, defval = false, title = "Show background")
fromyear = input(1900, defval = 1900, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")
//Price Channel
h = highest(high, pclen)
l = lowest(low, pclen)
center = (h + l) / 2
//Stop-loss
needstop = stoptype == "Center" or needlong == false or needshort == false
sl = center
//Lines
pccol = showll ? color.black : na
slcol = showll and stoptype == "Center" ? color.red : na
offset = showof ? 1 : 0
plot(h, offset = offset, color = pccol, title = "Channel High")
plot(center, offset = offset, color = slcol, title = "Cannel Center")
plot(l, offset = offset, color = pccol, title = "Channel Low")
//Background
size = strategy.position_size
bgcol = showbg == false ? na : size > 0 ? color.lime : size < 0 ? color.red : na
bgcolor(bgcol, transp = 70)
//Var
loss = 0.0
maxloss = 0.0
equity = 0.0
truetime = time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)
//Lot size
risksizelong = -1 * risklong
risklonga = stoptype == "Center" ? ((center / h) - 1) * 100 : ((l / h) - 1) * 100
coeflong = abs(risksizelong / risklonga)
lotlong = (strategy.equity / close) * coeflong
risksizeshort = -1 * riskshort
riskshorta = stoptype == "Center" ? ((center / l) - 1) * 100 : ((h / l) - 1) * 100
coefshort = abs(risksizeshort / riskshorta)
lotshort = (strategy.equity / close) * coefshort
//Trading
if h > 0
strategy.entry("Long", strategy.long, lotlong, stop = h, when = strategy.position_size <= 0 and needlong and truetime)
strategy.entry("Short", strategy.short, lotshort, stop = l, when = strategy.position_size >= 0 and needshort and truetime)
sl := sl != 0 ? sl : size > 0 ? l : size < 0 ? h : na
if size > 0 and needstop
strategy.exit("Stop Long", "Long", stop = sl)
if size < 0 and needstop
strategy.exit("Stop Short", "Short", stop = sl)
if time > timestamp(toyear, tomonth, today, 23, 59)
strategy.close_all()
strategy.cancel("Long")
strategy.cancel("Short")
if showdd
//Drawdown
max = 0.0
max := max(strategy.equity, nz(max[1]))
dd = (strategy.equity / max - 1) * 100
min = 100.0
min := min(dd, nz(min[1]))
//Max loss size
equity := strategy.position_size == 0 ? strategy.equity : equity[1]
loss := equity < equity[1] ? ((equity / equity[1]) - 1) * 100 : 0
maxloss := min(nz(maxloss[1]), loss)
//Label
min := round(min * 100) / 100
maxloss := round(maxloss * 100) / 100
labeltext = "Drawdown: " + tostring(min) + "%" + "\nMax.loss " + tostring(maxloss) + "%"
var label la = na
label.delete(la)
tc = min > -100 ? color.white : color.red
osx = timenow + round(change(time)*10)
osy = highest(100)
// la := label.new(x = osx, y = osy, text = labeltext, xloc = xloc.bar_time, yloc = yloc.price, color = color.black, style = label.style_labelup, textcolor = tc)