[기술적 분석] 지표/전략 : 켈트너 채널 (Keltner Channels) / 수차 (Aberration)

반응형

  켈트너 채널(KC, Keltner Channels)은 체스터 켈트너(Chester W. Keltner)라는 사람이 만든 변동성 지표이다. 켈트너는 10일 단순 이동 평균을 사용하여 거래하였으나 현재는 보통 20일 지수 이동 평균을 사용한다. 볼린저 밴드와 유사한 변동성 지표이나 상하단 밴드를 정하는 방법이 다르다. 종목의 변동성을 반영한다는 점은 같으나 표준편차 대신 ATR (Average True Range)를 사용한다. 켈트너 채널은 일반적으로 기준선에는 20일 EMA (지수이동평균, Exponential Moving Average)를 사용하고, 가격밴드를 그리는 상하단에 기준선에 10일 ATR을 두 배수 해서 사용한다. 표준편차 대신 ATR을 사용하면서 밴드 폭 변화가 어떻게 될까? 

볼린저 밴드와 켈트널 채널 비교

  위 차트에서 푸른색 상하단 밴드가 켈트너 채널, 그리고 붉은색 상하단 밴드가 볼린저 밴드이다. 볼린저 밴드가 상대적으로 밴드 폭이 변동성에 민감하게 반응해서 가격변화가 클 때는 켈트너 채널에 비해 밴드폭이 크게 벌어지고, 가격 변화가 적을 때는 밴드폭이 켈트너 채널에 비해 좁게 모이는 걸 볼 수 있다.

  켈트너 채널을 이용한 매매 방식은 볼린저 밴드, 엔벨롭의 그것과 유사하다. 밴드 상단에 다다르면 매도, 밴드 하단에 다다르면 매수를 검토한다. 이 역시 이동평균선의 종류를 변경하거나, 이동평균선이나 ATR의 길이를 조절하거나, ATR의 배수를 조정해서 사용한다. 엔벨롭보다는 종목별/기간별 변동성을 잘 반영하여 밴드를 구성하는 장점이 있으나, 앞서 본 것과 같이 ATR이 기간 내 가격 변동 폭의 평균이다 보니 표준편차에 비해 밴드 폭이 기민하게 변하진 않는다.

  켈트너 채널에서 basis라인을 Typical Price(고저종가 평균)을 사용하고 이동평균을 단순 이동 평균을 사용했을 때는 Aberration (수차, 일탈)이라고도 한다.

  가격과 변동성에 기반한 매매 방식에 적합하며, 추세에 대한 고려가 없으므로 엔벨롭, 볼린저 밴드와 마찬가지로 박스권 장세에서 주효한 전략.

켈트너 채널 전략을 이용한 매매

 

  마지막으로 트레이딩 뷰 소스와 pandas-ta 소스를 공유하며 마무리한다.

 

  • 켈트너 채널 (Keltner Channels) 트레이딩 뷰 파인 스크립트 지표 소스
//@version=5
indicator(title="Keltner Channels", shorttitle="KC", overlay=true, timeframe="", timeframe_gaps=true)
import TradingView/ta/7 as ta7

len = input.int(20, minval=1)
mult = input(2.0, "Multiplier")
src = input(close, title="Source")
BandsStyle = input.string("Average True Range", options = ["Average True Range", "True Range", "Range"], title="Bands Style", display = display.data_window)
atrlength = input(10, "ATR Length", display = display.data_window)
maType = input.string("SMA", "MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA"])
ma(source, length, _type) =>
    switch _type
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "DEMA" => ta7.dema(source,length)
        "TEMA" => ta7.tema(source,length)
        "FRAMA" => ta7.frama(source,length)
        "T3" => ta7.t3(source,length)
        "TRIMA" => ta7.trima(source,length)
        "RMA" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "HMA" => ta.hma(source, length)
        "VWMA" => ta.vwma(source, length)
basis = ma(src, len, maType)

rangema = BandsStyle == "True Range" ? ta.tr(true) : BandsStyle == "Average True Range" ? ta.atr(atrlength) : ta.rma(high - low, len)
upper = basis + rangema * mult
lower = basis - rangema * mult
u = plot(upper, color=#2962FF, title="Upper")
plot(basis, color=#2962FF, title="Basis")
l = plot(lower, color=#2962FF, title="Lower")
fill(u, l, color=color.rgb(33, 150, 243, 95), title="Background")

 

  • 켈트너 채널 (Keltner Channels) 트레이딩 뷰 파인 스크립트 전략 소스
//@version=5
strategy(title="Keltner Channels", shorttitle="KC", overlay=true, margin_long=100, margin_short=100, default_qty_type=strategy.percent_of_equity, default_qty_value=50, commission_type=strategy.commission.percent, commission_value=0.2, pyramiding=0)
import TradingView/ta/7 as ta7

len = input.int(20, minval=1)
mult = input(2.0, "Multiplier")
src = input(close, title="Source")
BandsStyle = input.string("Average True Range", options = ["Average True Range", "True Range", "Range"], title="Bands Style", display = display.data_window)
atrlength = input(10, "ATR Length", display = display.data_window)
maType = input.string("SMA", "MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA"])
ma(source, length, _type) =>
    switch _type
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "DEMA" => ta7.dema(source,length)
        "TEMA" => ta7.tema(source,length)
        "FRAMA" => ta7.frama(source,length)
        "T3" => ta7.t3(source,length)
        "TRIMA" => ta7.trima(source,length)
        "RMA" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "HMA" => ta.hma(source, length)
        "VWMA" => ta.vwma(source, length)
basis = ma(src, len, maType)

rangema = BandsStyle == "True Range" ? ta.tr(true) : BandsStyle == "Average True Range" ? ta.atr(atrlength) : ta.rma(high - low, len)
upper = basis + rangema * mult
lower = basis - rangema * mult
u = plot(upper, color=#2962FF, title="Upper")
plot(basis, color=#2962FF, title="Basis")
l = plot(lower, color=#2962FF, title="Lower")
fill(u, l, color=color.rgb(33, 150, 243, 95), title="Background")

startDate = input.time(defval=timestamp("01 Jan 1970 00:00 +0000"), group = "Test Range")
finishDate = input.time(defval=timestamp("31 Dec 2025 24:00 +0000"), group = "Test Range")
time_condition = time >= startDate and time <= finishDate

if(time_condition)
	if ta.crossover(src, lower)
		strategy.entry("매수", strategy.long, stop=lower, oca_type=strategy.oca.cancel, comment="매수")
	if ta.crossunder(src, upper)
		strategy.close_all('매도')

bgcolor(strategy.position_size > 0 ? color.new(color.yellow,90) : na)

 

  • 켈트너 채널 (Keltner Channels) / 수차 (Aberration) pandas-ta 소스
import pandas as pd
import pandas_ta as ta
import FinanceDataReader as fdr

# Keltner Channels
data = fdr.DataReader('005930')
kc = ta.kc(high=data['High'], low=data['Low'], close=data['Close'], length=20, scalar=2, mamode='EMA')
data = pd.concat([data, kc], axis=1)
data.dropna(inplace=True)

# Aberration
data = fdr.DataReader('005930')
aberration = ta.aberration(high=data['High'], low=data['Low'], close=data['Close'], length=5, atr_length=15)
data = pd.concat([data, aberration], axis=1)
data.dropna(inplace=True)
반응형