| 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