| 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 2.371 Tracking Error 0.192 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
class SwimmingOrangeAlpaca(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 2, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Minute
self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw
self.AddUniverse(self.Universe.DollarVolume.Top(3))
self.SetSecurityInitializer(self.OptionContractSecurityInitializer)
self.optionsByEquity = {}
def OptionContractSecurityInitializer(self, security):
if security.Type == SecurityType.Equity:
symbol = security.Symbol
security.VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30, Resolution.Daily)
for index, row in self.History(symbol, 30, Resolution.Daily).iterrows():
security.SetMarketPrice(IndicatorDataPoint(index[1], row.close))
if security.Type == SecurityType.Option:
security.PriceModel = OptionPriceModels.CrankNicolsonFD()
def CoarseContractSelection(self, security):
symbol = security.Symbol
price = security.Price
contracts = self.OptionChainProvider.GetOptionContractList(symbol, self.Time)
strikes = set([x.ID.StrikePrice for x in contracts])
strikes = sorted(strikes, key=lambda x: abs(price-x))[:10]
return [x for x in contracts if (x.ID.Date - self.Time).days < 15 and
x.ID.OptionRight == OptionRight.Put and
x.ID.StrikePrice in strikes]
def OnSecuritiesChanged(self, changes):
# When the Underlying is added, add the contracts
for security in changes.AddedSecurities:
if security.Type != SecurityType.Equity:
continue
symbol = security.Symbol
contracts = self.CoarseContractSelection(security)
if not contracts:
continue
msg = ', '.join([x.Value for x in contracts])
self.Log(f'Adding {len(contracts)} for {symbol} on {self.Time}')
self.optionsByEquity[symbol] = list()
for contract in contracts:
contractSymbol = self.AddOptionContract(contract).Symbol
self.optionsByEquity[symbol].append(contractSymbol)
# When the Underlying is removed, remove the contracts
for security in changes.RemovedSecurities:
symbol = security.Symbol
if security.Type == SecurityType.Equity:
contractSymbols = self.optionsByEquity.pop(symbol, [])
for contractSymbol in contractSymbols:
self.Log(f'Removing {contractSymbol} on {self.Time}')
self.RemoveOptionContract(contractSymbol)
def OnData(self, data):
for kvp in data.OptionChains:
underlyingSymbol = kvp.Key.Underlying
if not self.IsMarketOpen(underlyingSymbol):
return
contracts = kvp.Value.Contracts.Values
zero_delta = 0
for contract in contracts:
delta = contract.Greeks.Delta
if delta == 0:
zero_delta += 1
if zero_delta > 0:
self.Debug(f'Zero delta in {100 * zero_delta / len(contracts)}% of contracts on {self.Time}')