Overall Statistics |
Total Trades 21 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 104.700% Expectancy 0 Net Profit -104.703% Sharpe Ratio -0.042 Probabilistic Sharpe Ratio 17.446% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 24.048 Annual Variance 578.32 Information Ratio -0.042 Tracking Error 24.048 Treynor Ratio 0 Total Fees $64.00 Estimated Strategy Capacity $1000.00 Lowest Capacity Asset VXXB 32577E9IRY2UE|VXXB WRBPJAJZ2Q91 Portfolio Turnover 83.57% |
# 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(2023, 1, 1) # self.SetEndDate(2023, 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.Portfolio.MarginCallModel = MarginCallModel.Null # self.side = 'none' # def OnEndOfAlgorithm(self): # for trade in self.TradeBuilder.ClosedTrades: # self.Log(self.trade_to_string(trade)) # def trade_to_string(self, trade): # return 'Symbol: {0} EntryTime: {1} EntryPrice {2} Direction: {3} Quantity: {4} ExitTime: {5} ExitPrice: {6} ProfitLoss: {7} TotalFees: {8} MAE: {9} MFE: {10} EndTradeDrawdown: {11}'.format( # trade.Symbol, # trade.EntryTime, # trade.EntryPrice, # trade.Direction, # trade.Quantity, # trade.ExitTime, # trade.ExitPrice, # trade.ProfitLoss, # trade.TotalFees, # trade.MAE, # trade.MFE, # trade.EndTradeDrawdown) 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' if self.Time.day == 31: log_profit(self) # 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 log_profit(self): for symbol in self.Portfolio.Keys: holding = self.Portfolio[symbol] self.Debug(f"{symbol}: {holding.UnrealizedProfit}") 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