웬디의 기묘한 이야기

글 작성자: WENDYS
반응형

주식 시장에는 이동평균선이라는 지표가 있습니다. 10일 이동평균선은 과거 10일 동안의 주가를 평균낸값을 계속 이어서 표시하는 방법입니다. 이런 이동평균선과 현재 주가의 괴리가 얼마나 벌어져 있는가로 추세 매매를 결정하게 됩니다.

이러한 이동평균선의 등장 배경에는 랜덤워크가설이라는것이 존재합니다. 즉, 주가는 예측할 수 없이 움직인다는 것입니다. 그러나 예측할 수 없는 움직임이라도 평균을 내보면 어떠한 방향성을 찾을 수 있지 않을까?라는 가정에서 이동평균선이 등장하게 되었습니다.

 

시장에서는 단순 이동평균 SMA(simple moving average), 지수 이동평균 EMA(exponetial moving average), 가중 이동평균 WMA(weighted moving average)등을 사용하며, 단순 이동평균 SMA와 지수 이동평균 EMA를 많이 사용합니다.

 

주식에서 많이 사용되는 평균은 5, 10, 20, 50, 100, 200 이평선으로 5 이평선은 1주, 10 이평선은 2주, 20 이평선은 4주, 50 이평선은 한 분기, 100 이평선은 반년, 200 이평선은 1년의 거래일에 대한 평균을 측정합니다. 코인의 경우엔 7, 14,... 등으로 시장에 쉬는 날이 없기 때문에 이동평균을 7일 기준으로 합니다.

이동평균은 기술적 분석에서 매일 가격 변동에서 나오는 노이즈(noise)를 제거하는데 도움을 주고 가격 추세를 볼 수 있도록 도움을 줍니다.

 

단순 이동평균 SMA (Simple Moving Average)

단순 이동평균을 구하는 공식은 아주 간단합니다.

 

 

코드를 보면 다음과 같습니다.

이동평균에 대해 단순히 구하는 값이므로 rolling 함수를 이용한 뒤 mean() API를 사용하여 구할 수 있습니다.

df['sma5'] = df['Close'].rolling(5).mean()
df['sma20'] = df['Close'].rolling(20).mean()
df['sma100'] = df['Close'].rolling(100).mean()
df['sma200'] = df['Close'].rolling(200).mean()

 

지수 이동평균 EMA (Exponetial Moving Average)

보다 최근의 값에 가중치를 두면서 이동평균을 계산하는 방법입니다.

금일의 지수이동평균 = (금일 종가 * EP) + (전일의 지수 이동평균 * (1 - EP))

EP(평활 계수 : Exponential Percentage) = 2 / (기간 + 1)

 

EMA도 SMA처럼 ewm 함수를 사용하여 간단하게 처리가 가능합니다.

df['ema5'] = df['Close'].ewm(5).mean()
df['ema20'] = df['Close'].ewm(20).mean()
df['ema100'] = df['Close'].ewm(100).mean()
df['ema200'] = df['Close'].ewm(200).mean()

 

가중 이동평균 WMA(Weighted Moving Average)

현재에 가까운 가격 데이터가 과거의 가격 데이터보다 더 중요하다는 전제로 합니다. 선형 가중 이동평균(Linearly Weighted Moving Average)을 보면 동일한 값 1(4일 전) 2(3일 전) 3(2일 전) 4(1일 전) 5(금일)의 가격이라면 금일의 종가에 가중치를 부여하여 1*1 + 2*2 + 3*3 + 4*4 + 5*5 = 55

계산에서 사용된 값 (1 + 2 + 3 + 4 + 5 = 15)

55 / 15 = 3.67을 5개의 값의 평균으로 사용하는 것입니다.

WMA의 문제점은 여전히 이용한 기간 값의 가격 데이터만을 평균으로 반영하기 때문에 실제로는 잘 사용되지 않습니다.

 

 

독특한 방식으로 가중치를 주는 방식이기 때문에 아래와 같이 별도로 구현이 필요합니다.

def weighted_mean(weight_array):
    def inner(x):
        return (weight_array * x).mean()
    return inner
    
weights = np.arange(1,6)
wma5 = df['Close'].rolling(5).apply(lambda prices: np.dot(prices, weights)/weights.sum(), raw=True)

weights = np.arange(1,21)
wma20 = df['Close'].rolling(20).apply(lambda prices: np.dot(prices, weights)/weights.sum(), raw=True)

weights = np.arange(1,101)
wma100 = df['Close'].rolling(100).apply(lambda prices: np.dot(prices, weights)/weights.sum(), raw=True)

weights = np.arange(1,201)
wma200 = df['Close'].rolling(200).apply(lambda prices: np.dot(prices, weights)/weights.sum(), raw=True)

df['wma5'] = wma5
df['wma20'] = wma20
df['wma100'] = wma100
df['wma200'] = wma200

 

반응형