임펄스 MACD (IMPULSE MACD) 파이썬 코딩
임펄스 MACD(Impulse MACD)는 전통적인 MACD를 변형한 지표인데, 시장이 횡보하는지를 확인할 수 있다는 장점이 있습니다. 기존의 전통적인 MACD로는 시장이 횡보하는지를 알기가 어렵습니다. 이번 포스팅에서는 두 MACD를 비교해보고, 임펄스 MACD를 파이썬으로 구현하는 방법까지 알아보겠습니다.
글의 순서
MACD
임펄스 MACD (Impulse MACD)
임펄스 MACD 계산 방법
파이썬 코딩 : 임펄스 MACD
MACD
임펄스 MACD를 이해하기 위해 이동평균선과 MACD를 먼저 살펴보겠습니다. 코인이나 주가의 이동평균선을 각기 다른 시간 구간을 기준으로 표시했다고 가정해보겠습니다. 예를들어 5일선, 10일선을 표시했다면, 5일선을 단기 이동평균선, 10일선을 장기 이동평균선이라고 부를 수 있습니다. 캔들 스틱 차트에 이들 이동평균선을 그려놓고 모양을 관찰해보면, 단기 이동평균선, 장기 이동평균선이 모였다, 벌어졌다를 반복합니다.
MACD는 이들 이동평균선이 모여있는지 벌어져 있는지를 시각화해주는 지표라고 이해하시면 되겠습니다. 모이려고 할 때는 음수, 벌어질려고 할때는 양수로 나타나며, 모이거나 벌어질려고 하는 강도를 막대그래프로 나타낸 것을 MACD 히스토그램이라고 합니다. 따라서 MACD로는 추세와 모멘텀을 동시에 알 수 있습니다.
MACD는 Moving Average Convergence, Divergence를 줄여 쓴 말입니다. 우리말로는 이동평균 수렴, 확산 정도로 표현할 수 있습니다. 모였다, 벌어졌다가 바로 수렴, 확산입니다. 일반적으로 MACD선은 종가의 12일 지수 이동평균선(EMA)에서 26일 지수 이동평균선을 뺀 것으로, 가격 변화를 빠르게 반영하는 편입니다. 12일, 26일 이라는 시간 간격은 각 개인이 시장을 보는 관점에 따라 조절할 수 있습니다.
임펄스 MACD (Impulse MACD)
전통적인 MACD는 위로 갔다 아래로 갔다 쉴 새 없이 움직입니다. 그런데 임펄스 MACD는 중간에 움직이지 않고 있는 것처럼 보이는 구간이 있습니다. 임펄스 MACD가 0에 가까이 붙어있는 구간인데요. 임펄스 MACD가 0에 가까이 붙어있는 구간은 주가가 횡보하고 있다는 것을 나타냅니다. 참고로, 주가가 올라가거나, 내려가지 않는 구간, 즉 주가의 방향성이 뚜렷하지 않을 때를 횡보하고 있다고 표현합니다. 횡보구간이 끝날 때 방향성을 알 수 있습니다.
이처럼 임펄스 MACD는 이동 평균(MA) 특정 범위 내의 값을 필터링함으로써, 횡보 시장에서 흔히 발생하는 잘못된 신호(Whipsaw)를 줄이기 위해 설계되었습니다. Impulse MACD는 고가(high)와 저가(low)의 이동평균 영역을 계산한 후, 이 영역을 벗어나는 움직임만을 사용합니다.
임펄스 MACD 계산 방법
Impulse MACD는 다음과 같은 과정으로 계산됩니다.
step1) 34개의 캔들(34개의 시간 구간)을 기준으로 고가와 저가의 지수이동평균선(EMA)을 구한다
step2) 고가, 저가 중간값의 zero lag EMA를 구한다.
step3) 임펄스 MACD (MD) 계산
– 중간값이 고가보다 높을 경우 : MI – High
– 중간값이 저가보다 낮을 경우 : MI – Low
– 그 외 0
step4) 신호선 : MD의 9개 시간구간 단순 이동평균(SMA)
step5) 히스토그램 : 임펄스 MACD와 신호선 간의 차이 계산
임펄스 MACD는 ZLEMA(Zero Lag EMA)를 기반으로 계산된 중간값(MI, Midpoint)과 상단 및 하단 경계값(SMMA High, SMMA Low) 간의 상대적 위치를 나타냅니다. 또한 신호선(Impulse Signal)은 임펄스 MACD의 단순이동평균(스무딩한 값)입니다. 마지막으로 히스토그램(Impulse Histogram)은 Impulse MACD와 Impulse Signal 간의 차이룰 나타내며, 이를 통해 시장의 변화를 시각적으로 확인할 수 있습니다.
파이썬 코딩 : 임펄스 MACD
Impulse MACD를 아래의 파이썬 코드에서 구현하였습니다. Impulse MACD는 전통적인 MACD를 확장한 지표로, 시장의 횡보 구간에서 발생하는 노이즈를 줄이고 주요 추세를 더 명확하게 파악하기 위해 개발된 지표입니다. 아래의 파이썬 코드는 Binance API를 활용하여 이더리움의 일별 데이터를 가져오고, 이를 기반으로 Impulse MACD를 계산하여 시각화합니다.
파이썬 pyplot으로 구현된 캔들스틱 차트에 볼린저 밴드를 함께 나타내고, 그 아래에는 MACD와 Impulse MACD 지표를 계산하고 시각화합니다. 위에서 설명한 변수들을 중심으로 코드를 살펴보면 이해가 쉬워집니다. Impulse는 ZLEMA(Zero Lag EMA)를 기반으로 계산된 중간값(Midpoint)과 상단 및 하단 경계값(SMMA High, SMMA Low) 간의 상대적 위치를 나타냅니다. Impulse Signal은 이 값을 스무딩한 값(단순이동평균)으로, Impulse MACD의 주요 신호선 역할을 합니다. 마지막으로 Impulse Histogram은 Impulse와 Impulse Signal 간의 차이로, 시장의 변화를 시각적으로 확인할 수 있습니다.
Impulse MACD 계산을 위한 주요 함수는 다음과 같습니다.
▶calc_smma 함수는 LazyBear 알고리즘에 따라 SMMA(지수형 단순 이동 평균)를 계산합니다.
▶calc_zlema 함수는 Zero Lag EMA를 계산하여 Impulse MACD의 중간값 역할을 합니다.
▶calculate_impulse_macd 함수는 ZLEMA와 SMMA 상단 및 하단 값의 상대적 위치를 기반으로 Impulse 값을 계산하며, 이를 스무딩하여 신호선과 히스토그램을 생성합니다.
캔들스틱 차트의 두께는 candle_width로, 히스토그램의 폭은 bar_width로 설정됩니다.
Impulse MACD, 신호선, 히스토그램은 plot과 bar를 이용해 각각 시각화됩니다.
MACD와 Impulse MACD의 두 히스토그램을 서로 비교해보면 Impulse MACD가 0인 구간이 눈에 띕니다. 다만, MACD와 Impulse MACD의 window, length가 다르므로 직접적으로 1:1 비교를 할 수는 없습니다. 두 지표의 시간 구간을 맞춰서 직접적으로 비교할 수 있는 방안을 다음 포스팅에서 찾아 보겠습니다.
마지막으로 코드의 맨 아래 부분은 생성된 차트를 PNG 파일로 저장하는 방법을 포함합니다. 이 코드에서는 그래프가 C:/_python/impulse_macd/라는 폴더에 저장되도록 설정하였습니다. 물론, 저장 경로는 각자 원하는 곳으로 변경할 수 있습니다. Impulse MACD와 함께 시장의 흐름을 분석하고 매매 전략을 세워 보시기 바랍니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
import os import pandas as pd import numpy as np from binance.client import Client import datetime from datetime import datetime, timedelta import matplotlib.pyplot as plt import matplotlib.dates as mdates # 01) 바이낸스 계정 접속 api_key = os.getenv('Binan_API_KEY') api_secret = os.getenv('Binan_SECRET_KEY') client = Client(api_key, api_secret) print('\n', '[ BINANCE ACCOUNT ACCESSED ]') # 02) 입력 : 시계열 데이터 수집 구간(tstt~tend), 시간 간격(t_interval) tstt_utc = '2024-07-01 00:00:00' tend_utc = '2025-01-04 23:59:59' t_interval = '1d' symbol = 'SOLUSDT' # 그래프에 나타낼 구간 tstt_KST = datetime.strptime('2024-09-01 00:00:00', '%Y-%m-%d %H:%M:%S') tend_KST = datetime.strptime('2025-01-04 23:59:59', '%Y-%m-%d %H:%M:%S') # 01-3) 시간 형식을 'YYMMDD_HHMM'로 변환 time_start_kst_str = tstt_KST.strftime('%y%m%d_%H%M') time_end_kst_str = tend_KST.strftime('%y%m%d_%H%M') file_name_only = f'{symbol}_{t_interval}_{time_start_kst_str}~{time_end_kst_str}_Impulse_MACD.png' file_path = 'C:/_python/impulse_macd/' file_name = file_path + file_name_only # 볼린저밴드 중앙선인 SMA를 구하기 위한 시간 구간 개수 period = 20 # 볼린저밴드 sigma 값 설정 sigmas=[2] shading_sigma = 2 # 음영 처리할 sigma 값 colors = ['royalblue','green','orange'] # 03) 파이썬 바이낸스 API로 비트코인 가격 데이터 가져오기 bars = client.get_historical_klines(symbol, t_interval, tstt_utc, tend_utc, limit=1000) # 03-1) ohlcv 데이터만 추출 for i in bars: del i[6:] # 04) 데이터프레임 열 이름 붙여주기 df = pd.DataFrame(bars, columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume']) # 05) 데이터프레임 열 type을 실수형으로 변환 df = df.astype({'Open': 'float', 'High': 'float', 'Low': 'float', 'Close': 'float', 'Volume': 'float'}) # 06) Date 열의 형태를 epoch에서 Pandas.Timestamp로 변경 df['Date'] = pd.to_datetime(df['Date'], unit='ms').dt.tz_localize('UTC').dt.tz_convert('Asia/Seoul').dt.tz_localize(None) # 07-1) 볼린저 밴드 def calculate_bollinger_bands(df, period, sigmas): df['SMA'] = df['Close'].rolling(window=period).mean() df['stddev'] = df['Close'].rolling(window=period).std() for sigma in sigmas: df[f'Upper Band {sigma}'] = df['SMA'] + (df['stddev'] * sigma) df[f'Lower Band {sigma}'] = df['SMA'] - (df['stddev'] * sigma) return df # MACD 계산 def calculate_macd(df, short_window, long_window, signal_window): df['EMA_sw'] = df['Close'].ewm(span=short_window, adjust=False).mean() df['EMA_lw'] = df['Close'].ewm(span=long_window, adjust=False).mean() df['MACD'] = df['EMA_sw'] - df['EMA_lw'] df['Signal'] = df['MACD'].ewm(span=signal_window, adjust=False).mean() df['Histogram'] = df['MACD'] - df['Signal'] return df # Impulse MACD 계산 # SMMA 계산 함수 def calc_smma(series, length): smma = series.rolling(window=length, min_periods=1).mean() for i in range(length, len(series)): smma[i] = (smma[i - 1] * (length - 1) + series[i]) / length return smma # ZLEMA 계산 함수 def calc_zlema(series, length): lag = (length - 1) // 2 lagged_series = series.shift(lag) ema = series.ewm(span=length, adjust=False).mean() ema_lagged = lagged_series.ewm(span=length, adjust=False).mean() return 2 * ema - ema_lagged def calculate_impulse_macd(df, ma_length, signal_length): hlc3 = (df['High'] + df['Low'] + df['Close']) / 3 smma_high = calc_smma(df['High'], ma_length) smma_low = calc_smma(df['Low'], ma_length) zlema = calc_zlema(hlc3, ma_length) df['Impulse'] = np.where(zlema > smma_high, zlema - smma_high, np.where(zlema < smma_low, zlema - smma_low, 0)) df['Impulse_Signal'] = df['Impulse'].rolling(window=signal_length).mean() df['Impulse_Histogram'] = df['Impulse'] - df['Impulse_Signal'] return df df = calculate_bollinger_bands(df, period, sigmas) df = calculate_macd(df, short_window=12, long_window=26, signal_window=9) df = calculate_impulse_macd(df, ma_length=34, signal_length=9) print(df['Histogram']) # 08) 캔들 차트 및 지표 그리기 df = df[(df['Date'] >= tstt_KST) & (df['Date'] <= tend_KST)] fig, axs = plt.subplots(3, 1, figsize=(12, 15), sharex=True) title_plot = f'{symbol} Bollinger Band & MACD' # 캔들 차트 그리기 # candle 두께, bar 두께를 각기 다른 방법으로 설정 ''' plot()은 x축 좌표와 관계없이 선 두께를 픽셀 단위로 적용 bar()의 width는 x축 좌표의 간격을 기준으로 적용 ''' candle_width = max(0.1, 0.5 * (axs[1].get_window_extent().width / len(df))) bar_width = 0.7 for i in range(len(df)): color = 'green' if df['Close'].iloc[i] >= df['Open'].iloc[i] else 'red' axs[0].plot([df['Date'].iloc[i], df['Date'].iloc[i]], [df['Low'].iloc[i], df['High'].iloc[i]], color=color) axs[0].plot([df['Date'].iloc[i], df['Date'].iloc[i]], [df['Open'].iloc[i], df['Close'].iloc[i]], color=color, linewidth=candle_width) for sigma, color in zip(sigmas, colors): axs[0].plot(df['Date'], df[f'Upper Band {sigma}'], label=f'Upper Band {sigma}', color=color, linestyle='--') axs[0].plot(df['Date'], df[f'Lower Band {sigma}'], label=f'Lower Band {sigma}', color=color, linestyle='--') axs[0].plot(df['Date'], df['SMA'], label='SMA', color='navy', linestyle='-.') # 볼린저 밴드(shading_sigma)를 회색영역으로 표시 axs[0].fill_between(df['Date'], df[f'Upper Band {shading_sigma}'], df[f'Lower Band {shading_sigma}'], color='0.9') axs[0].legend() axs[0].set_title(title_plot, fontsize=20) axs[0].set_ylabel('Price (USDT)') axs[0].grid(True) # MACD axs[1].plot(df['Date'], df['MACD'], label='MACD', color='blue') axs[1].plot(df['Date'], df['Signal'], label='Signal', color='orange') axs[1].bar(df['Date'], df['Histogram'], label='Histogram', color='gray', alpha=0.9, width=bar_width) axs[1].axhline(0, color='black', linestyle='--', linewidth=1) axs[1].set_xlim([tstt_KST, tend_KST]) axs[1].tick_params(axis='x', rotation=15) axs[1].legend(loc='best') axs[1].grid(True) # Impulse MACD axs[2].plot(df['Date'], df['Impulse'], label='Impulse MACD', color='green') axs[2].plot(df['Date'], df['Impulse_Signal'], label='Impulse Signal', color='red') axs[2].bar(df['Date'], df['Impulse_Histogram'], label='Impulse Histogram', color='purple', alpha=0.9, width=bar_width) axs[2].legend() axs[2].grid(True) plt.subplots_adjust(hspace=0.03) plt.savefig(file_name, dpi=200) plt.show() |
마치며 …
이번 포스팅에서는 전통적인 MACD와 Impulse MACD를 비교하며, Impulse MACD가 시장 분석에 어떤 이점을 제공하는지 살펴보았습니다. Impulse MACD는 횡보 시장에서 발생하는 잘못된 신호를 줄이고 주요 추세를 더욱 명확하게 파악할 수 있도록 설계된 기술적 분석 도구입니다. 특히, 시장의 방향성이 없는 구간을 효과적으로 시각화하여 트레이더가 불필요한 매매를 피하도록 돕습니다. Impulse MACD와 함께 시장의 흐름을 더욱 깊이 이해하고, 스마트한 투자 결정을 내릴 수 있기를 바랍니다.
함께 참고하면 좋은 글
▶ 호크아이 거래량 지표 (HawkEye Volume Indicator) 파이썬 코딩
▶ 볼린저밴드, BBW, 파이썬 pyplot 캔들스틱 차트에 표시 방법
▶ 바이낸스 API, 판다스 시계열 데이터 분석. 볼린저 밴드 지표 %b, 밴드폭(Bandwidth)
▶ 캔들 차트의 의미와 파이썬 pyplot으로 그리는 캔들스틱 차트
▶ 파이썬 바이낸스 API로 시계열 데이터 분석. 판다스, 볼린저 밴드 (Bollinger Band)
▶ 파이썬 바이낸스 비트코인 투자 백테스팅 : 볼린저 밴드 추세 추종 매매 기법
▶ 파이썬 바이낸스 API로 시계열 데이터를 가져오는 파이썬 프로그래밍
▶ mplfinance 캔들 차트 스타일
▶ 캔들 차트 스타일 변경 (mplfinance, customization)
▶ 바이낸스 API 보안을 위한 환경 변수 설정 : 윈도우 10
▶ 시계열 데이터 분석 : 추세분석 지표 6가지