본문 바로가기

주식 분석

기술적 분석 (3) - 불린저 밴드(Bollinger Bands)

 이번에 소개해 드릴 지표는 불린저 밴드 입니다. 이평선, MACD 처럼 상당히 인지도가 있는 지표 입니다. 존 볼린저라는 미국의 유명한 재무분석가가 1980년대에 만들었다고 합니다. 

 주가가 이평선을 중심으로 일정한 범위(표준편차) 안에서 움직인다는 전제로 개발 되었습니다. 통계적으로 보면 어떤 분포가 정규분포를 따를때, 평균값을 기준으로 앞 뒤 2 표준편차 이내에 약 95%의 샘플이 존재합니다. 따라서 이 표준편차 밖에 값이 있을 확률이 5% 정도 입니다. 볼린저 밴드는 이러한 통계를 배경으로 만들어졌습니다.

 

 구성 요소는 중심선, 상한선, 하한선 입니다.

1) 중심선 - 이동평균선 (일반적으로 20일선)

2) 상한선 - 이동평균선 + 2표준편차

3) 하한선 - 이동평균선 - 2표준편차

삼성전자 차트(영웅문)

 볼린저 밴드 20,2의 20은 20일 이동평균선을 사용했다는 것이고, 2는 표준편차를 두번 플러스 마이너스 해서 상한선과 하한선을 설정했다는 의미 입니다. 보시다시피 볼린저 밴드의 상한선과 하한선의 바깥에 주가가 형성이 되는 경우가 극히 드뭅니다. 바깥에 형성이 되더라도 금방 안쪽으로 돌아오게 되어 있습니다. 

 

 볼린저 밴드를 이용하기 위해서는 매매신호 보다 특성을 잘 아는것이 중요합니다.

 1) 가격의 등락폭이 적을 때는 밴드의 상, 하한선 폭이 축소 -> 박스권을 나타내는 것으로 볼 수 있음.

 2) 가격의 등락폭이 클 때는 밴드의 상, 하한선 폭이 확대

 

 위와 같은 특성을 이용해서, 가격이 볼린저 밴드를 벗어나는 경우를 확인합니다. 그리고 다른 지표와 상황을 토대로 매매신호를 파악합니다. 볼린저 밴드의 상한선을 뚫고 상승한 경우에, 다른 지표나 상황이 좋다면 상승세로 봐서 매수를 할 수 있습니다. 그러나 다른 지표나 상황이 좋지 않다면, 과매수 상황으로 볼 수 있는것이죠.

 

 의미도 알기 쉽고, 보기도 편하기 때문에 직관적인 지표긴 합니다. 그러나 한계도 존재합니다. 가격이 급등락 할때는 변동성이 크니 비교적 매매신호를 포착하기 쉽고, 분명한 신호를 준다고 합니다. 그러나 가격이 완만하게 등락을 할때는 변동성이 적어져, 매매신호가 분명하지 않다고 합니다. 또한 후행 지표의 특성상 볼린저 밴드만을 사용해서 거래를 하는게 아니라, 다른 지표들이나 정보를 혼합해서 사용하는게 적절합니다.

 


Python으로 보여주기 위해서 데이터와 라이브러리를 불러옵니다.

.
import pandas as pd
import numpy as np
import plotly.graph_objects as go

path_dir = './data'
data = np.loadtxt(path_dir + '/' + '000660_from_2010.csv', delimiter = ',')
data = pd.DataFrame(data)
data.columns = ['Open', 'High', "Low", "Close", "Volumn", "Adj"]

위에서 설명한대로 불린저밴드의 요소들을 계산해줍니다.

.
def cal_bb(stock, w=20, k=2) :
    x = pd.Series(stock)
    mbb = x.rolling(w).mean()
    ubb = mbb + k * x.rolling(w).std()
    lbb = mbb - k * x.rolling(w).std()

    return mbb, ubb, lbb
    
data["MBB"], data["HBB"], data["LBB"] = cal_bb(data["Close"])

그리고 그려줍니다.

.
fig = go.Figure()

fig.add_trace(go.Scatter(x=data.index, y=data["Close"],
                        mode='lines',
                        name="Close"))
fig.add_trace(go.Scatter(x=data.index, y=data["MBB"],
                        mode='lines',
                        name="MBB"))
fig.add_trace(go.Scatter(x=data.index, y=data["HBB"],
                        mode='lines',
                        name="HBB"))
fig.add_trace(go.Scatter(x=data.index, y=data["LBB"],
                        mode='lines',
                        name="LBB"))
fig.update_layout(title='Close and Bollinger Bands',
                   xaxis_title='days',
                   yaxis_title='StockValue')

fig.show()

 전체 시간을 대상으로 보여주면, 불린저 밴드가 잘 안보여서 350일 거래일 정도의 데이터만 잘라서 캡쳐했습니다.

 


 위와 같은 지표를 모델링에 사용할때는 주의점이 있을 것 같습니다. 딥러닝에서 사용하는 Fully Connected layer는 불린저 밴드의 의미를 학습 할 수도 있겠습니다만, 쉽지는 않겠죠. 또한 Tree 모형등에서는 불린저 밴드의 상한선, 하한선 값 자체로는 별 의미를 찾을 수 없을 것 입니다.

 그래서 실제 주가와 불린저 밴드간의 관계를 알려줄 수 있는 변수를 새로 만든다던가, 볼린저 밴드 바깥에서 주가가 형성될 때의 신호를 줄 수 있는 변수를 만드는 등의 노력이 필요할 것으로 보입니다.