본문 바로가기

Python/Investment

Python으로 MACD와 MACD 오실레이터 계산 및 차트 생성

반응형

Python으로 MACD와 MACD 오실레이터 계산 및 차트 생성

이번 포스트에서는 Python으로 주식 차트의 보조 지표 중 하나인 MACD와 MACD 오실레이터를 계산하고 차트를 생성해보는 시간을 가져 보고자 한다.
필자 같은 경우에 MACD는 주식 차트 분석을 배울 때 이동평균선 다음으로 배운 기억이 있다.
MACD에 대한 자세한 내용 및 매매 방법은 다음 포스트로 작성하고 오늘은 Python으로 MACD를 구현해보자.

목차

MACD란?

MACD(Moving Average Convergence Divergence)장기적인 추세단기적인 추세비교해서 이 둘 간의 편차를 측정하는 기술적 지표이다.
특히, 가격의 상승 추세나 하락 추세가 계속될 것인지 아니면 변동이 발생할 것인지에 대한 시그널을 제공한다.

MACD는 보통 세 가지 요소로 구성된다.

MACD 구성 요소

  • MACD 선
  • 시그널
  • MACD 히스토그램 또는 MACD 오실레이터

✔ MACD

단기 이동 평균(보통 12일)에서 장기 이동 평균(보통 26일)을 뺀 값이다.
보통 최근의 주가 변화를 강조하는 지수이동평균으로 사용된다.


✔ 시그널

MACD 선의 이동 평균(보통 9일)이다.


MACD와 시그널


✔ MACD 오실레이터 또는 히스토그램

MACD 선과 시그널 간의 차이를 나타낸다.



MACD가 어떻게 움직이는지를 보면 가격의 추세와 다가올 가능성 있는 변동을 예측할 수 있다.


MACD에 대한 자세한 내용 및 매매 방법은 아래 포스트에서 확인 가능하다.

MACD 오실레이터란?

위에서 간단하게 설명했 듯이 MACD 오실레이터(히스토그램)는 MACD와 시그널 간의 차이를 나타낸다.
MACD 오실레이터는 MACD와 시그널 사이의 차이를 그래픽적으로 보여주며, 이 차이가 클수록 두 선은 멀어진다.
이는 강한 상승 추세 또는 하락 추세를 나타낸다.
이 차이가 작아질수록 두 선은 가까워지고, 이는 추세의 변동이나 반전을 나타낼 수 있다.


MACD 오실레이터


MACD/MACD 오실레이터 계산

MACD와 오실레이터에 대해서 간단하게 알아 보았다.
그럼 이제 MACD와 오실레이터를 한 번 계산해보자.
우선 MACD를 계산하려면 종가 데이터가 필요하다.
아래 데이터 중 close가 종가이다.


샘플 데이터


저번 이동평균선과 동일한 데이터로 MACD를 계산해보자.
MACD는 장기(일반적으로 26일) 지수이동평균과 단기(일반적으로 12일) 지수이동평균의 차이로 구할 수 있다.
MACD의 지수이동평균을 계산하면 MACD 시그널이 된다.
pandas 라이브러리의 ewm 메서드를 사용하면 지수 가중 이동평균(Exponential Weighted Moving Average)을 구할 수 있다.


✔ pandas ewm 메서드

ewm 메서드는 지수 가중 이동 평균(Exponential Weighted Moving Average)을 계산하기 위해 사용된다.
(ewm은 'exponential weighted function'의 약자)
이 메서드는 주어진 시계열 데이터에서 각 요소에 대해 감소하는 가중치를 적용하며, 최근의 데이터에 더 많은 가중치를 주는 특성이 있다.

DataFrame.ewm(self, com=None, span=None, halflife=None, alpha=None, min_periods=0, adjust=True, ignore_na=False, axis=0)
  • com (center of mass): 이동 평균의 중심을 지정하는 데 사용
  • span: EW(지수 가중치) 계산에 사용되는 window 크기.
    'span'은 원하는 N-day 지수 가중치 이동 평균의 길이를 설정하는 데 사용된다.
  • halflife: 지수 가중치의 감소가 절반으로 줄어드는 기간을 설정.
  • alpha: 지수 가중치의 감소 계수를 직접 설정하는 데 사용.
    'alpha'는 0과 1 사이의 값을 가져야 한다.
  • min_periods: 최소 기간 수를 지정.
    매개변수는 윈도우의 최소 관측치 수를 지정하는 데 사용된다.
  • adjust: 가중치를 조정할지 여부를 지정하는 논리 매개변수.
    True로 설정하면 관찰된 기간 동안 가중치가 고정되며, False로 설정하면 가중치가 관찰된 시점에 따라 변한다.
  • ignore_na: 결측치를 무시할지 여부를 지정.
    True로 설정하면, 결측치는 계산에서 제외된다.
  • axis: 연산을 수행할 축을 지정.
    0은 인덱스(행), 1은 열을 나타낸다.


그럼 이제 ewm 메서드를 사용해서 MACD를 구해보자.
우선 단기 지수 이동평균을 코드로 작성하면,

# 단기(12일) 지수 이동평균
df['close'].ewm(span=12, adjust=False).mean()

단기 지수 이동평균


이렇게 ewm에서 span을 12로 두고 adjust는 False로 설정했다.
adjust를 False로 설정하면 최근의 데이터에 더 큰 가중치를 부여하고, 이전의 데이터에는 점차적으로 줄어드는 가중치를 부여한다.

단기 지수 이동평균을 구했으니 이제 장기 지수 이동평균(26일)을 구한다.

# 장기(26일) 지수 이동평균
df['close'].ewm(span=26, adjust=False).mean()

장기 지수 이동평균


이렇게 계산된 단기와 장기 지수 이동평균의 차이를 계산하면 이것이 MACD가 된다.

# 단기(12일) 지수 이동평균
short_ema = df['close'].ewm(span=12, adjust=False).mean()

# 장기(26일) 지수 이동평균
long_ema = df['close'].ewm(span=26, adjust=False).mean()

macd_line = short_ema - long_ema

MACD 계산


이제 MACD를 계산했으니 데이터프레임에 MACD 컬럼을 추가해주고 시그널을 계산해보자.

# MACD 컬럼 및 데이터 추가
df['MACD'] = macd_line

시그널은 MACD의 지수 이동 평균(9일)이라고 했다.
그럼 아까 계산했던 MACD로 다시 ewm을 사용하고 span을 9로 설정하면 시그널도 계산할 수 있다.

# MACD로 9일 지수 이동평균 계산
df['MACD'].ewm(span=9, adjust=False).mean()

MACD 시그널 계산


이렇게 MACD와 시그널 모두 계산을 완료했다.
시그널도 MACD와 마찬가지로 데이터프레임에 새로운 컬럼으로 추가해주자.

# Signal 컬럼 및 데이터 추가
df['Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()

MACD와 시그널을 계산했으니 이제 오실레이터도 간단하게 계산할 수 있다.
오실레이터는 MACD와 시그널 간의 차이이다.
고로 위에서 데이터프레임에 추가했던 MACD 컬럼과 Signal 컬럼의 차이를 계산하면 이것이 오실레이터이다.

# MACD 오실레이터
df['MACD'] - df['Signal']

MACD 오실레이터


MACD 오실레이터도 새로운 컬럼으로 추가해주자.

# MACD 오실레이터 컬럼 추가
df['Oscillator'] = df['MACD'] - df['Signal']
          

현재 최종적으로 그럼 아래와 같은 데이터프레임이 생성된다.


최종 데이터프레임


그럼 이 데이터 프레임으로 MACD 차트를 생성해보자.

MACD/MACD 오실레이터 차트

MACD와 오실레이터 차트를 matplotlib로 생성해보자.
날짜 데이터를 인덱스로 사용했기 때문에 차트를 생성할 때 x축에 날짜가 들어가게 된다.
이 때 matplotlib에서 날짜로 인식을 하는 건지 주말 날짜가 포함되어서 오실레이터에 빈칸이 생성된다.
그래서 이 부분을 해결하기 위해 날짜 데이터는 우선 사용하지 않고 데이터의 index 기준으로만 차트를 생성했다.
종가 차트 / MACD / 시그널 / 오실레이터 차트를 생성하는 최종 코드는 아래와 같다.

# NaN 값 채우기
df.fillna(method='ffill', inplace=True)

# figure, subplot 생성
fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(12, 8), dpi=80, sharex=True)

# 종가 차트 생성
axes[0].plot(df['close'].values, label='close')
axes[0].set_title('close')

# MACD와 시그널 라인 차트 생성
axes[1].plot(df['MACD'].values, color='darkorange', label='MACD')
    # > MACD는 좀 어두운 오렌지색으로 설정
axes[1].plot(df['Signal'].values, color='purple', label='Signal')
    # > 시그널은 보라색으로 설정
axes[1].set_title('MACD and Signal')

# MACD 오실레이터의 값이 양수/음수에 따라 색을 빨간색 또는 파란색 계열로 설정 및 차트 생성
oscillator_values = df['Oscillator'].values
colors = ['#FF7F7F' if value >= 0 else '#7FA0FF' for value in oscillator_values]
axes[2].bar(range(len(df)), oscillator_values, color=colors, label='Oscillator')
axes[2].set_title('MACD Oscillator')

# 각 하위 plot에 범례 추가
for ax in axes:
    ax.legend()

plt.tight_layout()
plt.show()

위 코드를 실행하면 아래와 같은 차트를 출력할 수 있다.


종가 차트 / MACD / MACD 오실레이터

이렇게 Python pandas와 matplotlib를 활용해서 주식 데이터의 MACD/MACD 오실레이터를 계산하고 차트를 생성해보았다.
pandas의 ewm 메서드 덕분에 비교적 쉽게 해볼 수 있었다.

커피 한 잔으로
저를 응원해주세요!
반응형

loading