본문 바로가기

Python/Investment

Python으로 볼린저밴드 계산 및 차트 생성

반응형

Python으로 볼린저 밴드 계산 및 차트 생성

이번 포스트에서는 Python으로 주식 투자의 핵심 도구 중 하나인 볼린저 밴드를 구현해보고자 한다.
볼린저 밴드는 주식, 외환, 상품 등 다양한 금융 상품의 가격 변동성을 측정하고 상대적인 고저점을 식별하는 데 사용되는 테크니컬 분석 도구이다.
필자도 HTS와 MTS에는 볼린저 밴드를 항상 설정해두고 보는 편이다.
그럼 볼린저 밴드가 무엇인지 간단하게 살펴보고 Python으로 계산 및 차트를 생성해보자.

목차

볼린저 밴드(Bollinger Bands)란?

볼린저 밴드는 존 볼린저가 개발한 테크니컬 분석 도구로, 주가의 변동성을 측정하고 상대적인 고저점을 식별하는 데 사용된다.
볼린저 밴드는 중앙선(중심선)과 이를 중심으로 한 상단 밴드(상한선)하단 밴드(하한선), 총 세 개의 선으로 이루어져 있다.

이 세 개의 라인은 주가의 상대적인 '높음'과 '낮음', 그리고 변동성을 명확하게 보여준다.

가격이 상단 밴드에 근접하면 주식이 과매수 상태에 있다는 신호로 해석될 수 있으며,
반대로 가격이 하단 밴드에 근접하면 과매도 상태로 해석될 수 있다.


볼린저밴드


추가적인 설명 및 활용법/매매 방법은 아래 포스트에서 확인 가능하다.

볼린저 밴드 계산 방법

볼린저 밴드는 세 개의 라인으로 구성되어 있는데, 각각의 계산 방법은 아래와 같다.

✔ 볼린저 밴드 계산 방법

  • 중앙선(중심선) : n일간의 단순 이동 평균(SMA: Simple Moving Average)
    일반적으로 20일 이동평균을 사용한다.
    \( \text{Middle Band} = \text{SMA(n)} \)

  • 상단 밴드(상한선): 중앙선에서 2(일반적으로)의 표준 편차를 더한 값
    \( \text{Upper Band} = \text{SMA(n)} + 2*stddev(n) \)

  • 하단 밴드(한선): 중앙선에서 2의 표준 편차를 뺀 값
    \( \text{Lower Band} = \text{SMA(n)} - 2*stddev(n) \)

여기서 'stddev(n)'는 n일간의 종가 표준 편차이다.

볼린저 밴드 계산 코드 구현

그럼 이제 볼린저 밴드를 계산해보자.
샘플 데이터는 아래 이미지와 같으며, pandas와 이따 차트를 생성하기 위한 matplotlib를 같이 import 하겠다.
볼린저 밴드를 계산하려면 종가만 필요하다.
여기서 close가 종가이다.

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('../TEST.csv')
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')

샘플 데이터


볼린저 밴드를 계산하려면 우선 20일 이동평균선을 계산해야한다.
위에서 설명한 바와 같이 중심선을 기준으로 상한선과 하한선을 계산하는데, 중심선이 20일 이동평균선이기 때문이다.
물론 20일이라는건 볼린저 밴드의 기본값인 것이고, 입맛에 맞게 변경 가능하다.
20일 이동평균선을 구하려면 pandas 라이브러리의 rolling 메서드를 사용하면 아주 간단하게 구할 수 있다.
rolling 메서드에 대한 내용은 이동평균선 관련 포스트에 작성해놨는데 아래 포스트를 참고하면 좋을 것 같다.

우선 20일 기준으로 중앙선, 상한선, 하한선을 모두 계산할 예정이니 20으로 선언한 window 변수를 선언해두고 시작하겠다.

# 20일 기준으로 계산
window = 20

✔ 중심선

우선 rolling으로 20일 이동평균 값들을 DataFrame에 저장한다.
이것이 이제 중심선이다.

# 중심선 (20일 이동평균선)
df['MA20'] = df['close'].rolling(window).mean()

✔ 상한선

중심선 기준으로 20일 기준의 2의 표준 편차를 더한 값이 상한선이다.
DataFrame에 upper 컬럼을 추가해서 저장해주겠다.
여기서 'std()' 이것은 표준편차를 구하는 메서드이다.

# 상한선
df['upper'] = df['MA20'] + 2 * df['close'].rolling(window).std()

✔ 하한선

중심선 기준으로 20일 기준의 2의 표준 편차를 뺀 값이 하한선이다.
DataFrame에 lower 컬럼을 추가해서 저장해주겠다.

# 하한선
df['lower'] = df['MA20'] - 2 * df['close'].rolling(window).std()

이렇게 간단하게 볼린저 밴드를 계산해볼 수 있다.
최종적으로 저장된 데이터 프레임은 아래와 같다.


볼린저 밴드 계산 결과 (NaN 제외)

볼린저 밴드 차트 생성

그럼 이제 계산된 볼린저 밴드 값들로 차트를 생성해보자.
matplotlib를 사용할 것이며, 종가 차트와 함께 생성해보겠다.
종가선은 파란색, 중심선은 주황색, 상한선과 하한선은 녹색으로 하고 상한선과 하한선의 사이를 배경색을 적용해보겠다.
그리고 여기서 matplotlib.dates의 mdates를 사용하겠다.


matplotlib.dates는 matplotlib 라이브러리에서 날짜와 시간 기반의 데이터를 다루기 위한 모듈이다.
이 모듈은 시간 표현을 관리하고, 시간 기반의 플롯(plot)을 생성하거나 조정하는 데 사용된다.
이 모듈의 주요 기능과 클래스 중 몇개만 소개하겠다.

✔ Date Locator

눈금의 위치를 결정하는 역할을 한다.
이에는 여러 클래스가 있으며, HourLocator, DayLocator, MonthLocator, YearLocator 등이 있다.
이들 클래스를 사용하면 시간 단위, 일 단위, 월 단위, 년 단위 등으로 눈금 위치를 설정할 수 있다.

## Example
# 시간 단위 데이터 생성
ax.xaxis.set_major_locator(mdates.HourLocator(interval = 1))

# 2일 간격으로 눈금 위치 설정
ax.xaxis.set_major_locator(mdates.DayLocator(interval=2))

# 월별로 눈금 위치 설정
ax.xaxis.set_major_locator(mdates.MonthLocator())

# 년도 단위로 눈금 위치 설정
ax.xaxis.set_major_locator(mdates.YearLocator())

✔ Date Formatter

눈금 레이블의 형식을 제어하는 역할을 한다.
이를 사용하면 날짜를 원하는 형식으로 표시할 수 있다.

# '년-월-일' 형식으로 라벨 설정
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))


그럼 이제 matplotlib의 dates 모듈을 함께 사용해서 볼린저 밴드의 차트를 생성해보자.
우선 plot으로 차트를 생성해주고, 종가, 중심선, 상한선, 하한선을 설정한다.

import matplotlib.dates as mdates

fig, ax = plt.subplots(figsize=(14,7))
ax.plot(df.index, df['close'], color='#1f77b4', label='Close Price')
ax.plot(df.index, df['MA20'], color='#ff7f0e', label='Moving Average (20 days)')
ax.plot(df.index, df['upper'], color='#2ca02c', label='Upper Bollinger Band')
ax.plot(df.index, df['lower'], color='#2ca02c', label='Lower Bollinger Band')

그리고 상한선과 하한선 사이의 배경색을 설정해주겠다.
상한선과 하한선의 같은 color로 하고 alpha를 0.1로 설정해서 투명도를 조절했다.

# 상한선과 하한선 사이의 배경 설정
ax.fill_between(df.index, df['lower'], df['upper'], color='#98df8a', alpha=0.1)

x축에는 날짜가 눈금으로 들어갈 것이다.
그냥 하게 되면 모든 날짜의 텍스트가 겹쳐지게 되어서 보기 좋지 않다.
MonthLocator로 월 단위로 x축 label이 표시되게 설정하고, DateFormatter로 '월 년' 형태로 표시되게 설정했다.

# 월 단위로 x축 눈금 설정
ax.xaxis.set_major_locator(mdates.MonthLocator())

# '월 년'으로 눈금 포맷팅
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))

이제 마지막으로 타이틀과 xlabel, ylabel을 설정하면 끝이다.

plt.title('Bollinger Bands')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend()
plt.grid(True)
plt.show()

최종 결과는 아래 이미지와 같다.


볼린저 밴드 차트 생성

이렇게 해서 Python으로 주식 보조지표 중 하나인 볼린저 밴드를 계산하고 차트를 생성해보았다.
겸사겸사 matplotlib의 dates로 date를 라벨로 표시할 때 단위 설정 및 포맷팅 하는 방법도 함께 알아보았다.
필자도 공부가 많이 되었던 것 같다.

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

loading