| Overall Statistics |
|
Total Trades 129 Average Win 6.17% Average Loss -3.60% Compounding Annual Return 88.026% Drawdown 39.800% Expectancy 0.357 Net Profit 274.090% Sharpe Ratio 1.249 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.71 Alpha 0.535 Beta 3.183 Annual Standard Deviation 0.702 Annual Variance 0.493 Information Ratio 1.214 Tracking Error 0.634 Treynor Ratio 0.275 Total Fees $2949.24 |
#
# QuantConnect Basic Template:
# Fundamentals to using a QuantConnect algorithm.
#
# You can view the QCAlgorithm base class on Github:
# https://github.com/QuantConnect/Lean/tree/master/Algorithm
#
import numpy as np
import pandas as pd
from arch import arch_model
from datetime import datetime
from math import log10
class SPYVolStrategy(QCAlgorithm):
def Initialize(self):
#import S&P500 tracker ETF and VIX futures ETN
self.vxx = self.AddEquity("VXX", Resolution.Minute)
self.spy = self.AddEquity("SPY", Resolution.Minute)
self.vxxsyl = self.vxx.Symbol
self.spysyl = self.spy.Symbol
# Set the cash we'd like to use for our backtest
# This is ignored in live trading
self.SetCash(100000)
self.SetStartDate(2015,8,01) #2013,01,30
self.SetEndDate(2017,9,01) #2015,7,31
#schedule trading function every day 15 minutes before market close
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.BeforeMarketClose('SPY', 15), Action(self.trade_fn))
def trade_fn(self):
spy_hist = self.History('SPY', 2520, Resolution.Daily)
self.close = []
#create list of close prices, add current price (10 mins before market close)
for slice in spy_hist:
self.close.append(slice.Close)
del spy_hist
#add current price to close prices (treat this as todays tradeable close price)
self.close.append(self.Securities['SPY'].Price)
#get log returns
log_prices = map(log10, self.close)
del self.close
returns = np.diff(log_prices)
del log_prices
#parameters
self.p_val = 1
self.q_val = 2
#fit
am = arch_model(returns, vol='Garch', p=self.p_val, q=self.q_val)
res = am.fit()
fcast = res.forecast(horizon=1).variance.loc[:,'h.1']
predicted_return_delta = fcast.values[-1] - returns[-1]**2
todays_return_delta = returns[-1]**2 - returns[-2]**2
holdings = self.Portfolio['VXX'].Quantity
if predicted_return_delta == todays_return_delta:
self.Liquidate('VXX')
if predicted_return_delta > todays_return_delta:
if holdings >= 0:
self.SetHoldings('VXX', -1)
if predicted_return_delta < todays_return_delta:
if holdings <= 0:
self.SetHoldings('VXX', 1)
def OnData(self, slice):
pass