[python] 볼린저 밴드(Bollinger bands) - (2) %b와 밴드폭(BandWidth)

[python] 볼린저 밴드(Bollinger bands) - (2) %b와 밴드폭(BandWidth)

1. %b

$$\%b= \frac{종가 - 하단 볼린저 밴드}{상단 볼린저 밴드 - 하단 볼린저 밴드}$$
  • 주가가 볼린저 밴드 어디에 있는지 나타내는 지표

  • %b 값은 종가가 상단밴드를 태그하면 1이되고, 중간밴드를 태그하면 0.5, 하단밴드를 태그하면 0이 됨

  • 만약 종가가 상단밴드 위에 있으면 %b 값은 1보다 커지고, 종가가 하단밴드 아래에 있으면 0보다 작아짐

2. 밴드폭(BandWidth)

$$밴드폭=\frac{상단 볼린저 밴드 - 하단 볼린저 밴드}{중간 볼린저 밴드}$$
  • 상단밴드와 하단밴드 사이의 폭

  • 변동계수와 같은 개념으로 볼 수 있음

  • 볼린저는 밴드폭을 통해 추세의 시작과 끝을 포착해보고자 함

  • (1) 추세의 시작: 변동성이 극히 낮은 수준(ex. 밴드폭의 6개월 저점)까지 떨어져서 곧이어 변동성 증가가 발생할 것으로 예상되는 지점을 추세의 시작으로 봄

  • (2) 추세의 끝: 주가가 강한 상승을 보여 밴드폭이 급격하게 증가하다가 밴드폭의 변동이 없거나 줄어드는 지점을 추세의 끝으로 봄

In [1]:
from pykrx import stock
import pandas as pd
from datetime import datetime # 오늘날짜 가져올때 사용
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors # 색상표

# 한글폰트 설정, 그래프 마이너스 표시 설정
import matplotlib
from matplotlib import font_manager, rc
import platform

if platform.system() == 'Windows':
# 윈도우인 경우
    font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
    rc('font', family=font_name)
else:    
# Mac 인 경우
    rc('font', family='AppleGothic')

matplotlib.rcParams['axes.unicode_minus'] = False
In [2]:
stock_list = pd.DataFrame({'종목코드':stock.get_market_ticker_list(market="ALL")})
stock_list['종목명'] = stock_list['종목코드'].map(lambda x: stock.get_market_ticker_name(x))
# 두산중공업의 2020년 이후 주가 데이터 가져오기
stock_nm = '두산중공업'
ticker = stock_list.loc[stock_list['종목명']==stock_nm, '종목코드']
today = datetime.today().strftime("%Y%m%d")  
df = stock.get_market_ohlcv_by_date(fromdate="20200101", todate=today, ticker=ticker)
df
Out[2]:
시가 고가 저가 종가 거래량
날짜
2020-01-02 5263 5327 5199 5264 732351
2020-01-03 5263 5309 5217 5254 761035
2020-01-06 5208 5245 5070 5098 1346655
2020-01-07 5144 5180 5070 5080 675755
2020-01-08 5052 5061 4822 4878 1736784
... ... ... ... ... ...
2021-06-07 25950 32000 25900 32000 78938648
2021-06-08 31900 31900 25350 25350 69302385
2021-06-09 24800 27650 23650 26100 49304967
2021-06-10 25500 26000 23050 23400 26820159
2021-06-11 23900 24450 22600 23750 20349542

358 rows × 5 columns

In [3]:
df = df.assign(이동평균=df['종가'].rolling(window=20).mean(),
               표준편차=df['종가'].rolling(window=20).std())
df = df.assign(상단밴드=df['이동평균'] + df['표준편차']*2,
               하단밴드=df['이동평균'] - df['표준편차']*2)
df = df.assign(PB=(df['종가']-df['하단밴드']) / (df['상단밴드']-df['하단밴드']),
               밴드폭=(df['상단밴드']-df['하단밴드'])/df['이동평균'])
df = df[19:]
In [5]:
tab_cols = mcolors.TABLEAU_COLORS
plt.figure(figsize=(10, 15))
plt.subplot(3,1,1)
plt.plot(df.index, df['종가'], color=tab_cols['tab:gray'], linewidth=1, label='종가')
plt.plot(df.index, df['상단밴드'], color=tab_cols['tab:red'], linestyle='dashed', linewidth=1, label='상단밴드')
plt.plot(df.index, df['이동평균'], color=tab_cols['tab:green'], linestyle='dashed', linewidth=1, label='20일 이동평균')
plt.plot(df.index, df['하단밴드'], color=tab_cols['tab:blue'], linestyle='dashed', linewidth=1, label='하단밴드')
plt.title(f'{stock_nm}({int(ticker.values)})의 볼린저 밴드(20일, 2 표준편차)')
plt.legend(loc='best')

plt.subplot(3,1,2)
plt.plot(df.index, df['PB'], color=tab_cols['tab:purple'], label='%B')
plt.grid(True)
plt.legend(loc='best')

plt.subplot(3,1,3)
plt.plot(df.index, df['밴드폭'], color=tab_cols['tab:brown'], label='밴드폭')
plt.grid(True)
plt.legend(loc='best');
  • 최근 두산중공업은 주가의 급격한 상승을 보였는데, 밴드폭이 감소 추세로 전환되는 것처럼 보이고, %b 값도 내려가고 있음 기술적 측면에서 볼 때, 두산중공업 주가의 추세가 전환될 것으로 예상해볼 수 있음