AO(Awesome Oscillator)는 빌 윌리엄스(Bill Williams)가 개발한 지표로 국내에는 다른 지표들에 비해 덜 알려져 있으나 해외에서는 이름만큼이나 'Awesome'해서인지 주식, 선물, 외환, 코인 등 투자대상을 가리지 않고 광범위하게 제법 많이 사용되는 모멘텀 지표이다. 어썸 오실레이터는 MACD(Moving Average Convergence Divergence)나 PPO(Percentage Price Oscillator)처럼 장기, 단기 이동 평균선의 차이를 이용하는데, 가장 큰 차이점은 종가 기준으로 장기, 단기 이동평균선을 그리는 것이 아니라, 고가와 저가의 중간값(median)을 이용하여 이동평균선을 그린다. 또한 단순 이동 평균(SMA, Simple Moving Average)을 사용하며 장기에는 34일, 단기에는 5일 이동평균을 적용하는 것이 일반적이다.
AO는 MACD나 PPO처럼 추세와 모멘텀을 식별하기 좋은 지표이며 추세반전 신호를 포착하기 위해 공을 많이 들였다. 통상 MACD나 PPO의 경우에는 히스토그램(이동평균 간 차이 - 이동평균 간 차이의 이동평균)이 0을 지나는 시점, MACD나 PPO가 시그널과 교차하는 시점을 기점으로 하여 추세반전이 되었다고 포착하는데, 어썸 오실레이터는 이 차이가 줄어드는 시점을 포착하기 위해 히스토그램 색깔을 다르게 표현하여 이 지점에서 매매를 하는 방식도 존재한다.
단, MACD와 마찬가지로 장단기 이동 평균선 간의 가격차이를 그대로 표현하기 때문에 AO 값의 범위가 주당 주가에 따라 각각 다르며 종목 간의 비교나 계량화 하기 어려운 점이 있다.
매매전략은 앞서 설명했다시피 히스토그램의 색깔이 바뀌는 지점에 매수, 매도를 하는 방법이다. 이 매매법은 Saucer(받침 접시)하는데, 이는 이동평균선 간의 간격이 좁혀지기 시작했는지, 벌어지기 시작했는지를 포착하는 방법으로 단기 이동 평균선이 장기 이동 평균선보다 기민하게 움직이는 원리를 이용한다. 히스토그램의 색깔이 빨간색이 되면(단기 이동평균선이 장기 이동평균선의 위에서 아래로 내려오는 경우, 단기 이동평균선이 장기 이동평균선의 아래에서 그 간격을 더 벌리는 경우), 매도, 히스토그램의 색깔이 녹색이 되면(단기 이동평균선이 장기 이동평균선의 위에서 간격을 더 벌리는 경우, 단기 이동평균선이 장기 이동평균선의 아래에서 위로 올라오는 경우), 매수하는 전략이다. 단, 이 전략은 허위시그널이 발생할 가능성이 제법 되며 이런 허위시그널을 방지하기 위해 단순 이동평균선을 사용하는 듯하다.
다음은 MACD나 PPO와 마찬가지로 히스토그램이 양전, 음전하는 시점을 이용하여 매매를 하는 방법이다. 이 경우, 앞선 히스토그램의 색깔을 이용하여 매매하는 전략보다 시그널 발생 시점이 느리나 허위시그널의 발생 정도는 훨씬 낮아진다. 이 방법의 경우, 비슷하게 MACD의 히스토그램 매매전략과 비교했을 경우, 보통의 경우 허위 시그널의 발생 빈도가 훨씬 낮은 것으로 알려져 있다. 이런 장점들 때문에 어썸 오실레이터라고 불리는 듯.
이 외에도, 히스토그램이 고점을 갱신하지 못하고 내려오거나, 저점을 갱신하지 못하고 올라가는 경우, 향후 추세전환이 있을 것으로 예측할 수 있다. 단, 이 방법은 눈으로 확인하기에는 용이하나 시스템화하여 적용하기에는 어려운 점이 있다. 일단 직전 고점을 파악하기가 어려우며 이런 다이버전스가 발생한 후 얼마의 시간이 지나 추세전환이 발생하는지 지정하기 어렵기 때문이다.
마지막으로 AO(Awesome Oscillator)의 트레이딩 뷰 파인 스크립트 소스와 pandas-ta 소스를 공유하며 마친다.
- AO(Awesome Oscillator) 트레이딩 뷰 파인 스크립트 지표 소스
//@version=5
indicator(title="Awesome Oscillator", shorttitle="AO", format=format.price, precision=2, timeframe="", timeframe_gaps=true)
import TradingView/ta/7 as ta7
import blackcat1402/pandas_ta/7 as pta
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 * volume, length)
"ALMA" => pta.alma(source, length)
"JMA" => pta.jma(source, length)
"SINWMA" => pta.sinwma(source, length)
"FWMA" => pta.fwma(source, length)
"LINREG" => pta.linreg(source, length)
"SWMA" => pta.swma(source)
"YIDYA" => pta.vidya(source, length)
"VWAP" => pta.vwap(source)
"ZLMA" => pta.zlma(source, length)
fastLengthInput = input.int(5, title="Fast Length", group="Fast", minval=1)
fastmaTypeInput = input.string("SMA", title="Fast MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Fast", display = display.data_window)
slowLengthInput = input.int(34, title="Slow Length", group="Slow", minval=1)
slowmaTypeInput = input.string("SMA", title="Fast MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Slow", display = display.data_window)
fastMA = ma(hl2, fastLengthInput, fastmaTypeInput)
slowtMA = ma(hl2, slowLengthInput, slowmaTypeInput)
ao = ( fastMA - slowtMA )
diff = ao - ao[1]
plot(ao, color = diff <= 0 ? color.red : color.lime , style=plot.style_columns)
- AO(Awesome Oscillator) 트레이딩 뷰 파인 스크립트 전략 소스
//@version=5
strategy(title="Awesome Oscillator", shorttitle="AO", 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
import blackcat1402/pandas_ta/7 as pta
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 * volume, length)
"ALMA" => pta.alma(source, length)
"JMA" => pta.jma(source, length)
"SINWMA" => pta.sinwma(source, length)
"FWMA" => pta.fwma(source, length)
"LINREG" => pta.linreg(source, length)
"SWMA" => pta.swma(source)
"YIDYA" => pta.vidya(source, length)
"VWAP" => pta.vwap(source)
"ZLMA" => pta.zlma(source, length)
fastLengthInput = input.int(5, title="Fast Length", group="Fast", minval=1)
fastmaTypeInput = input.string("SMA", title="Fast MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Fast", display = display.data_window)
slowLengthInput = input.int(34, title="Slow Length", group="Slow", minval=1)
slowmaTypeInput = input.string("SMA", title="Fast MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Slow", display = display.data_window)
indi = input.string("Saucer", title="Strategy Indicator", options = ["Saucer", "Cross"])
fastMA = ma(hl2, fastLengthInput, fastmaTypeInput)
slowtMA = ma(hl2, slowLengthInput, slowmaTypeInput)
ao = ( fastMA - slowtMA )
diff = ao - ao[1]
plot(ao, color = diff <= 0 ? color.red : color.lime , style=plot.style_columns)
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 (indi == "Saucer")
if ta.crossover(diff, 0)
strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
if ta.crossunder(diff, 0)
strategy.close_all('매도')
if (indi == "Cross")
if ta.crossover(ao, 0)
strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
if ta.crossunder(ao, 0)
strategy.close_all('매도')
bgcolor(strategy.position_size > 0 ? color.new(color.yellow,90) : na)
- AO(Awesome Oscillator) pandas-ta 소스
import pandas as pd
import pandas_ta as ta
import FinanceDataReader as fdr
data = fdr.DataReader('005930')
ao = ta.ao(high=data['High'], low=data['Low'], fast=5, slow=34)
data = pd.concat([data, ao], axis=1)
data.dropna(inplace=True)