STOCK/비트코인

백테스트 - 모멘텀

BOTTLE6 2022. 1. 2. 23:46
import pandas as pd
import numpy as np

df = pd.read_csv("20220102_btc_minute1_30days.csv").rename(columns = {"Unnamed: 0":'datetime'}).set_index("datetime")
df = df[['close','volume']]
df

 

○ long-short position 

import matplotlib.pyplot as plt
plt.style.use('seaborn')
import matplotlib as mpl
mpl.rcParams['savefig.dpi']=300
mpl.rcParams['font.family']='serif'

data = df.copy()
# returns : 분단위 로그 수익률
data['returns'] = np.log(data['close']/data['close'].shift(1)) # 어제종가 대비 오늘 수익률

# momentum : 분단위 수익률의 기간 이동평균 수익률이 양수면 1(매수포지션), 아니면 -1(매도포지션)
cols = []
for momentum in [5, 10, 15, 60, 120]:
    col = 'position_{}'.format(momentum)
    
    # long- short
    data[col] = np.sign(data['returns'].rolling(momentum).mean()) # 오늘 종가기준 (내일) 포지션 
    """position = 1(buy) : long"""
    """position = -1(sell) : short """
    cols.append(col)

    # only long
#     data[col] = np.where(data['returns'].rolling(momentum).mean()>0,1,0) # 오늘 종가기준 (내일) 포지션 
#     """position = 1(buy) : long"""
#     cols.append(col)


# strategy : 분단위 모멘텀 수익률
strats = ['returns'] # 변수 초기화
for col in cols: #모멘텀별 포지션 반복
    strat = 'strategy_{}'.format(col.split("_")[1])
    data[strat] = data[col].shift(1) * data['returns'] # position=1일때, 어제 종가기준 (오늘) 포지션 * 어제종가 대비 오늘 수익률
    
    strats.append(strat)
# 누적 수익률 
data[strats].dropna().cumsum().apply(np.exp).plot(figsize=(10,6));

 

▶ fee 수수료 계산이 안 되어있다.

▶ 12월 한달 데이터에서 10분 모멘텀이 가장 좋은 수익률을 보여준다. (long-short 전략) 

 

○ long 포지션만 있는 전략

import matplotlib.pyplot as plt
plt.style.use('seaborn')
import matplotlib as mpl
mpl.rcParams['savefig.dpi']=300
mpl.rcParams['font.family']='serif'

data = df.copy()
# returns : 분단위 로그 수익률
data['returns'] = np.log(data['close']/data['close'].shift(1)) # 어제종가 대비 오늘 수익률

# momentum : 분단위 수익률의 기간 이동평균 수익률이 양수면 1(매수포지션), 아니면 -1(매도포지션)
cols = []
for momentum in [5, 10, 15, 60, 120]:
    col = 'position_{}'.format(momentum)
    
    # long- short
#     data[col] = np.sign(data['returns'].rolling(momentum).mean()) # 오늘 종가기준 (내일) 포지션 
#     """position = 1(buy) : long"""
#     """position = -1(sell) : short """
#     cols.append(col)

    # only long
    data[col] = np.where(data['returns'].rolling(momentum).mean()>0,1,0) # 오늘 종가기준 (내일) 포지션 
    """position = 1(buy) : long"""
    cols.append(col)


# strategy : 분단위 모멘텀 수익률
strats = ['returns'] # 변수 초기화
for col in cols: #모멘텀별 포지션 반복
    strat = 'strategy_{}'.format(col.split("_")[1])
    data[strat] = data[col].shift(1) * data['returns'] # position=1일때, 어제 종가기준 (오늘) 포지션 * 어제종가 대비 오늘 수익률
    
    strats.append(strat)
# 누적 수익률 
data[strats].dropna().cumsum().apply(np.exp).plot(figsize=(10,6));

▶ long-short에 비해 수익률이 많이 떨어지며 역시나 10분이 가장 좋다.

 

○ 참고. 분봉 데이터

temp = data.copy()
ii = ['close','returns','position_10','strategy_10']
temp = temp[ii]
temp['position_10_shift_1'] = temp['position_10'].shift(1)
temp[:50]

 

(참고) 파이썬을 활용한 알고리즘 트레이딩 8장 

 

 


■ 해야할 일

- 파이알고 백테스트 알고리즘 분석하여 분단위 데이터로 해보기

- 업비트는 매수호가/매도호가가 실시간 데이터밖에 조회할 수 없음

    > 누적데이터를 쌓아야 하는데 sql을 써야할까? 

 

- 업비트 웹소켓 데이터 활용

    > pyalgo의 실시간 호가 데이터 처리