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의 실시간 호가 데이터 처리