bolllinger band

jh_k·2023년 2월 5일
0

투자전략

목록 보기
2/7

볼린저 밴드

  1. 파일 로드
  2. 결측치와 이상치를 확인 및 제거
  3. 시간과 종가만의 데이터프레임으로 변경
  4. 이동 평균선 : 데이터 20개의 평균을 구해서 새로운 파생변수에 대입
  5. 상단 밴드 : 이동 평균선 + (2 * 데이터 20개의 표준편차)
  6. 하단 밴드 : 이동 평균선 - (2 * 데이터 20개의 표준편차)
  7. 구매 상태를 확인하는 파생변수 생성
  8. 구매 상태를 입력
  9. 수익율 계산
import pandas as pd
import numpy as np

df = pd.read_csv("../csv/BND.csv", index_col='Date')
df.head()
## 결측치와 이상치를 확인
df[df.isin([np.nan, np.inf, -np.inf]).any(1)]

## 시간과 종가만으로 이루어져있는 데이터프레임 생성

# price_df = df.loc[ : , ["Adj Close"]]

price_df = df[["Adj Close"]]
## 이동 평균선
# 데이터양이 20개의 평균을 구해서 새로운 파생변수 대입
# 과거의 데이터의 수가 20개가 되지 않으면 결측치로 출력

price_df["center"] = price_df['Adj Close'].rolling(20).mean()
## ub 파생변수를 생성 
## 이동평균선 + (2 * 종가 데이터 20개의 표준편차)
price_df["ub"] = \
    price_df["center"] + ( 2 * price_df["Adj Close"].rolling(20).std() )
## lb 파생변수 생성
# 이동평균선 - ( 2 * 종가 데이터 20개의 표준편차 )
price_df["lb"] = \
    price_df['center'] - ( 2 * price_df['Adj Close'].rolling(20).std() )
## 시작 시간 생성 
start_time = '2010-01-02'

## 거래 내역이라는 파생변수 생성
## 비어있는 값을 생성
price_df_2['trade'] = ""

구매내역 추가

  • 조건
    1. 상단 밴드보다 종가가 높은 경우
      • 현재 구매 상태인 경우
        • 매도 trade = ""
      • 현재 구매 상태가 아닌 경우
        • 아무 행동도 하지 않는다. trade = ""
    2. 하단 밴드보다 종가가 낮은 경우
      • 현재 구매 상태인 경우
        • 구매 상태를 유지 trade = "buy"
      • 현재 구매 상태가 아닌 경우
        • 구매 trade = "buy"
    3. 하단 밴드와 상단 밴드 사이에 종가가 존재하면
      • 현재 구매 상태인 경우
        • 구매 상태를 유지 trade = "buy"
      • 현재 구매 상태가 아닌 경우
        • 현 상태를 유지 trade = ""
for i in price_df_2.index:
    if price_df_2.loc[i, 'Adj Close'] > price_df_2.loc[i, 'ub']:
        if price_df_2.shift(1).loc[i, 'trade'] == "buy":
            price_df_2.loc[i, 'trade'] = ""
        else : 
            price_df_2.loc[i, 'trade'] = ""
    elif price_df_2.loc[i, 'Adj Close'] < price_df_2.loc[i, 'lb']:
        if price_df_2.shift(1).loc[i, 'trade'] == "buy":
            price_df_2.loc[i, 'trade'] = 'buy'
        else : 
            price_df_2.loc[i, 'trade'] = 'buy'
    elif price_df_2.loc[i, 'Adj Close'] >= price_df_2.loc[i, 'lb'] and price_df_2.loc[i, 'Adj Close'] <= price_df_2.loc[i, 'ub']:
        if price_df_2.shift(1).loc[i, 'trade'] == 'buy':
            price_df_2.loc[i, 'trade'] = 'buy'
        else:
            price_df_2.loc[i, 'trade'] = ""
price_df_2['trade'].value_counts()
# price_df_2[price_df_2.isin(["buy"]).any(1)]
# price_df_2.query("trade == 'buy'")
# 구매한 시점의 종가
price_df_2[price_df_2['trade'] == 'buy']

수익율 계산

  • 구매를 한 날의 종가
    • trade 컬럼에서 전 행의 trade가 "" 현재 행 trade가 "buy"인 날의 종가 = 구매 가격
  • 판매를 한 날의 종가
    • 전 행의 trade가 "buy"이고 현재 행 trade가 "" 인 날의 종가 = 판매 가격
  • 수익율 계산
    • (판매 가격 - 구매 가격) / 구매 가격 + 1
  • 구매 가격과 판매 가격를 초기화
  • 여러개의 수익율 발생
  • 누적 수익율
    • 수익율 누적으로 곱
# 손익 계산
rtn = 1.0
price_df_2["return"] = 1
buy = 0.0
sell = 0.0
for i in price_df_2.index:
    ## 구매가를 출력
    if price_df_2.shift(1).loc[i, "trade"] == '' and \
        price_df_2.loc[i, 'trade'] == 'buy':
        buy = price_df_2.loc[i, 'Adj Close']
        print('진입일 :', i, "구매 가격 :", buy)
    ## 판매가를 출력
    elif price_df_2.shift(1).loc[i, 'trade'] == 'buy' and \
        price_df_2.loc[i, 'trade'] == '':
        sell = price_df_2.loc[i, 'Adj Close']
        rtn = (sell - buy) / buy + 1
        price_df_2.loc[i, 'return'] = rtn
        print('청산일 :', i, "판매 가격 :", sell, "수익율 :", round(rtn, 4))
    
    ## buy, sell 변수를 초기화
    if price_df_2.loc[i, 'trade'] == "":
        buy = 0.0
        sell = 0.0
    
    


## for문을 이용하여 구매 가격 print, 판매 가격 print()
# 구매인 경우 조건 : 전 행의 trade가 "" 이고(그리고) 현재 행의 trade가 "buy"
# 판매인 경우 조건 : 전 행의 trade가 "buy" 이고(그리고) 현재 행의 trade가 ""
# 이 두 경우에 종가를 print()
##누적 수익율

acc_rtn = 1.0

for i in price_df_2.index:
    rtn = price_df_2.loc[i, 'return']
    acc_rtn *= rtn
    price_df_2['acc_rtn'] = acc_rtn

print("누적 수익율 : ", round(acc_rtn, 4))
profile
Just Enjoy Yourself

0개의 댓글