본문 바로가기
코딩 공부/python

볼린저 밴드와 현금흐름 지표를 이용해 매수, 매도 타이밍 구하기

by Camel_coding_food 2022. 3. 2.
반응형

이번에는 마리아디비에 저장한 시세 데이터로 매수, 매도 타이밍을 구해보겠습니다.

 

전략은 볼린저 밴드, 현금흐름지표를 이용하겠습니다.

 

볼린저밴드의 %B는 가격의 볼린저밴드 속 가격의 상대적 위치를 나타냅니다.

선택한 지표는 간단히 설명하겠습니다.

 

import matplotlib.pyplot as plt
import MarketDB2

mk = MarketDB2.MarketDB()
df = mk.getDailyPrice('000020', '2019-10-14', '2022-02-25')
  
df['MA20'] = df['close'].rolling(window=20).mean()
# rolling 과 window 를 이용하여 몇개의 데이터로 평균을 낼지 정한다.
df['stddev'] = df['close'].rolling(window=20).std()
# std로 표준편차를 구한 후 칼럼에 추가한다.
df['upper'] = df['MA20'] + (df['stddev'] * 2)
# 상단 볼린저밴드 
df['lower'] = df['MA20'] - (df['stddev'] * 2)
# 하단 볼린저밴드
df['PB'] = (df['close'] - df['lower']) / (df['upper'] - df['lower'])
df['TP'] = (df['high']+df['low']+df['close'])/3
df['PMF']=0
df['NMF']=0
# PMF는 긍정적인 현금흐름, NMF는 부정적인 현금흐름
for i in range(len(df.close)-1):
    if df.TP.values[i] < df.TP.values[i+1]:
        df.PMF.values[i+1] = df.TP.values[i+1] * df.volume.values[i+1]
        df.NMF.values[i+1] = 0
    else:
        df.NMF.values[i+1] = df.TP.values[i+1] * df.volume.values[i+1]
        df.PMF.values[i+1] = 0
df['MFR'] =df.PMF.rolling(window=10).sum() / df.NMF.rolling(window=10).sum()
df['MFI10'] =100-100/(1+df['MFR'])
# df = df[:19] df의 값이 20열부터 값이 존재하므로 이 코드를 써줘야한다는데 저는 빼도 문제가 없더군요.

plt.figure(figsize=(9, 8))
plt.subplot(2, 1, 1)
plt.title('NAVER Bollinger Band(20 day, 2 std) - Trend Following')
plt.plot(df.index, df['close'], color='#0000ff', label='Close') #종가를 그래프상 파란색 실선으로 표시한다.
plt.plot(df.index, df['upper'], 'r--', label ='Upper band')     #상단 볼린저밴드를 검은색 실선으로 지정
plt.plot(df.index, df['MA20'], 'k--', label='Moving average 20')#20일 이평선을 검은색 실선으로 지정
plt.plot(df.index, df['lower'], 'c--', label ='Lower band')     #하단 볼린저 밴드 하늘색 점선 지정
plt.fill_between(df.index, df['upper'], df['lower'], color='0.9')   #상단, 하단 볼린저 밴드 사이를 회색으로 채운다.
for i in range(len(df.close)):  #종가의 개수만큼 반복한다.
    if df.PB.values[i] > 0.8 and df.MFI10.values[i] > 80:       #MFI10(10일 현금흐름지표)가 80초과이고 %b(볼린저밴드에서 가격의 위치)가 0.8 초과일때
        plt.plot(df.index.values[i], df.close.values[i], 'r^')  #빨간색 삼각형으로 표시한다(매수타이밍).
    elif df.PB.values[i] < 0.2 and df.MFI10.values[i] < 20:     #MFI10(10일 현금흐름지표)가 20미만이고 %b(볼린저밴드에서 가격의 위치)가 0.8 미만일때
        plt.plot(df.index.values[i], df.close.values[i], 'bv')  #파란색 역삼각형을 표시한다.
plt.legend(loc='best')

plt.subplot(2, 1, 2)        #한 창에 두개의 그래프를 그린다.
plt.plot(df.index, df['PB'] * 100, 'b', label='%B x 100')   #%b가 1 이하의 소수점으로 표시되므로 100을 곱하여 파란색 선으로 그래프에 그린다.
plt.plot(df.index, df['MFI10'], 'g--', label='MFI(10 day)') #MFI를 녹색으로 그린다.
plt.yticks([-20, 0, 20, 40, 60, 80, 100, 120])      #y축을 20단위로 -20~120까지 그래프에 나타낸다.
for i in range(len(df.close)):  
    if df.PB.values[i] > 0.8 and df.MFI10.values[i] > 80:
        plt.plot(df.index.values[i], 0, 'r^')
    elif df.PB.values[i] < 0.2 and df.MFI10.values[i] < 20:
        plt.plot(df.index.values[i], 0, 'bv')
plt.grid(True)
plt.legend(loc='best')
plt.show();

 

각 코드별 설명은 코드 밑에 달았습니다.

 

 

결과 그래프는 이렇게 나옵니다.

 

반응형

댓글