Overall Statistics
Total Trades
1
Average Win
0%
Average Loss
0%
Compounding Annual Return
18.782%
Drawdown
33.400%
Expectancy
0
Net Profit
30.020%
Sharpe Ratio
0.847
Probabilistic Sharpe Ratio
38.655%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.002
Beta
0.985
Annual Standard Deviation
0.276
Annual Variance
0.076
Information Ratio
-1.209
Tracking Error
0.004
Treynor Ratio
0.237
Total Fees
$1.00
'''
ref. 
https://www.quantconnect.com/forum/discussion/2657/a-simple-vix-strategy
'''
from QuantConnect.Python import PythonQuandl # quandl data not CLOSE
from QuantConnect.Python import PythonData # custom data
from QuantConnect.Data import SubscriptionDataSource

from QuantConnect import *
from QuantConnect.Algorithm import *

import pandas as pd
import numpy as np

from datetime import datetime, timedelta
import decimal

ONEDAYSHIFT = timedelta(1) # shift date to avoid look ahead bias
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]))+ONEDAYSHIFT
            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:
            return None
        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]))+ONEDAYSHIFT
            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

# for using VIX futures settle in calc. ratios like VIX/VIX1
class QuandlFuture(PythonQuandl):
    '''Custom quandl data type for setting customized value column name. 
       Value column is used for the primary trading calculations and charting.'''
    def __init__(self):
        # Define ValueColumnName: cannot be None, Empty or non-existant column name
        # If ValueColumnName is "Close", do not use PythonQuandl, use Quandl:
        # self.AddData[QuandlFuture](self.VIX1, Resolution.Daily)
        self.ValueColumnName = "Settle"
        
class MyAlgorithm(QCAlgorithm):
    def Initialize(self):
        
        self.SetStartDate(2019, 6, 15)
        self.SetEndDate(datetime.now().date() - timedelta(1))
        self.SetCash(10000)
        self.SetBrokerageModel(BrokerageName.AlphaStreams)

        self.spy = self.AddEquity("SPY", Resolution.Minute).Symbol
        self.vix = self.AddData(CboeVix, "VIX").Symbol
        self.vxv = self.AddData(CboeVxV, "VXV").Symbol

        self.SetBenchmark("SPY")
        
        # Define the Schedules
        self.Schedule.On(
            self.DateRules.EveryDay(),
            self.TimeRules.AfterMarketOpen(self.spy,1),
            Action(self.Balance)
        )
        
        # logging is limited, add plot!
        indicatorPlot0 = Chart("len")
        self.AddChart(indicatorPlot0)
        
    def Balance(self):
        _window_len = 252*5
        self.histSPY = self.History([self.spy], _window_len, Resolution.Daily)
        self.histVIX = self.History([self.vix], _window_len, Resolution.Daily)
        self.histVXV = self.History([self.vxv], _window_len, Resolution.Daily)
        
        self.SetHoldings(self.spy,1.0)
        
        # plot signals
        self.Plot("len",'spy',len(self.histSPY))
        self.Plot("len",'vix',len(self.histVXV))
        self.Plot("len",'vxv',len(self.histVXV))