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