Overall Statistics |
Total Trades 436 Average Win 8.59% Average Loss -6.32% Compounding Annual Return 0% Drawdown 100.500% Expectancy -0.128 Net Profit -100.793% Sharpe Ratio -0.362 Probabilistic Sharpe Ratio 0.093% Loss Rate 63% Win Rate 37% Profit-Loss Ratio 1.36 Alpha 0 Beta 0 Annual Standard Deviation 2.346 Annual Variance 5.505 Information Ratio -0.362 Tracking Error 2.346 Treynor Ratio 0 Total Fees $1132.50 Estimated Strategy Capacity $31000.00 Lowest Capacity Asset VXXB 31XQECQPCLGIU|VXXB WRBPJAJZ2Q91 Portfolio Turnover 12.54% |
# region imports from AlgorithmImports import * from datetime import timedelta # endregion class Vxx(QCAlgorithm): def Initialize(self): # # Series A expired on 30 January 2019 # self.SetStartDate(2010, 1, 1) # Set Start Date # self.SetEndDate(2019, 1, 1) # Set End Date # self.vxx = self.AddEquity("VXX.1", Resolution.Daily) # # new VXX self.SetStartDate(2021, 1, 1) # self.SetEndDate(2022, 2, 1) self.vxx = self.AddEquity("VXX", Resolution.Daily) self.option = self.AddOption(self.vxx.Symbol, Resolution.Daily) # self.option.SetFilter(lambda option_filter_universe: option_filter_universe.Strikes(-1, 1).Expiration(1, 90)) self.option.SetFilter(-1, 1, timedelta(days=15), timedelta(days=45)) self.SetCash(100000) # Set Strategy Cash # subscribe to VXX ETF, VIX and VIX3M date on daily resolution self.vix = self.AddData(CBOE, "VIX", Resolution.Daily) self.vix3m = self.AddData(CBOE, "VIX3M", Resolution.Daily) # set ib brokerage model self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.Schedule.On(self.DateRules.MonthEnd(), self.TimeRules.At(0, 0), self.log_profit) # self.Schedule.On(self.DateRules.MonthStart(), self.TimeRules.At(0, 0), self.log_profit()) def log_profit(self): try: if self.Portfolio.Invested: for symbol, holding in self.Portfolio.items(): if holding.Invested: self.Debug(f"{symbol}: {holding.UnrealizedProfit}") except: self.Debug("Error logging profit") # self.side = 'none' def OnData(self, data: Slice): # self.Log("VXX: " + str(self.vxx.Close) + " VIX: " + str(self.vix.Close) + " VIX3M: " + str(self.vix3m.Close)) self.side = 'none' # we don't ever want to own shares after assignment if self.Portfolio[self.vxx.Symbol].Quantity != 0: self.SetHoldings(self.vxx.Symbol, 0) self.Log('owned VXX shares, liquidating') self.side = 'none' # some funny business with automatic execution due to dividends if not self.Portfolio.Invested: self.side = 'none' # if we have value of > 10k in options, do nothing if self.Portfolio.TotalMarginUsed > 10000: return if self.vix.Close > self.vix3m.Close and self.side != 'long': self.Log('entered call block') self.Debug("Long VXX") option = buy_option(self, 'call', data, self.option) if not option: return # buy $1000 of the call qty = 1000 // (option.AskPrice * 100) if option.AskPrice != 0 else 1 self.Log("Buy call: " + str(option.Symbol) + "qty: " + str(qty) + " calls at: " + str(option.AskPrice) + 'VXX spot: ' + str(self.vxx.Close) + 'strike is: ' + (str(option.Strike) if hasattr(option, 'Strike') else '') + 'expiry is: ' + str(option.Expiry)) most_recent_call = self.MarketOrder(option.Symbol, qty) self.side = 'long' # log_profit(self) return if self.vix.Close < self.vix3m.Close and self.side != 'short': self.Log('entered put block') self.Debug("Short VXX") option = buy_option(self, 'put', data, self.option) if not option: return # buy $1000 of the put qty = 1000 // (option.AskPrice * 100) if option.AskPrice != 0 else 1 self.Log("Buy put: " + str(option.Symbol) + "qty: " + str(qty) + " puts at: " + str(option.AskPrice) + 'VXX spot: ' + str(self.vxx.Close) + 'strike is: ' + (str(option.Strike) if hasattr(option, 'Strike') else '') + 'expiry is: ' + str(option.Expiry)) most_recent_put = self.MarketOrder(option.Symbol, qty) self.side = 'short' # log_profit(self) return pass def buy_option(self, option_type: str, data: Slice, option: Option): chain = data.OptionChains.get(option.Symbol) if not chain: # log no chain at this time self.Log('No option chain for ' + str(option.Symbol) + ' at ' + str(self.Time)) return None side = OptionRight.Call if option_type == 'call' else OptionRight.Put if option_type == 'put' else None contracts = [c for c in chain if c.Right == side] try: expiry = max([c.Expiry for c in contracts]) if option_type == 'put' else min([c.Expiry for c in contracts]) except: return None contracts = sorted([c for c in contracts if c.Expiry == expiry], key=lambda c: c.Strike, reverse=False) option = contracts[0] return option ############################## # # region imports # from AlgorithmImports import * # # endregion # class Vxx(QCAlgorithm): # def Initialize(self): # # Series A expired on 30 January 2019 # # self.SetStartDate(2010, 1, 1) # Set Start Date # # self.SetEndDate(2019, 1, 30) # Set End Date # # self.vxx = self.AddEquity("VXX.1", Resolution.Daily) # # new VXX # self.SetStartDate(2019, 1, 31) # # self.vxx = self.AddEquity("VXX", Resolution.Daily) # self.SetCash(100000) # Set Strategy Cash # # subscribe to VXX ETF, VIX and VIX3M date on daily resolution # self.vix = self.AddData(CBOE, "VIX", Resolution.Daily) # self.vix3m = self.AddData(CBOE, "VIX3M", Resolution.Daily) # # set ib brokerage model # self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) # def OnData(self, data: Slice): # self.Log("VXX: " + str(self.vxx.Close) + " VIX: " + str(self.vix.Close) + " VIX3M: " + str(self.vix3m.Close)) # if not self.Portfolio.Invested: # if self.vix.Close < self.vix3m.Close: # self.SetHoldings(self.vxx.Symbol, -0.1) # self.Log("Short VXX") # else: # self.SetHoldings(self.vxx.Symbol, 0.1) # self.Log("Long VXX") # return # #if vix < vix3m, short vxx ... Contango # if (self.Portfolio['VXX'].Quantity > 0) and self.vix.Close < self.vix3m.Close : # self.Liquidate() # self.SetHoldings(self.vxx.Symbol, -0.1) # self.Log("Short VXX") # return # #if vix > vix3m, long vxx ... Backwardation # if (self.Portfolio['VXX'].Quantity < 0) and self.vix.Close > self.vix3m.Close : # self.Liquidate() # self.SetHoldings(self.vxx.Symbol, 0.1) # self.Debug("Long VXX") # return # pass
# region imports from AlgorithmImports import * # endregion class Vxx(QCAlgorithm): def Initialize(self): # Series A expired on 30 January 2019 self.SetStartDate(2010, 1, 1) # Set Start Date self.SetEndDate(2019, 1, 30) # Set End Date self.vxx = self.AddEquity("VXX.1", Resolution.Daily) # new VXX # self.SetStartDate(2019, 1, 31) # # self.vxx = self.AddEquity("VXX", Resolution.Daily) self.SetCash(100000) # Set Strategy Cash # subscribe to VXX ETF, VIX and VIX3M date on daily resolution self.vix = self.AddData(CBOE, "VIX", Resolution.Daily) self.vix3m = self.AddData(CBOE, "VIX3M", Resolution.Daily) # set ib brokerage model self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) def OnData(self, data: Slice): self.Log("VXX: " + str(self.vxx.Close) + " VIX: " + str(self.vix.Close) + " VIX3M: " + str(self.vix3m.Close)) chain = data.OptionChains.get(self.optionSymbol) if not chain: return if not self.Portfolio.Invested: if self.vix.Close < self.vix3m.Close: self.SetHoldings(self.vxx.Symbol, -0.1) self.Log("Short VXX") else: self.SetHoldings(self.vxx.Symbol, 0.1) self.Log("Long VXX") return #if vix < vix3m, short vxx ... Contango if (self.Portfolio['VXX'].Quantity > 0) and self.vix.Close < self.vix3m.Close : self.Liquidate() self.SetHoldings(self.vxx.Symbol, -0.1) self.Log("Short VXX") return #if vix > vix3m, long vxx ... Backwardation if (self.Portfolio['VXX'].Quantity < 0) and self.vix.Close > self.vix3m.Close : self.Liquidate() self.SetHoldings(self.vxx.Symbol, 0.1) self.Debug("Long VXX") return pass