-
[금융경제] 볼린저밴드(Bollinger Bands) 투자 기법__Data Analysis/교육 2021. 6. 8. 23:13
볼린저밴드 관련 지표
- 20일 이동평균선
- %b
- 밴드폭(bandwidth)
- MFI(+RSI)
[ 코드 구현 ]
라이브러리 불러오기¶
import pandas as pd import numpy as np import pandas_datareader as pdr import FinanceDataReader as fdr from matplotlib import dates as mdates %matplotlib inline from pykrx import stock from xml.etree import ElementTree import warnings warnings.filterwarnings(action='ignore') # pd.set_option('display.float_format', '${:.6g}'.format) # pd.options.display.float_format = '{:.6f}'.format import seaborn as sns import matplotlib.pyplot as plt plt.rcParams['font.family'] = 'Malgun Gothic'
함수 정의 ¶
def myplot(df, nrows=5, kind='line', title='제목', labels=False): if nrows > 0: print(df.head(nrows)) else: print(df.tail(nrows)) if labels: cols = df.columns for i, col in enumerate(cols): df[col].plot(label=labels[i], kind=kind) else : df.plot(kind=kind) plt.title(title) plt.legend() plt.show()
파라미터 정의 ¶
- 100개 데이터를 확인하고자 함df = pd.DataFrame() df = my_krx('20181203', '20210427', '005930') df.head()
>outsuccess:1, failed:0
date code open high low close volume 0 2018-12-03 005930 42750 43400 42400 43250 12110702 1 2018-12-04 005930 42650 42900 41900 42150 14347746 2 2018-12-05 005930 40900 41750 40850 41450 12631983 3 2018-12-06 005930 40600 41100 40450 40500 14251826 4 2018-12-07 005930 40900 41400 40850 40950 11433083 - 지표 : 20일 이동평균선
df['m20']= df['close'].rolling(20).mean() df['m20_std']= df['close'].rolling(20).std() df['upper']= df['m20'] + df['m20_std']*2 df['lower']= df['m20'] - df['m20_std']*2
- rolling 후 생겨난 null값 행 삭제df.dropna(axis=0, inplace=True)
- 날짜데이터 datetime 타입으로 변형, index 설정df['date']= pd.to_datetime(df['date']) df.set_index('date',inplace=True)
df.head()
Out>code open high low close volume m20 m20_std upper lower date 2019-01-02 005930 39400 39400 38550 38750 7847664 39772.5 1370.312584 42513.125169 37031.874831 2019-01-03 005930 38300 38550 37450 37600 12471493 39490.0 1185.615541 41861.231082 37118.768918 2019-01-04 005930 37450 37600 36850 37450 14108958 39255.0 1092.787358 41440.574717 37069.425283 2019-01-07 005930 38000 38900 37800 38750 12748997 39120.0 966.872331 41053.744663 37186.255337 2019-01-08 005930 38000 39200 37950 38100 12756554 39000.0 934.992260 40869.984520 37130.015480 - 볼린저밴드 차트 확인
plt.plot(df['close'].iloc[:SIZE_],label='close') plt.plot(df['m20'].iloc[:SIZE_],label='m20') plt.plot(df['upper'].iloc[:SIZE_],label='upper') plt.plot(df['lower'].iloc[:SIZE_],label='lower') plt.legend() plt.fill_between(df.iloc[:SIZE_].index, df['upper'].iloc[:SIZE_], df['lower'].iloc[:SIZE_],alpha=0.2) plt.show()
df['%b']= (df['close']-df['lower'])/(df['upper']-df['lower'])
plt.plot(df['close'].iloc[:SIZE_],label='close') plt.plot(df['%b'].iloc[:SIZE_],label='%b') plt.plot(df['m20'].iloc[:SIZE_],label='m20') plt.plot(df['upper'].iloc[:SIZE_],label='upper') plt.plot(df['lower'].iloc[:SIZE_],label='lower') plt.legend() plt.fill_between(df.iloc[:SIZE_].index, df['upper'].iloc[:SIZE_], df['lower'].iloc[:SIZE_],alpha=0.2) plt.show()
- 볼린저밴드, 주가 데이터가 %b와 지수가 달라 차트에서 비교 불가- 이중 차트를 그려 해결=>>plt.plot(df['close'].iloc[:SIZE_], label = 'close') plt.plot(df['m20'].iloc[:SIZE_], label= 'm20') plt.plot(df['upper'].iloc[:SIZE_], label='upper') plt.plot(df['lower'].iloc[:SIZE_], label= 'lower') plt.fill_between(df.iloc[:SIZE_].index, df['upper'].iloc[:SIZE_], df['lower'].iloc[:SIZE_], alpha =0.2) plt.legend() plt.twinx() plt.plot(df['%b'].iloc[:SIZE_],label = '%b' , color = 'yellow') plt.legend() plt.show()
- %b와 종가는 유사하게 움직인다. 즉, %b는 주가의 흐름을 따른다- 지표: 밴드폭(bandwidth)¶
- 스퀴즈 파악에 유용
- 주가가 극도로 떨어져 이제 곧 반등세(상승세)를 보일 것으로 예상되는 상황
- 밴드폭= (상한-하한)/중간 (option *100(비율))
df['bwith']= (df['upper']-df['lower'])/df['m20']
plt.figure(figsize=(10,5)) plt.plot(df['close'].iloc[:SIZE_], label = 'close') plt.plot(df['m20'].iloc[:SIZE_], label= 'm20') plt.fill_between(df.iloc[:SIZE_].index, df['upper'].iloc[:SIZE_], df['lower'].iloc[:SIZE_], alpha =0.2) plt.legend() plt.twinx() plt.plot(df['%b'].iloc[:SIZE_],label = '%b' , color = 'purple') plt.plot(df['bwith'].iloc[:SIZE_],label = 'bwith' , color = 'yellow') plt.legend() plt.show()
- 변동성이 크다 = 밴드폭이 크다
- 밴드폭 최상 = lower 최저
RSI(상대강도지수), MFI(현금흐름지표)¶
- 일중강도지수는 II
볼린저밴드 매매 전략¶- 변동성 돌파
- 추세 추종 >> 추세가 상승세에 매수, 하락세에 매도
- 반전(반등세) >> 꺾이는 지점, 주가가 반등세인 구간을 찾아내 매수, 매도
현금흐름지수 계산
- 추세추종: 현금흐름지수(MFI)를 따른다
- MF => 평균가 (고가,저가,종가)/3 * 거래량
- MFI= 100 - (100/ (1+긍정현금흐름/부정현금흐름) )
- 긍정현금흐름: 중심가가 전날보다 상승한 날들의 일수 합
- 부정현금흐름: 중심가가 전날보다 하락한 날들의 일수 합df.head()
Out>code open high low close volume m20 m20_std upper lower %b bwith date 2019-01-02 005930 39400 39400 38550 38750 7847664 39772.5 1370.312584 42513.125169 37031.874831 0.313455 0.137815 2019-01-03 005930 38300 38550 37450 37600 12471493 39490.0 1185.615541 41861.231082 37118.768918 0.101473 0.120093 2019-01-04 005930 37450 37600 36850 37450 14108958 39255.0 1092.787358 41440.574717 37069.425283 0.087065 0.111353 2019-01-07 005930 38000 38900 37800 38750 12748997 39120.0 966.872331 41053.744663 37186.255337 0.404331 0.098862 2019-01-08 005930 38000 39200 37950 38100 12756554 39000.0 934.992260 40869.984520 37130.015480 0.259356 0.095897 - 지표: MFI ¶
# MFI df['medium'] =(df['high']+ df['low']+ df['close'])/3 # 평균가 df['m_shift']= df['medium'].shift(1) # 전일가 # 현금흐름 분류 df['positive'] = (df['medium'] > df['m_shift']).apply(lambda x:1 if x==True else 0) df['negative'] = (df['medium'] <= df['m_shift']).apply(lambda x:1 if x==True else 0) # MF = 전일보다 올랐을 때의 MF 합, 전일보다 내렸을 때의 MF 합 df['positive']*= df['medium']* df['volume'] # 긍정현금흐름 df['negative']*= df['medium']* df['volume'] # 부정현금흐름 df['MFI'] = 100 - (100 / (1 + (df['positive'].sum() / df['negative'].sum())) ) df['MFI10'] = 100 - (100 / (1 + (df['positive'].rolling(10).sum() / df['negative'].rolling(10).sum())) )
- MFI 결과값 확인
df.tail()
Out[20]:code open high low close volume m20 m20_std upper lower %b bwith medium m_shift positive negative MFI MFI10 date 2021-04-21 005930 83300 83500 82500 82600 21636079 83495.0 1430.669700 86356.339399 80633.660601 0.343605 0.068539 82866.666667 83666.666667 0.000000e+00 1.792910e+12 54.91464 46.708272 2021-04-22 005930 82900 83000 82400 82400 13934746 83555.0 1352.376077 86259.752153 80850.247847 0.286487 0.064742 82600.000000 82866.666667 0.000000e+00 1.151010e+12 54.91464 48.408114 2021-04-23 005930 81900 82900 81600 82800 17805080 83620.0 1277.579949 86175.159898 81064.840102 0.339540 0.061114 82433.333333 82600.000000 0.000000e+00 1.467732e+12 54.91464 48.628373 2021-04-26 005930 82900 83500 82600 83500 15489938 83715.0 1186.891118 86088.782236 81341.217764 0.454714 0.056711 83200.000000 82433.333333 1.288763e+12 0.000000e+00 54.91464 57.492564 2021-04-27 005930 83200 83300 82500 82900 12941533 83750.0 1149.599473 86049.198945 81450.801055 0.315153 0.054906 82900.000000 83200.000000 0.000000e+00 1.072853e+12 54.91464 48.695328 - 차트 확인plt.subplots(figsize=(10, 6)) ax1,ax2= plt.gca(),plt.gca().twinx() plt.subplot(2,1,1) plt.plot(df['close'].iloc[:SIZE_], label = 'close') plt.plot(df['m20'].iloc[:SIZE_], label= 'm20') plt.fill_between(df.iloc[:SIZE_].index, df['upper'].iloc[:SIZE_], df['lower'].iloc[:SIZE_], alpha =0.2) plt.twinx() plt.plot(df['bwith'].iloc[:SIZE_],label = 'bwith' , color = 'yellow') plt.legend() plt.grid() #====================================================== plt.subplots(figsize=(10, 6)) plt.subplot(2,1,2) plt.plot(df['%b'].iloc[:SIZE_] , label = '%b' , color = 'purple') plt.twinx() plt.plot(df['MFI10'].iloc[:SIZE_], label = 'MFI10' , color = 'pink') plt.legend() plt.grid() plt.show()
- 수정 필요사항: 반등지점 표시할 지표를 추가해야한다.- 내용 추가중입니다. -728x90'__Data Analysis > 교육' 카테고리의 다른 글
[금융경제] 유가증권 - 수익률 계산 (0) 2021.06.08 [금융경제] 파생상품 - 옵션(Option) (0) 2021.05.31 [금융경제] 파생상품 - 선물(Futures) (0) 2021.05.29 [금융경제] 실습2 - 환율 (0) 2021.05.26 [금융경제] 주가데이터 지수화(Indexing), 변동률 구하기, 주가데이터 불러오기 (0) 2021.05.18