1. Basic Indicators
1.1 Exponential Moving Average
\[\begin{align}
EMA &= v_t \times k + EMA(v_{t-1}) \times (1-k) \\
\text{or} & \\
EMA &= (v_t - EMA(v_{t-1})) \times k + EMA(v_{t-1})
\end{align}\]
\(v_t\) : today
\(v_{t-1}\) : yesterday
N : number of days over which to average
k : 2 / (N + 1)
특징은 다음과 같습니다.
기존 Moving Average보다 좀 더 최신 데이터에 wegith를 주게 됩니다.
Moving Average 와 동일하게 .. 횡보하게 되면 수익률이 쭉쭉 떨어짐.
random . seed ( 0 )
data = [ random . randint ( 0 , 20 ) for i in range ( 30 )]
def cal_ema1 ( data , n = 10 ):
k = 2 / ( n + 1 )
ema_p = data [ 0 ]
ema = [ data [ 0 ]]
for v in data [ 1 :]:
ema_p = ( v - ema_p ) * k + ema_p
ema . append ( ema_p )
return np . array ( ema ). round ( 2 )
Python 1
def cal_ema2 ( data , n = 10 ):
k = 2 / ( n + 1 )
ema_p = data [ 0 ]
ema = [ data [ 0 ]]
for v in data [ 1 :]:
ema_p = v * k + ema_p * ( 1 - k )
ema . append ( ema_p )
return np . array ( ema ). round ( 2 )
Python 2
def cal_ema2 ( data , n = 10 ):
k = 2 / ( n + 1 )
ema_p = data [ 0 ]
ema = [ data [ 0 ]]
for v in data [ 1 :]:
ema_p = v * k + ema_p * ( 1 - k )
ema . append ( ema_p )
return np . array ( ema ). round ( 2 )
Pandas
ema3 = pd . Series ( data ). ewm ( span = 10 , adjust = False ). mean (). round ( 2 ). tolist ()
1.2 Absolute Price Oscillator
\[\text{Absolute Price Oscillator} = \text{EMA}_{fast} - \text{EMA}_{slow}\]
data = pd . Series ([ random . randint ( - 5 , 5 ) for i in range ( 300 )]). cumsum ()
ema1 = pd . Series ( data ). ewm ( span = 7 , adjust = False ). mean ()
ema2 = pd . Series ( data ). ewm ( span = 20 , adjust = False ). mean ()
# Absolute Price Oscillator
apo = ema1 - ema2
1.3 MACD (Moving Average Convergence Divergence)
\[\begin{align}
\text{MACD} &= EMA_{Fast} - EMA_{Slow} \\
\text{MACD}_{Signal} &= EMA_{MACD} \\
\text{MACD}_{Histogram} &= MACD - MACD_{Signal}
\end{align}\]
첫번째줄 MACD는 사실상 APO (Absolute Price Oscillator) 와 동일하다
두번째줄 MACD_Signal은 Raw MACD (APO)에 한번더 smoothing factor 를 입힌 것이다.
MACD_Histogram에서 최종적으로 signal을 찾는다.
data = pd . Series ([ random . randint ( - 5 , 5 ) for i in range ( 300 )]). cumsum ()
ema1 = pd . Series ( data ). ewm ( span = 6 , adjust = False ). mean ()
ema2 = pd . Series ( data ). ewm ( span = 15 , adjust = False ). mean ()
# MACD = APO
macd = ema1 - ema2
macd_signal = macd . ewm ( span = 15 , adjust = False ). mean () # span은 ema_slow 와 동일하게 가져감
macd_histogram = macd - macd_signal
MACD(histogram) 에서 보듯이 0을 기준으로 오르면 사고, 내릴때는 매도 하는 시그널로 사용하면 됨.
1.4 Bollinger Bands
Bollinger bands는 최근 가격의 변동성을 반영하기 때문에 여러가지 상황에 고정적으로 대응하기 보다 좀 더 유연하게 대처할 수 있습니다.
사용 예제로는 해당 upper 또는 lower 를 주가가 더 튀어 나갈때는 잡습니다.
\[\begin{align}
\text{BB}_{upper} = SMA_{n - periods} + \sigma \times \alpha \\
\text{BB}_{lower} = SMA_{n - periods} - \sigma \times \alpha \\
\end{align}\]
SMA, EMA 가 됐든.. 아무거나 사용하면 됨
\(\sigma\) : standard deviation
data = pd . Series ([ random . randint ( - 5 , 5 ) for i in range ( 50 )]). cumsum ()
ema = pd . Series ( data ). ewm ( span = 12 , adjust = False ). mean ()
# Bollinger Bands
alpha = 2
std = np . sqrt (( data - ema ) ** 2 / 12 )
upper = ema + std * alpha
lower = ema - std * alpha
1.5 RSI (Relative Strength)
MA 기반의 Indicator와는 좀 다르게, RSI는 가격의 변화, 강도를 담아냅니다.
50% 이상은 up-trend 를 가르키며, 50% 이하면 downtrend 를 의미 합니다.
\[\begin{align}
RSI &= 100 - \frac{100}{1-RS} \\
RS &= \frac{AvgU}{AvgD} \\
AvgU &= \frac{\sum \text{all gain in the last N periods}}{N} \\
AvgD &= \frac{\sum \text{all loss in the last N periods}}{N} \\
\end{align}\]
AvgU 에서 loss 부분을 0으로 대체
AvgD 에서 gain 부분을 0으로 대체
data = pd . Series ([ random . randint ( - 1 , 1 ) for i in range ( 300 )]). cumsum ()
gain , loss = data . copy (), data . copy ()
diff = data . diff ( 1 )
gain [ diff <= 0 ] = 0
loss [ diff >= 0 ] = 0
gain_mean = gain . rolling ( 7 ). mean ()
loss_mean = loss . rolling ( 7 ). mean ()
rsi = 100 - 100 / ( 1 - ( gain_mean / loss_mean ))
1.6 Momentum
\[\begin{align}
\text{Momentum} = Price_t - Price_{t-n}
\end{align}\]
달리는 말에 올라타는 전략.
1.7 Average True Indicator (ATR)
\[\begin{align}
TR &= \max[(H-L), abs(H-C_p), abs(L-C_p)] \\
ATR &= \frac{1}{n} \sum^n_{i=1} TR_i
\end{align}\]
\(TR_i\) : True Range.
n : 보통 n=14
Stop-loss 를 어디서 걸어야 되는지를 결정하도록 도와줌
의미
가격폭의 평균 값. -> ATR 값이 높다는건 변동성이 높다는 뜻이고 낮다는건 변동성 작음.
손절 익절 기준으로도 활용됨.
손절: ATR * 3
익절: ATR * 1.5
아래 그림을 보면 쉽게 이해가 됨. 방향을 찾는건 아니고, 어제와 비교해서 가장 크게 움직인 크기를 찾아냄.
import numpy as np
import pandas as pd
def atr ( df , n = 14 ):
c_p = df . close . shift ()
df [ 'H-L' ] = df . high - df . low
df [ 'H-Cp' ] = ( df . high - c_p ). abs ()
df [ 'L-Cp' ] = ( df . low - c_p ). abs ()
df [ 'TR' ] = df [[ 'H-L' , 'H-Cp' , 'L-Cp' ]]. max ( axis = 1 )
df [ 'ATR' ] = df . TR . ewm ( alpha = 1 / n , min_periods = n , adjust = False ). mean ()
atr ( df )
ZetaValue 내부 툴로 확인한 ATR. (n=14)