Overall Statistics |
Total Trades 127 Average Win 2.99% Average Loss -1.16% Compounding Annual Return 10.588% Drawdown 19.000% Expectancy 0.822 Net Profit 225.287% Sharpe Ratio 0.895 Probabilistic Sharpe Ratio 28.597% Loss Rate 49% Win Rate 51% Profit-Loss Ratio 2.59 Alpha 0.085 Beta 0.056 Annual Standard Deviation 0.103 Annual Variance 0.011 Information Ratio -0.229 Tracking Error 0.178 Treynor Ratio 1.654 Total Fees $287.10 Estimated Strategy Capacity $150000000.00 Lowest Capacity Asset VIXY UT076X30D0MD |
# The portfolio holds positions in the S&P 500 Index and constant maturity VIX futures. # weightings == of their risk contribution to portfolio, which is estimated by the GARCH(1,1) model lagged by one day. # Long (Short) position in VIX futuresis determined by the shape of the VIX premium. # The portfolio is rebalanced daily. # The VIX premium is used as a one-day lagged indicator for trade execution of the VIX futures # The positive (negative) value of VIX premium indicates to hold the short (long) position in # VIX futures on the next day after calculation of VIX premium. from collections import deque from QuantConnect.Python import PythonQuandl import numpy as np class VIXPremium(QCAlgorithm): def Initialize(self): self.SetStartDate(2010, 1, 1) self.SetCash(100000) self.symbols = ['VIXY', 'SPY'] # Daily price data. period = 20 self.data = {} for symbol in self.symbols: self.AddEquity(symbol, Resolution.Daily) self.data[symbol] = deque(maxlen = period) # VIX and VIX3M filter. self.vix = self.AddData(QuandlVix, 'CBOE/VIX', Resolution.Daily).Symbol self.vix3M = self.AddData(Quandl, 'CBOE/VXV', Resolution.Daily).Symbol def OnData(self, data): # Store daily price. for symbol in self.symbols: if symbol in data and data[symbol]: price = data[symbol].Value self.data[symbol].append(price) if self.vix in data and data[self.vix] and self.vix3M in data and data[self.vix3M]: # Data is ready. if len(self.data['VIXY']) == self.data['VIXY'].maxlen and len(self.data['SPY']) == self.data['SPY'].maxlen: vix = data[self.vix].Value vix3m = data[self.vix3M].Value vix_volatility = Volatility(self.data['VIXY']) market_volatility = Volatility(self.data['SPY']) total_volatility = 1/vix_volatility + 1/market_volatility w = (1.0 / vix_volatility) / total_volatility # Rebalance only on signal change. if vix3m >= vix: # Contango -> short vixy. if not self.Portfolio['VIXY'].IsShort: self.SetHoldings('VIXY', -w) else: # Backwardation -> long vixy. if not self.Portfolio['VIXY'].IsLong: self.SetHoldings('VIXY', w) class QuandlVix(PythonQuandl): def __init__(self): self.ValueColumnName = "close" def Volatility(values): values = np.array(values) returns = (values[1:] - values[:-1]) / values[:-1] return np.std(returns)