기술/지표 알림

지수이동평균(EMA) 가중이동평균(WMA) 계산

금붕맨 2023. 4. 11. 22:17
반응형

 

EMA WMA

 

지수이동평균(EMA) 가중이동평균(WMA) 계산

 

이동평균의 종류

이동평균의 종류

바이낸스 차트에서 지표설정을 누르면 나오는 모습입니다. 맨 위의 이동평균인 MA(Moving Average)는 지난번 골든크로스 알림에서 다루어 보았습니다. 이번 포스팅에서는 차트데이터를 받아와서 지수이동평균(EMA)과 가중이동평균(WMA)을 파이썬으로 계산하는 식을 만들어 보겠습니다.

 

MA는 단순이동평균(Simple Moving Average)라고도 불리는데 이름처럼 계산식이 단순하였습니다. 이번 EMA와 WMA가 저번에 다루었던 MA와 어떤 차이가 있고, 어떤 의미를 가지는지 생각하면서 읽으시면 더욱 도움이 될 것입니다.

 

 

지수이동평균(EMA)

EMA는 Exponential Moving Average의 약자로 가중승수(Weighted Multiplier)가 계산에 들어가며 최근의 데이터일수록 높은 가중치를 부여합니다.

EMA = Price(t) × k + EMA(y) × (1−k)

Price(t): 오늘의 종가

EMA(y): 어제의 EMA

k(가중승수): 2 / (period + 1)

살짝 이해하기 힘드실 것 같아서 예시도 보여드리겠습니다.

종가 EMA
100 100
150 125
200 162.5

우선 k = 2 / (3+1) = 0.5입니다. 두 번째 EMA의 값은 150x0.5 + 100x0.5 = 125입니다. 세 번째 EMA의 값은 200x0.5 +125x0.5 = 162.5입니다. 이와 같은 방식으로 더 현재에 가까운 종가일수록 높은 가중치가 부여된다는 것을 알 수 있습니다. 저번 MA를 구하였을 때는 pandas의 rolling함수를 이용하였는데 EMA를 구하는 계산식에는 적용할 수 없으므로 pandas의 ewm이라는 함수를 사용해야 합니다. ewm의 대표적인 매개변수로 alpha, com, span이 있는데 com과 span 모두 alpha와 관계식이 성립되므로 3개 중 1개만 넣어주시면 다른 매개변수들은 자동적으로 계산이 되어 넣어줄 필요가 없습니다. 밑에 파이썬 코드를 작성할 때 ewm의 매개변수 중 기간(period)을 뜻하는 span이 가장 간단하므로 span을 매개변수로 입력해 주시면 됩니다.

 

 

가중이동평균(WMA)

WMA는 Weighted Moving Average의 약자로 현재에 가까운 데이터일수록 높은 가중치를 부여해 평균을 구한 값입니다. EMA와 가중치를 부여한다는 점은 유사하나 MA와 비슷하게 간단한 계산으로 이루어집니다.

WMA = ( Price(1) x n +Price(2) x (n-1) +... + Price(n) )  /  ( n x (n-1) / 2 )

price1은 가장 최근의 종가이며 n은 이동평균을 설정할 기간입니다. 예시로 확인하겠습니다.

종가 WMA
100 NaN
150 NaN
200 166.667

period를 3으로 설정할 경우 앞에 두 WMA는 계산할 수 없게 되므로 NaN으로 표시됩니다. 세 번째 WMA의 값은 166.667 = (100x1 + 150x2 +200x3) / (1+2+3)으로 계산됩니다. 분모항의 1+2+3은 nx(n-1)/2이라는 등차수열로 정리한 식을 풀어서 쓴 것입니다.

 

EMA와 같이 가중치를 적용하는 모습을 계산식에서 찾을 수 있는데 다른 점은 가중치가 어떻게 분포되어 있는가입니다. EMA의 Exponential은 지수라는 뜻을 가지고 있고 이 이름을 붙인 이유는 가중치가 기하급수적으로 분포되어 있기 때문입니다. 반면 WMA의 가중치는 산술급수적으로 분포하기 때문에 period이전의 종가에는 가중치가 0이 부여됩니다. WMA는 MA와 마찬가지로 간단하게 계산이 되므로 rolling함수를 써서 구하시면 됩니다.

 

 

전체코드

import binance as bn
import numpy as np
import pandas as pd

def ema(symbol,interval,period1, period2=1, period3=1):
    close = bn.get(symbol,interval)['close']

    EMA1 = close.ewm(span= period1).mean()
    EMA2 = close.ewm(span= period2).mean()
    EMA3 = close.ewm(span= period3).mean()

    EMA = pd.concat([EMA1, EMA2, EMA3], axis=1)
    EMA.columns = [str(period1), str(period2), str(period3)]
    return EMA

def wma(symbol,interval,period1, period2=0, period3=0):
    close = bn.get(symbol,interval)['close']

    def weighted_mean(x):
        weights1 = np.arange(1, len(x) + 1)
        return np.sum(x * weights1) / np.sum(weights1)

    WMA1 = close.rolling(window=period1).apply(weighted_mean)
    WMA2 = close.rolling(window=period2).apply(weighted_mean)
    WMA3 = close.rolling(window=period3).apply(weighted_mean)

    WMA = pd.concat([WMA1, WMA2, WMA3], axis=1)
    WMA.columns = [str(period1), str(period2), str(period3)]
    return WMA

period2와 period3 매개변수는 선택사항으로 정리하였습니다. ema와 wma로 정의한 함수는 각각 EMA와 WMA로 반환되고 칼럼의 이름은 period입니다.

 

 

결과물

print(ema("BTC","1d", 25,99))
print(wma("BTC","1d", 25,99))
               25            99         1
0     9133.720000   9133.720000   9133.72
1     9144.432000   9144.124040   9154.32
2     9153.746098   9153.019415   9170.28
3     9169.256750   9167.438907   9208.99
4     9167.279758   9166.052778   9160.78
..            ...           ...       ...
995  27076.474891  23797.908601  27906.33
996  27142.775284  23880.718029  27938.38
997  27233.620262  23969.578868  28323.76
998  27418.521781  24082.934091  29637.34
999  27624.553182  24203.214009  30096.93

               25            99   0
0             NaN           NaN NaN
1             NaN           NaN NaN
2             NaN           NaN NaN
3             NaN           NaN NaN
4             NaN           NaN NaN
..            ...           ...  ..
995  27874.990123  24742.172523 NaN
996  27912.055138  24838.952689 NaN
997  27968.709477  24941.151384 NaN
998  28113.983508  25067.241606 NaN
999  28280.338123  25199.893206 NaN

ema의 두 번째 세 번째 period매개변수를 선택사항으로 만들어 입력하지 않을 경우 Nan로 나타내고 싶었지만 =0 또는 =None으로 처리할 시에 com값이 음수가 돼버리거나 오류가 발생하여 =1 방식으로 만들었습니다. 매개변수 period를 입력하지 않아서 만들어진 ['1'] 칼럼은 무시해 주시길 바랍니다.

 

마지막으로 비트코인 998번째 행의 EMA와 WMA를 비교해 봅니다.

EMA WMA 비트코인

모두 알맞게 매칭이 된 것을 확인하였습니다.

 

만약 모든 코인을 동시에 더 나아가서 이것으로 골든크로스 같은 이동평균선 교차가 발생하였을 때 알림을 주고 싶다면 이전 포스팅인 이동평균선(MA) 골든크로스 알림 글을 참고하시길 바랍니다.

 

이동 평균(MA) 골든크로스 알림

이동 평균(MA) 골든크로스 알림 이동평균(MA) 골든크로스 전체 코드 결과물 이동평균(MA) MA는 설정한 기간 동안의 종가 평균입니다. 종가 이동평균(MA) 7 NaN 13 NaN 15 NaN 10 NaN 11 11.2 15 12.8 5번째 행 MA값

goldfishman.tistory.com

 

반응형