| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
from datetime import timedelta
class SmoothBlueLion(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 9, 1) # Set Start Date
self.SetEndDate(2021, 9, 1)
self.SetCash(100000) # Set Strategy Cash
# self.AddEquity("SPY", Resolution.Minute)
self.AddUniverse(self.MyCoarseFilterFunction)
self.UniverseSettings.Resolution = Resolution.Minute
self.DTE = 30
self.ExpDelta = 20 # num days to look before/after desired DTE (i.e if only monthly exp, might need to go 50 days out)
self.contractsAdded = set()
self.SetSecurityInitializer(lambda x: x.SetDataNormalizationMode(DataNormalizationMode.Raw))
self.contractsWithoutPrices = 0
self.contractsWithPrices = 0
def OnData(self, data):
if not (data.Time.hour == 10 and data.Time.minute == 0):
return
for security in self.ActiveSecurities.Values:
if security.Symbol.SecurityType == SecurityType.Equity:
contracts = self.OptionsFilter(security.Symbol)
if contracts == str(): continue
for contract in contracts:
if contract.ID.OptionRight == OptionRight.Put:
bid = self.Securities[contract].BidPrice
self.Debug("bid: " + str(bid))
else:
ask = self.Securities[contract].AskPrice
self.Debug("ask: " + str(ask))
if bid > 0 and ask > 0:
self.contractsWithPrices += 1
else:
self.contractsWithoutPrices += 1
#self.Debug(str(security.Symbol.Value))
#self.Debug("returned contracts: " + str([x.Value for x in contracts]))
self.Debug("Number of Contracts with Prices: " + str(self.contractsWithPrices))
self.Debug("Number of Contracts without Prices: " + str(self.contractsWithoutPrices))
self.contractsWithPrices = 0
self.contractsWithoutPrices = 0
def MyCoarseFilterFunction(self, coarse):
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
filtered = [ x.Symbol for x in sortedByDollarVolume
if x.Price > 5 and x.Price < 30 ][:5]
return filtered
def OnSecuritiesChanged(self, changes):
for security in changes.AddedSecurities:
if security.Symbol.SecurityType == SecurityType.Equity:
self.OptionsFilter(security.Symbol) # call OptionsFilter to subscribe to the options contracts data
self.Debug(str(security.Symbol) + " is an equity")
def OptionsFilter(self, symbol):
contracts = self.OptionChainProvider.GetOptionContractList(symbol, self.Time)
underlyingPrice = self.Securities[symbol].Price
puts = [i for i in contracts if i.ID.OptionRight == OptionRight.Put and
underlyingPrice < i.ID.StrikePrice and
self.DTE - self.ExpDelta < (i.ID.Date - self.Time).days < self.DTE + self.ExpDelta]
calls = [i for i in contracts if i.ID.OptionRight == OptionRight.Call and
underlyingPrice < i.ID.StrikePrice and
self.DTE - self.ExpDelta < (i.ID.Date - self.Time).days < self.DTE + self.ExpDelta]
if len(puts) > 0 and len(calls) > 0:
sortedPuts = sorted(sorted(puts, key = lambda x: abs((x.ID.Date - self.Time).days - self.DTE)),
key = lambda x: underlyingPrice - x.ID.StrikePrice, reverse=True)[0]
sortedCalls = sorted(sorted(calls, key = lambda x: abs((x.ID.Date - self.Time).days - self.DTE)),
key = lambda x: underlyingPrice - x.ID.StrikePrice, reverse=True)[0]
atmContracts = [sortedPuts, sortedCalls]
for contract in atmContracts:
if contract not in self.contractsAdded:
self.contractsAdded.add(contract)
self.AddOptionContract(contract, Resolution.Minute)
return atmContracts
else:
return str()