Overall Statistics
Total Trades
16
Average Win
4.18%
Average Loss
-4.47%
Compounding Annual Return
-1.456%
Drawdown
29.500%
Expectancy
-0.032
Net Profit
-2.895%
Sharpe Ratio
0.029
Probabilistic Sharpe Ratio
5.740%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.94
Alpha
0.023
Beta
-0.227
Annual Standard Deviation
0.177
Annual Variance
0.031
Information Ratio
-0.264
Tracking Error
0.279
Treynor Ratio
-0.023
Total Fees
$16.00
Estimated Strategy Capacity
$1200000.00
Lowest Capacity Asset
VIXY UT076X30D0MD
# https://quantpedia.com/strategies/trading-vix-etfs-v2/
#
# Investment universe consists of SPDR S&P500 Trust ETF (SPY) and ProShares Short S&P500 ETF (SH) for long and short exposure to the
# S&P500 and iPath S&P500 VIX ST Futures ETN (VXX) and VelocityShares Daily Inverse VIX ST ETN (XIV) for long and short exposure to 
# short-term VIX futures. First, the relative difference between the front-month VIX futures and spot VIX is calculated 
# (contango/backwardation check). If the relative basis is above (below) an upper (lower) buy threshold, BU (BL) determined by the trader, 
# it indicates that the market is in contango (backwardation) and that one should hold XIV (VXX) and hedge with SH (SPY). The position is 
# closed when the relative basis falls below an upper (lower) sell-threshold, SU (SL), which may be set equal to, or lower (higher) than
# the buy-threshold. A reason why one might want the upper (lower) sell-threshold lower (higher) than the upper (lower) buy-threshold is
# to avoid too-frequent trading. The best results are with a 0% hedge ratio (trader doesn’t use SPY/SH hedging). However, it is possible
# to use multiple different hedging levels with different results (see table 10 in a source academic paper for more options).

from QuantConnect.Python import PythonQuandl

class TradingVIXETFsv2(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2010, 1, 1)
        self.SetEndDate(2012, 1, 1)
        self.SetCash(100000)

        self.vixy_data = self.AddEquity('VIXY', Resolution.Daily)
        self.vixy = self.vixy_data.Symbol
        # Vix futures data.
        self.vix_future = self.AddFuture(Futures.Indices.VIX, Resolution.Minute)

        # Vix spot.
        self.vix_spot = self.AddData(QuandlVix, 'CBOE/VIX', Resolution.Daily).Symbol
        
        # Find the front contract expiring no earlier than in 90 days.
        self.vix_future.SetFilter(timedelta(0), TimeSpan.FromDays(90))
        
        # Vix futures actiove contract updated on expiration.
        self.active_contract = None
            
    def Rebalance(self):
        if self.active_contract:
            if self.Securities.ContainsKey(self.vix_spot):
                spot_price = self.Securities[self.vix_spot].Price
                vix_future_price = self.active_contract.LastPrice
                if spot_price == 0 or vix_future_price == 0: 
                    return
                
                relative_basis = vix_future_price / spot_price
                
                if relative_basis <= 0.92:
                    if not self.Portfolio[self.vixy].Invested:
                        self.SetHoldings(self.vixy, -1)
                    return
                
                if relative_basis >= 0.94:
                    if self.Portfolio[self.vixy].Invested:
                        self.Liquidate(self.vixy)
                        return
                
                
    def OnData(self, slice):
        chains = [x for x in slice.FutureChains]

        if len(chains) > 0:
            cl_chain = chains[0]

            if cl_chain.Value.Contracts.Count >= 1:
                contracts = [i for i in cl_chain.Value]
                contracts = sorted(contracts, key = lambda x: x.Expiry)
                near_contract = contracts[0]
                
                self.active_contract = near_contract
        
        if slice.ContainsKey(self.vixy) and slice[self.vixy] is not None and not slice[self.vixy].IsFillForward:
            self.Rebalance()

class QuandlVix(PythonQuandl):
    def __init__(self):
        self.ValueColumnName = "VIX Close"