Overall Statistics
Total Trades
109
Average Win
15.76%
Average Loss
-8.03%
Compounding Annual Return
93.075%
Drawdown
69.600%
Expectancy
0.756
Net Profit
272.780%
Sharpe Ratio
1.868
Probabilistic Sharpe Ratio
25.694%
Loss Rate
41%
Win Rate
59%
Profit-Loss Ratio
1.96
Alpha
3.934
Beta
0.196
Annual Standard Deviation
2.112
Annual Variance
4.46
Information Ratio
1.84
Tracking Error
2.114
Treynor Ratio
20.11
Total Fees
$2183.55
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
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data.Custom.CBOE import *
from QuantConnect.Python import PythonQuandl # quandl data not CLOSE
from QuantConnect.Data import SubscriptionDataSource
from QuantConnect.Python import PythonData
import pandas as pd
from my_custom_data import *  # QuandlFuture, CboeVix, CboeVxV
from QuantConnect.Python import PythonData # custom data

from datetime import date, timedelta, datetime
from decimal import Decimal
import numpy as np
from math import floor
import json

class QuandlFutures(PythonQuandl):
        def __init__(self):
            self.ValueColumnName = "open"

class VentralTachyonAtmosphericScrubbers(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017, 1, 1)  # Set Start Date
        #self.SetStartDate(2018, 3, 20)
        self.SetEndDate(2019, 1, 1)
        self.SetCash(100000)  # Set Strategy Cash
        
        self.perc_qnty = 1
        self.selectedResolution = Resolution.Daily
        
        self.uvxy = self.AddEquity("UVXY", self.selectedResolution).Symbol
        self.svxy = self.AddEquity("SVXY", self.selectedResolution).Symbol
        
        self.spy = self.AddEquity("SPY", self.selectedResolution).Symbol
        self.tqqq = self.AddEquity("TQQQ", self.selectedResolution).Symbol
        self.spySma = self.SMA(self.spy, 25, self.selectedResolution, Field.Open)
        
        self.vixStr = "VIX"
        self.vxvStr = "VXV"
        self.vixsmStr = "VIX9D"
        self.AddData(CboeVix, "VIX")
        self.AddData(CboeVxv, "VXV")
        self.AddData(CboeVixsm, "VIX9D")
        
        self.macd = self.MACD("SPY", 12, 26, 6, MovingAverageType.Exponential, self.selectedResolution, Field.Open)
        
        self.yvixRatio = 0
        self.yvixCrossUp = False
        self.yspy = 0
        self.yspySma = 0

    def OnData(self, data):
        if self.vixStr not in data or self.vxvStr not in data: return
        
        vixPrice = data[self.vixStr].Open
        vxvPrice = data[self.vxvStr].Open
        vixsmPrice = None
        if self.vixsmStr in data:
            vixsmPrice = data[self.vixsmStr].Open
        
        uvxy_qnty = self.Portfolio[self.uvxy].Quantity
        svxy_qnty = self.Portfolio[self.svxy].Quantity
        tqqq_qnty = self.Portfolio[self.tqqq].Quantity
        
        vixRatio = vixPrice/vxvPrice
        #self.Plot("Vix/Vix3M", "Vix/Vix3M", vixRatio)
        #self.Plot("SVXY", "SVXY", self.Securities["SVXY"].Price)
        #self.Plot("SPY", "SPY", self.Securities["SPY"].Open)
        #self.Plot("MACD", "Source", self.macd.Current.Value)
        #self.Plot("MACD", "Signal", self.macd.Signal.Current.Value)
        
        vixCrossUp = False
        if vixsmPrice:
            vixCrossUp = vixsmPrice > vixPrice
            
        macdLong = self.macd.Current.Value < self.macd.Signal.Current.Value
        
        inLong = uvxy_qnty != 0
        inShort = svxy_qnty != 0
        inRest = tqqq_qnty != 0 
        
        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.yvixRatio = vixRatio
        self.yvixCrossUp = vixCrossUp
        self.yspy = self.Securities["SPY"].Open
        self.yspySma = self.spySma.Current.Value