Trend tracking backtest

 

Remarks

본 포스팅은 파이썬을 활용한 금융분석(한빛미디어, 2016) 978-89-6848-277-9를 기반으로 작성되었습니다.


S&P500을 벤치마크로 하여 backtest 목적으로 과거 시장 정보를 분석하는 예제입니다.

import numpy as np
import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt
%matplotlib inline

매수

42일 추세 > 252일 추세 + SD 투자수익률이 시장 수익률을 따라간다.

대기

42일 추세 < 252일 추세 +- SD 투자수익률은 0

매도

42일 추세 < 252일 추세 - SD 투자수익률은 시장 수익률의 반대

sp500 = web.DataReader('^GSPC', 'yahoo', start='1/2/2000', end='4/14/2014')

sp500['42d'] = sp500['Close'].rolling(window=42).mean()
sp500['252d'] = sp500['Close'].rolling(window=252).mean()
sp500[['Close', '42d', '252d']].plot(grid=True, figsize=(20, 4));  plt.show();

sp500['42-252'] = sp500['42d'] - sp500['252d']
sp500[['42d', '252d', '42-252']].plot(grid=True, figsize=(20, 4));  plt.show();

SD = 50
sp500['Regime'] = np.where(sp500['42-252'] > SD, 1, 0)  # 1: 매수, 0: 대기
sp500['Regime'] = np.where(sp500['42-252'] < -SD, -1, sp500['Regime'])  # -1: 매도
sp500['Regime'].plot(grid=True, lw=1.5, figsize=(20, 2))
plt.ylim([-1.1, 1.1]);

sp500['Market'] = np.log(sp500['Close'] / sp500['Close'].shift(1))
sp500['Strategy'] = sp500['Regime'].shift(1) * sp500['Market']

sp500[['Market', 'Strategy']].cumsum().apply(np.exp).plot(grid=True, figsize=(20, 4));

png

png

png

png

sp500 = web.DataReader('^GSPC', 'yahoo', start='1/2/2000', end='4/14/2014')

sp500['42d'] = sp500['Close'].rolling(window=22).mean().shift(-11)
sp500['252d'] = sp500['Close'].rolling(window=252).mean().shift(-126)
sp500[['Close', '42d', '252d']].plot(grid=True, figsize=(20, 4));  plt.show();

sp500['42-252'] = sp500['42d'] - sp500['252d']
sp500[['42d', '252d', '42-252']].plot(grid=True, figsize=(20, 4));  plt.show();

SD = 50
sp500['Regime'] = np.where(sp500['42-252'] > SD, 1, 0)  # 1: 매수, 0: 대기
sp500['Regime'] = np.where(sp500['42-252'] < -SD, -1, sp500['Regime'])  # -1: 매도
sp500['Regime'].plot(grid=True, lw=1.5, figsize=(20, 2))
plt.ylim([-1.1, 1.1]);

sp500['Market'] = np.log(sp500['Close'] / sp500['Close'].shift(1))
sp500['Strategy'] = sp500['Regime'].shift(1) * sp500['Market']

sp500[['Market', 'Strategy']].cumsum().apply(np.exp).plot(grid=True, figsize=(20, 4));

png

png

png

png

sp500 = web.DataReader('^GSPC', 'yahoo', start='1/1/2010', end='3/10/2020')

sp500['42d'] = sp500['Close'].rolling(window=22).mean().shift(-11)
sp500['252d'] = sp500['Close'].rolling(window=252).mean().shift(-126)
sp500[['Close', '42d', '252d']].plot(grid=True, figsize=(20, 4));  plt.show();

sp500['42-252'] = sp500['42d'] - sp500['252d']
sp500[['42d', '252d', '42-252']].plot(grid=True, figsize=(20, 4));  plt.show();

SD = 50
sp500['Regime'] = np.where(sp500['42-252'] > SD, 1, 0)  # 1: 매수, 0: 대기
sp500['Regime'] = np.where(sp500['42-252'] < -SD, -1, sp500['Regime'])  # -1: 매도
sp500['Regime'].plot(grid=True, lw=1.5, figsize=(20, 2))
plt.ylim([-1.1, 1.1]);

sp500['Market'] = np.log(sp500['Close'] / sp500['Close'].shift(1))
sp500['Strategy'] = sp500['Regime'].shift(1) * sp500['Market']

sp500[['Market', 'Strategy']].cumsum().apply(np.exp).plot(grid=True, figsize=(20, 4));

png

png

png

png