| Overall Statistics |
|
Total Trades 1484 Average Win 1.69% Average Loss -2.45% Compounding Annual Return -12.464% Drawdown 84.100% Expectancy 0.001 Net Profit -41.307% Sharpe Ratio 0.166 Probabilistic Sharpe Ratio 3.312% Loss Rate 41% Win Rate 59% Profit-Loss Ratio 0.69 Alpha 0.122 Beta -0.184 Annual Standard Deviation 0.598 Annual Variance 0.358 Information Ratio -0.04 Tracking Error 0.614 Treynor Ratio -0.542 Total Fees $2150.84 |
from System import *
from QuantConnect import *
from QuantConnect.Indicators import *
from QuantConnect.Data import *
from QuantConnect.Data.Market import *
from QuantConnect.Data.Custom import *
from QuantConnect.Algorithm import *
from QuantConnect.Python import PythonQuandl
from QuantConnect.Data.Custom.CBOE import *
class VentralTachyonAtmosphericScrubbers(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2016, 1, 1)
self.SetEndDate(2020, 1, 1)
self.SetCash(10000) # Set Strategy Cash
self.perc_qnty = 0.95
self.selectedResolution = Resolution.Daily
# Tradable Symbols
self.svxy = self.AddEquity("SVXY", self.selectedResolution).Symbol
self.uvxy = self.AddEquity("UVXY", self.selectedResolution).Symbol
self.tqqq = self.AddEquity("TQQQ", self.selectedResolution).Symbol
self.AddEquity("SPY", self.selectedResolution)
# Vix Data
self.vix = "VIX"
self.vxv = "CBOE/VXV"
self.vixsm = "VIX9D"
self.cboeVix = self.AddData(CBOE, self.vix, Resolution.Daily).Symbol
self.quandlvxv = self.AddData(Quandl, self.vxv, Resolution.Daily).Symbol
self.cboeVixsm = self.AddData(CBOE, self.vixsm, Resolution.Daily).Symbol
# SPY SMA Indicator
self.spySma = self.SMA("SPY", 25, self.selectedResolution, Field.Open)
# SPY MACD Indicator
self.macd = self.MACD("SPY", 12, 26, 6, MovingAverageType.Exponential, self.selectedResolution, Field.Open)
self.Schedule.On(self.DateRules.EveryDay(), \
self.TimeRules.At(0, 0), \
self.ResetVix)
# self.AddRiskManagement(TrailingStopRiskManagementModel(0.05))
# self.AddRiskManagement(MaximumUnrealizedProfitPercentPerSecurity(0.30))
self.yspy = 0
self.yspySma = 0
def OnData(self, data):
if data.ContainsKey(self.cboeVix):
self.vixData = data.Get(CBOE, self.cboeVix)
if data.ContainsKey(self.vxv):
self.vxvData = data.Get(Quandl, self.quandlvxv)
if data.ContainsKey(self.cboeVixsm):
self.vixsmData = data.Get(CBOE, self.cboeVixsm)
if not (self.spySma.IsReady and self.macd.IsReady): return
if not (self.vixData and self.vxvData and self.vixsmData): return
vixPrice = self.vixData.Close
vxvPrice = self.vxvData.Value
vixsmPrice = self.vixsmData.Close
vixRatio = vixPrice/vxvPrice
vixCrossUp = False
if vixsmPrice:
vixCrossUp = vixsmPrice > vixPrice
inShort = self.Portfolio["SVXY"].Invested
inLong = self.Portfolio["SVXY"].Invested
inRest = self.Portfolio["TQQQ"].Invested
macdLong = self.macd.Current.Value < self.macd.Signal.Current.Value
shortEntry = (vixRatio < 0.95) and not vixCrossUp and not (self.Securities["SPY"].Open <= self.spySma.Current.Value and self.yspy > self.yspySma)
shortExit = inShort and (not shortEntry)
longEntry = vixRatio > 1.05 and vixCrossUp and macdLong
longExit = inLong and (not longEntry)
if shortExit or longExit:
self.Liquidate()
if not inRest and longExit:
self.SetHoldings(self.tqqq, self.perc_qnty)
return
if (shortEntry):
if inLong:
self.Liquidate(self.uvxy)
if inRest:
self.Liquidate(self.tqqq)
if not inShort:
self.SetHoldings(self.svxy, self.perc_qnty)
if (longEntry):
if inShort:
self.Liquidate(self.svxy)
if inRest:
self.Liquidate(self.tqqq)
if not inLong:
self.SetHoldings(self.uvxy, self.perc_qnty)
self.yspy = self.Securities["SPY"].Open
self.yspySma = self.spySma.Current.Value
def ResetVix(self):
self.vixData = None
self.vxvData = None
self.vixsmData = None
# In CBOE/VIX data, there is a "vix close" column instead of "close" which is the
# default column namein LEAN Quandl custom data implementation.
# This class assigns new column name to match the the external datasource setting.
class QuandlVix(PythonQuandl):
def __init__(self):
self.ValueColumnName = "VIX Close"from QuantConnect.Python import PythonQuandl # quandl data not CLOSE
from QuantConnect.Python import PythonData # custom data
from QuantConnect.Data import SubscriptionDataSource
from datetime import datetime, timedelta
import decimal
class CboeVix(PythonData):
'''CBOE Vix Download Custom Data Class'''
def GetSource(self, config, date, isLiveMode):
url_vix = "http://www.cboe.com/publish/scheduledtask/mktdata/datahouse/vixcurrent.csv"
return SubscriptionDataSource(url_vix,
SubscriptionTransportMedium.RemoteFile)
def Reader(self, config, line, date, isLiveMode):
if not (line.strip() and line[0].isdigit()): return None
# New CboeVix object
index = CboeVix();
index.Symbol = config.Symbol
try:
# Example File Format:
# Date VIX Open VIX High VIX Low VIX Close
# 01/02/2004 17.96 18.68 17.54 18.22
#print line
data = line.split(',')
date = data[0].split('/')
index.Time = datetime(int(date[2]), int(date[0]), int(date[1]))
index.Value = decimal.Decimal(data[4])
index["Open"] = float(data[1])
index["High"] = float(data[2])
index["Low"] = float(data[3])
index["Close"] = float(data[4])
except ValueError:
# Do nothing
return None
# except KeyError, e:
# print 'I got a KeyError - reason "%s"' % str(e)
return index
class CboeVixsm(PythonData):
'''CBOE Vix Download Custom Data Class'''
def GetSource(self, config, date, isLiveMode):
url_vix = "https://www.cboe.com/publish/scheduledtask/mktdata/datahouse/vix9ddailyprices.csv"
return SubscriptionDataSource(url_vix,
SubscriptionTransportMedium.RemoteFile)
def Reader(self, config, line, date, isLiveMode):
if not (line.strip() and line[0].isdigit()): return None
# New CboeVix object
index = CboeVixsm();
index.Symbol = config.Symbol
try:
# Example File Format:
# Date VIX Open VIX High VIX Low VIX Close
# 01/02/2004 17.96 18.68 17.54 18.22
#print line
data = line.split(',')
date = data[0].split('/')
index.Time = datetime(int(date[2]), int(date[0]), int(date[1]))
index.Value = decimal.Decimal(data[4])
index["Open"] = float(data[1])
index["High"] = float(data[2])
index["Low"] = float(data[3])
index["Close"] = float(data[4])
except ValueError:
# Do nothing
return None
# except KeyError, e:
# print 'I got a KeyError - reason "%s"' % str(e)
return index
# NB: CboeVxV class == CboeVix class, except for the URL
class CboeVxv(PythonData):
'''CBOE VXV Download Custom Data Class'''
def GetSource(self, config, date, isLiveMode):
url_vxv = "http://www.cboe.com/publish/scheduledtask/mktdata/datahouse/vix3mdailyprices.csv"
return SubscriptionDataSource(url_vxv,
SubscriptionTransportMedium.RemoteFile)
def Reader(self, config, line, date, isLiveMode):
if not (line.strip() and line[0].isdigit()): return None
index = CboeVxv();
index.Symbol = config.Symbol
try:
# Example File Format:
# OPEN HIGH LOW CLOSE
# 12/04/2007 24.8 25.01 24.15 24.65
data = line.split(',')
date = data[0].split('/')
index.Time = datetime(int(date[2]), int(date[0]), int(date[1]))
index.Value = decimal.Decimal(data[4])
index["Open"] = float(data[1])
index["High"] = float(data[2])
index["Low"] = float(data[3])
index["Close"] = float(data[4])
except ValueError:
# Do nothing
return None
return index