기술 분석은 시장의 과거 데이터를 분석하여 미래의 가격 움직임을 예측하는 방법론 중 하나이다. 그 중에서도 MACD(Moving Average Convergence Divergence)는 시장의 트렌드와 모멘텀을 분석하는 데 널리 사용되는 지표이다. 이 글에서는 TA-Lib를 활용하여 MACD Line, Signal Line, 그리고 Histogram을 어떻게 계산하는지에 대한 과정을 소개한다. 또한, MACD의 활용 방법과 이를 통한 트렌드 분석, 오버바이/오버셀 상황의 판단 기준 등을 자세히 살펴본다. TA-Lib의 설치 방법은 [TA-Lib] #2: 기술적 분석을 위한 TA-Lib 설치에서 확인할 수 있으며, MACD의 기본 개념은 [TA-Lib] #5 MACD - MACD 보는 법과 차트 분석에서 볼 수 있다.
MACD의 계산은 TA-Lib 라이브러리를 활용하여 손쉽게 할 수 있다.
MACD(Moving Average Convergence Divergence)의 기본 공식은 장기(보통 26일) 지수 이동 평균(EMA)와 단기(보통 12일) 지수 이동 평균의 차이를 사용하여 계산된다. 또한, Signal Line은 이 MACD Line의 9일 지수 이동 평균으로 구성된다. 이러한 공식이 TA-Lib에서 MACD를 계산할 때의 디폴트 파라미터로 정의되어 있어, 별도의 설정 없이도 기본적인 MACD 분석을 손쉽게 수행할 수 있다. Histogram은 MACD Line과 Signal Line의 차이로, 시장의 모멘텀을 평가하는데 사용된다.
# 라이브러리 임포트
from yahooquery import Ticker
import talib
import pandas as pd
# 삼성전자(005930.KS) 주식 데이터 가져오기
samsung = Ticker('005930.KS')
df = samsung.history(period='2y') # 2년치 데이터
# 기본 설정으로 MACD 계산
macd_line, signal_line, histogram = talib.MACD(df['close'])
# 결과를 DataFrame에 추가
df['macd'] = macd_line
df['signal'] = signal_line
df['histogram'] = histogram
# 결과 출력
print(df.tail())
macd signal histogram
date
2023-08-18 09:00:00+09:00 -1131.574418 -858.195089 -273.379329
2023-08-21 09:00:00+09:00 -1149.339226 -916.423916 -232.915310
2023-08-22 09:00:00+09:00 -1150.159640 -963.171061 -186.988579
2023-08-23 09:00:00+09:00 -1097.809142 -990.098677 -107.710465
2023-08-24 12:57:55+09:00 -956.533862 -983.385714 26.851852
만약 이동 평균의 기간을 커스텀하게 설정하고 싶다면, TA-Lib의 MACD 함수에서 fastperiod
, slowperiod
, signalperiod
파라미터를 조정할 수 있다. 예를 들어, 단기 EMA를 10일로, 장기 EMA를 22일로 설정하고 싶다면, fastperiod=10
, slowperiod=22
로 설정하면 된다. 커스텀 설정은 특정 전략이나 시장 상황에 더 적합한 분석을 위해 사용할 수 있으며, 분석가의 전략에 따라 다양한 방식으로 조정할 수 있다. 이를 통해 보다 유연하게 시장의 트렌드와 모멘텀을 분석할 수 있게 된다.
# 커스텀 이동평균 기간으로 MACD 계산
# 예를 들어, fast_period를 10으로, slow_period를 22로 변경하려면:
macd_line_custom, signal_line_custom, histogram_custom = talib.MACD(df['close'], fastperiod=10, slowperiod=22)
# 결과를 DataFrame에 추가
df['macdCustom'] = macd_line_custom
df['signalCustom'] = signal_line_custom
df['histogramCustom'] = histogram_custom
# 결과 출력
print(df.tail())
macdCustom signalCustom histogramCustom
date
2023-08-18 09:00:00+09:00 -1141.200751 -904.775863 -236.424889
2023-08-21 09:00:00+09:00 -1140.014223 -951.823535 -188.190688
2023-08-22 09:00:00+09:00 -1121.103904 -985.679609 -135.424295
2023-08-23 09:00:00+09:00 -1041.821430 -996.907973 -44.913457
2023-08-24 12:57:55+09:00 -861.775290 -969.881436 108.106146
위 코드를 통해, 각각의 이동 평균 기간을 조절하여 다양한 시장 상황과 전략에 맞게 MACD 분석을 수행할 수 있다.
MACD Line과 Signal Line의 교차는 시장의 변동성을 파악하는 데 중요한 신호로 사용된다. 이 둘이 교차할 때, 트렌드의 변화가 발생할 가능성이 있으므로, 이를 포착하여 투자 결정을 내릴 수 있다.
이 두 교차 현상을 포착하여 트렌드의 변화가 발생할 가능성을 인지하고, 이에 따른 투자 결정을 내릴 수 있다.
import talib
macd, signal, _ = talib.MACD(df['close'])
df['macd'] = macd
df['signal'] = signal
df['upward'] = df['macd'] > df['signal']
df['downward'] = df['macd'] < df['signal']
df['goldenCross'] = (df['upward']) & (~df['upward'].shift(1).fillna(False))
df['deadCross'] = (df['downward']) & (~df['downward'].shift(1).fillna(False))
print('골든 크로스 지점')
print(df[df['goldenCross']])
print('데드 크로스 지점')
print(df[df['deadCross']])
골든 크로스 지점
goldenCross deadCross
date
2021-10-26 09:00:00+09:00 True False
...
2023-08-24 12:57:55+09:00 True False
데드 크로스 지점
goldenCross deadCross
date
2021-10-15 09:00:00+09:00 False True
...
2023-06-14 09:00:00+09:00 False True
Histogram의 크기를 활용한 트렌드 분석은 크게 두 가지 방법으로 진행할 수 있다.
다음은 위 두 가지 사항을 분석하는 예제 코드이다.
macd, signal, histogram = talib.MACD(df['close'])
df['macd'] = macd
df['signal'] = signal
df['histogram'] = histogram
# 트렌드 컬럼 초기화
df['strong_bull'] = False
df['strong_bear'] = False
df['weak_bull'] = False
df['weak_bear'] = False
consecutive_increase = 0
consecutive_decrease = 0
prev_hist_size = abs(df['histogram'][0])
for i in df.index:
curr_hist_size = abs(df['histogram'][i])
if curr_hist_size > prev_hist_size:
consecutive_increase += 1
consecutive_decrease = 0
elif curr_hist_size < prev_hist_size:
consecutive_decrease += 1
consecutive_increase = 0
if consecutive_increase >= 5:
trend_col = 'strong_bull' if df['histogram'][i] > 0 else 'strong_bear'
df.at[i, trend_col] = True
consecutive_increase = 0
if consecutive_decrease >= 5:
trend_col = 'weak_bull' if df['histogram'][i] > 0 else 'weak_bear'
df.at[i, trend_col] = True
consecutive_decrease = 0
prev_hist_size = curr_hist_size
print('강력한 상승 트렌드의 시작 지점')
print(df[df['strong_bull']])
print('강력한 하락 트렌드의 시작 지점')
print(df[df['strong_bear']])
print('상승 트렌드 약화 시작 지점')
print(df[df['strong_bear']])
print('하락 트렌드 약화 시작 지점')
print(df[df['weak_bear']])
강력한 상승 트렌드의 시작 지점
strong_bull strong_bear weak_bull weak_bear
date
2021-12-07 09:00:00+09:00 True False False False
...
2023-05-25 09:00:00+09:00 True False False False
강력한 하락 트렌드의 시작 지점
strong_bull strong_bear weak_bull weak_bear
date
2022-01-19 09:00:00+09:00 False True False False
...
2023-08-08 09:00:00+09:00 False True False False
상승 트렌드 약화 시작 지점
strong_bull strong_bear weak_bull weak_bear
date
2021-12-16 09:00:00+09:00 False False True False
...
2023-06-07 09:00:00+09:00 False False True False
하락 트렌드 약화 시작 지점
strong_bull strong_bear weak_bull weak_bear
date
2021-10-22 09:00:00+09:00 False False False True
...
2023-07-17 09:00:00+09:00 False False False True
이 코드는 Histogram의 크기가 5회 이상 연속으로 증가하거나 감소하는 경우에 트렌드의 강화 또는 약화를 분석한다. 연속으로 증가하거나 감소하는 횟수를 추적하여 트렌드의 정확성을 더욱 높이는 방법을 사용해 시장의 동향을 더욱 정확하게 파악하고, 전략을 조율할 수 있게 된다.
MACD는 마켓의 오버바이와 오버셀 상태를 판단하는 데에도 활용될 수 있다. MACD Line과 Signal Line의 이격을 분석하거나, 제로라인과의 교차를 계산함으로써 마켓 상태를 판단하는 방법을 설명하겠다.
MACD Line과 Signal Line 사이의 이격은 두 선의 거리로 볼 수 있으며, 이를 통해 시장 상태를 분석할 수 있다. 두 선 사이의 거리가 멀면 시장이 과열(오버바이) 상태일 가능성이 있어 매도의 신호로 해석될 수 있다. 반대로 두 선 사이의 거리가 가까우면 시장이 과매도(오버셀) 상태일 가능성이 있으며, 이 경우 매수의 기회로 간주될 수 있다.
이격의 기준은 시장 조건과 종목의 특성에 따라 달라질 수 있다. 아래 코드 예제에서는 현재의 이격값이 과거 30일 동안의 최대 이격값의 80% 이상일 경우, 두 선이 너무 멀리 떨어져 있다고 판단하고 매도 타이밍으로 간주한다. 반대로 현재의 이격값이 과거 30일 동안의 최소 이격값의 120% 미만이면 두 선이 너무 가깝게 붙어 있다고 판단하고 매수 타이밍으로 간주한다.
macd, signal, _ = talib.MACD(df['close'])
df['macd'] = macd
df['signal'] = signal
# MACD Line과 Signal Line의 이격을 계산한다.
df['divergence'] = df['macd'] - df['signal']
# 과거 30일의 최대, 최소 이격값을 계산한다.
df['max_divergence'] = df['divergence'].rolling(window=30).max()
df['min_divergence'] = df['divergence'].rolling(window=30).min()
# 매도 타이밍 판단: 현재 이격값이 최대 이격값의 80% 이상일 경우
df['sell_signal'] = df['divergence'] >= df['max_divergence'] * 0.8
# 매수 타이밍 판단: 현재 이격값이 최소 이격값의 120% 미만일 경우
df['buy_signal'] = df['divergence'] <= df['min_divergence'] * 1.2
print('오버바이')
print(df[df['sell_signal']])
print('오버셀')
print(df[df['buy_signal']])
오버바이
sell_signal buy_signal
date
2021-11-25 09:00:00+09:00 True False
...
2023-08-24 12:57:55+09:00 True False
오버셀
sell_signal buy_signal
date
2021-12-20 09:00:00+09:00 False True
...
2022-11-18 09:00:00+09:00 False True
80%와 120%는 실험적인 값으로, 개별 시장 조건과 전략에 따라 조정될 수 있다.
MACD Line이 제로라인을 상향 또는 하향 돌파하는 시점은 중요한 거래 신호로 볼 수 있다. 제로라인을 상향 돌파하면 매수 신호로, 하향 돌파하면 매도 신호로 볼 수 있다.
# 제로라인 교차 계산
df['cross_zero_line_up'] = (df['macd'] > 0) & (df['macd'].shift(1) <= 0)
df['cross_zero_line_down'] = (df['macd'] < 0) & (df['macd'].shift(1) >= 0)
print('제로라인 상향 돌파')
print(df[df['cross_zero_line_up']])
print('제로라인 하향 돌파')
print(df[df['cross_zero_line_down']])
제로라인 상향 돌파
cross_zero_line_up cross_zero_line_down
date
2021-11-22 09:00:00+09:00 True False
...
2023-03-24 09:00:00+09:00 True False
제로라인 하향 돌파
cross_zero_line_up cross_zero_line_down
date
2022-01-21 09:00:00+09:00 False True
...
2023-07-25 09:00:00+09:00 False True
MACD는 트렌드와 모멘텀 분석에 뛰어난 도구로, 투자 결정에 있어 중요한 지표가 될 수 있다. 이 글을 통해 TA-Lib를 활용하여 MACD를 쉽게 계산하고 분석하는 방법을 배웠다. 이를 통해 시장의 다양한 상황과 전략에 맞게 분석을 수행할 수 있으며, 더욱 정확한 투자 결정을 내릴 수 있게 된다.
CloneCoding
한 줄의 코드에서 시작되는 혁신!