APO(Absolute Price Oscillator)는 단기, 장기 두개의 이동 평균선을 그려놓고 이동평균간의 가격차이를 측정하는 보조지표이다. 보통 EMA(지수 이동 평균, Exponential Moving Average) 두 개를 각각 10, 20 또는 12, 26의 구간을 그려 두 이동 평균간의 가격 차이를 이용하여 시장이나 종목의 추세, 그리고 모멘텀의 강도를 측정한다. 단기 이동 평균이 장기 이동 평균보다 상단에 위치해있을 경우는 양수를 나타내며 이는 상향 추세, 반대의 경우는 약세장으로 본다. 그리고 이동 평균선 간의 가격 차이가 클 수록 추세가 강하다고 본다.
매매 전략은 두 이동 평균이 교차하는 지점을 매매 시점으로 보며 기본적인 골든 크로스, 데드 크로스(Golden Cross, Dead Cross) 전략과 동일하다. 단 이 가격차이를 수치화 하여 제공한다는 것이 차이점. APO가 양수가 되면 골든 크로스가 발생한 것이고 이 지점에 매수를 한다. 반대로 APO가 음수가 되면 데드 크로스가 발생한 것이고 이 지점에 매도를 한다. 다만 일반적인 골든 크로스 / 데드 크로스는 통상 단순 이동 평균(Simple Moving Average)를 이용하나 APO의 경우, 시차를 줄이고 좀 더 빠르게 추세 변화를 감지하기 위해 지수 이동 평균을 이용하는데서 차이가 날 수 있다.
일반적인 골든 크로스, 데드 크로스에 비해 수치화 되어 그 강도가 표시되고 추세를 양수, 음수로 정량화 하여 표시한다는 장점은 있으나, 가격차이를 이용하므로 가격이 높은 종목의 이동평균선 간 차이가 가격이 낮은 종목의 이동평균선 간 차이보다 크게 보일 수 밖에 없다. 이런 단점을 제거하기 위해 이격도(Disparity)를 사용하거나 이격도와 비슷하게 현재가격으로 APO를 나눈 값을 사용하는 방법으로 값을 보정할 수 있다.
마지막으로 트레이딩 뷰 파인 스크립트 소스와 pandas-ta 소스를 공유하며 마친다.
- APO(Absolute Price Oscillator) 트레이딩 뷰 파인 스크립트 지표 소스
//@version=5
indicator(title="Absolute Price Oscillator", shorttitle="APO", 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)
srcInput = input(close, "Source")
shortLengthInput = input.int(10, title="Short Length", group="Short", minval=1)
shortmaTypeInput = input.string("EMA", title="Short MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Short", display = display.data_window)
longLengthInput = input.int(20, title="Long Length", group="Long", minval=1)
longmaTypeInput = input.string("EMA", title="Short MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Long", display = display.data_window)
shortMA = ma(srcInput, shortLengthInput, shortmaTypeInput)
longMA = ma(srcInput, longLengthInput, longmaTypeInput)
APO = shortMA - longMA
plot(APO, title="APO", color=color.yellow)
hline(0, "Middle Band", linestyle=hline.style_dotted, color=color.gray)
- APO(Absolute Price Oscillator) 트레이딩 뷰 파인 스크립트 전략 소스
//@version=5
strategy(title="Absolute Price Oscillator", shorttitle="APO", 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)
srcInput = input(close, "Source")
shortLengthInput = input.int(10, title="Short Length", group="Short", minval=1)
shortmaTypeInput = input.string("EMA", title="Short MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Short", display = display.data_window)
longLengthInput = input.int(20, title="Long Length", group="Long", minval=1)
longmaTypeInput = input.string("EMA", title="Short MA Type", options = ["SMA", "EMA", "DEMA", "TEMA", "FRAMA", "T3", "TRIMA", "RMA", "WMA", "HMA", "VWMA", "ALMA", "JMA", "SINWMA", "FWMA", "LINREG", "SWMA", "VIDYA", "VWAP", "ZLMA"], group="Long", display = display.data_window)
shortMA = ma(srcInput, shortLengthInput, shortmaTypeInput)
longMA = ma(srcInput, longLengthInput, longmaTypeInput)
APO = shortMA - longMA
plot(APO, title="APO", color=color.yellow)
hline(0, "Middle Band", linestyle=hline.style_dotted, color=color.gray)
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(shortMA, longMA)
strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
if ta.crossunder(shortMA, longMA)
strategy.close_all('매도')
bgcolor(strategy.position_size > 0 ? color.new(color.yellow,90) : na)
- APO(Absolute Price Oscillator) pandas-ta 소스
import pandas as pd
import pandas_ta as ta
import FinanceDataReader as fdr
data = fdr.DataReader('005930')
apo = ta.apo(close=data['Close'], fast=12, slow=26, mamode='SMA')
data = pd.concat([data, apo], axis=1)
data.dropna(inplace=True)