Overall Statistics
Total Trades
175
Average Win
16.73%
Average Loss
-8.25%
Compounding Annual Return
-3.570%
Drawdown
75.000%
Expectancy
0.172
Net Profit
-30.492%
Sharpe Ratio
0.139
Probabilistic Sharpe Ratio
0.050%
Loss Rate
61%
Win Rate
39%
Profit-Loss Ratio
2.03
Alpha
0.028
Beta
0.268
Annual Standard Deviation
0.393
Annual Variance
0.154
Information Ratio
-0.107
Tracking Error
0.405
Treynor Ratio
0.204
Total Fees
$269.23
Estimated Strategy Capacity
$5000000.00
Lowest Capacity Asset
VX Y59NU0I6SFS9
#region imports
from AlgorithmImports import *
#endregion
class VixCalendarSpread(QCAlgorithm):
    
    def Initialize(self):

        self.cap = 40000
        self.leverage = 1.
        self.SetStartDate(2012, 12, 13)  # Set Start Date
        self.SetCash(self.cap)
        
        self.vix = self.AddFuture(
            ticker=Futures.Indices.VIX,
            resolution=Resolution.Minute,
            dataMappingMode=DataMappingMode.LastTradingDay,
            dataNormalizationMode=DataNormalizationMode.Raw,
            contractDepthOffset=0,
            fillDataForward=True
        )

        self.vix.SetFilter(0, 90)

        self.AddEquity("SPY")

        self.Schedule.On(
            self.DateRules.EveryDay("SPY"),
            self.TimeRules.AfterMarketOpen("SPY", 60),
            self.Rebalance)
        
        self.isExpired = True
        self.orderWeights = {}
        
    def OnData(self, slice) -> None:
        for changedEvent in slice.SymbolChangedEvents.Values:
            if changedEvent.Symbol == self.vix.Symbol: self.isExpired = True
        if not self.isExpired: return

        chain = slice.FuturesChains.get(self.vix.Symbol)
        if not chain: return

        contracts = [symbol for symbol, contract in chain.Contracts.items()]
        if len(contracts) < 2: return

        self.isExpired = False
        self.orderWeights = {}
        self.orderWeights[contracts[0]] = -1
        self.orderWeights[contracts[1]] = 1
    
    def Rebalance(self):
        if len(self.orderWeights) < 1: return
        for symbol, holding in self.Portfolio.items():
            self.orderWeights[symbol] = self.orderWeights.get(symbol, 0)-holding.Quantity

        for symbol, quantity in self.orderWeights.items():
            if quantity!=0:
                self.MarketOrder(symbol, quantity)
        self.orderWeights = {}