| Overall Statistics |
|
Total Trades 18 Average Win 0% Average Loss -0.15% Compounding Annual Return -2.381% Drawdown 2.000% Expectancy -1 Net Profit -1.064% Sharpe Ratio -1.25 Probabilistic Sharpe Ratio 6.511% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.036 Beta 0.041 Annual Standard Deviation 0.018 Annual Variance 0 Information Ratio -2.698 Tracking Error 0.131 Treynor Ratio -0.549 Total Fees $5.50 Estimated Strategy Capacity $35000000.00 Lowest Capacity Asset TSLA XONZHCXLNOTI|TSLA UNU3P8Y3WFAD |
from QuantConnect.Securities.Option import OptionPriceModels
from datetime import timedelta
import math
class Wheelinginthemoney(QCAlgorithm):
def sort(self,option_contract):
#This function is to be used as the key from a sorted() function, it it used to take a list of options contracts and to create a key
#first split the Intrinsic and extrinsic value
option_cost = option_contract.AskPrice
return float(option_cost)
def get_option_contract_for_option_holding(self, symbol):
#this funtion takes an option holding as the input and returns an option contract so it can be used for analysis and rolling
for chain in self.CurrentSlice.OptionChains.Values:
for opt in chain:
if opt.Symbol == symbol:
return opt
def AddStocks(self,ticker):
equity = self.AddEquity(ticker, self.resolution) #Adding
self.Securities[ticker].SetDataNormalizationMode(DataNormalizationMode.Raw)
#option = self.AddOption(ticker, self.resolution) #Adding Options Chain
#option.SetFilter(-0, +10, timedelta(382), timedelta(730))
#option.PriceModel = OptionPriceModels.CrankNicolsonFD() #Setting the option pricing models to calculate the Greeks
return
def Initialize(self):
self.SetStartDate(2021, 1, 1)
self.SetEndDate(2021, 6,11)
self.SetCash(1000000)
self.resolution = Resolution.Minute
self.stocks = ["TSLA","VTI","VOO","BRK.B","IVV"]
self.sell_options = True
self.sell_down_mode = False
self.trade = True
self.SetBrokerageModel(BrokerageName.AlphaStreams)
for ticker in self.stocks:
self.AddStocks(ticker)
#assigns the first stock to a variable so it can be used in the date time scheduler
self.symbol = self.stocks[0]
self.SetWarmUp(7)
def OnData(self,slice):
if self.sell_options == False or self.IsWarmingUp or self.IsMarketOpen(self.symbol) == False: return
#in case there are open orders still, we want to cancel them
allCancelledOrders = self.Transactions.CancelOpenOrders()
option_invested = []
for x in self.ActiveSecurities:
if x.Value.Invested and x.Value.Type == SecurityType.Option:
option_invested.append(str(x.Value.Symbol.Underlying))
if len(option_invested) == len(self.stocks):break
option_invested_nodupes = list(dict.fromkeys(option_invested))
#checks if we have options invested in all of the stocks in our self.stocks list, if so then we set self.sell_options to False to not check anything until the next scheduled increment, else buy options.
#this is mainly for backtest performance
if len(option_invested_nodupes) == len(self.stocks):
self.sell_options = False
return
for x in self.stocks:
if x not in option_invested_nodupes and self.sell_down_mode == False:
self.buy_call(slice,x)
def buy_call(self,slice,underlying):
symbol = Symbol.Create(underlying, SecurityType.Equity, Market.USA)
calloption_symbol = self.GetOption(slice,symbol,OptionRight.Call,self.Portfolio[underlying].Price,self.Portfolio[underlying].Price + 100,self.Time + timedelta(40),self.Time + timedelta(100),self.sort,False)
if calloption_symbol is None: return
calloption = self.Securities[calloption_symbol.Symbol]
if calloption is None: return
if len(self.stocks) == 0 or calloption.AskPrice == 0 or self.Portfolio.TotalPortfolioValue == 0 : return
numberofcontracts = 1
if numberofcontracts == 0:
self.Debug("Not Enough funds to purchase " + str(underlying))
return
# Sell Put
self.Log('Buying Call ' + str(calloption))
#self.Debug(str(self.Securities[symbol].AskPrice))
self.MarketOrder(calloption.Symbol, numberofcontracts)
def OnOrderEvent(self, orderEvent):
self.trade
if orderEvent.Status != "Canceled" :
self.Debug(orderEvent)
def GetOption(self,slice,underlying,optionright,MinStrike,MaxStrike,MinExpiry,MaxExpiry,sortedfunction,reverse):
contracts = self.OptionChainProvider.GetOptionContractList(underlying, self.Time) ## Get list of Options Contracts for a specific time
if len(contracts) == 0: return
filtered_options = [x for x in contracts if x.ID.OptionRight == optionright and\
x.ID.StrikePrice > MinStrike and\
x.ID.StrikePrice < MaxStrike and\
x.ID.Date > MinExpiry and\
x.ID.Date < MaxExpiry]
if len(filtered_options) == 0: return
added_contracts = []
for x in filtered_options:
option = self.AddOptionContract(x, Resolution.Minute)
optionsymbol = self.Securities[option.Symbol]
added_contracts.append(optionsymbol)
sorted_options = sorted(added_contracts,key = sortedfunction, reverse = reverse)
selected = sorted_options[0]
for x in sorted_options:
if x != selected:
self.RemoveSecurity(x.Symbol)
return selected