Overall Statistics |
Total Trades 94 Average Win 0.37% Average Loss -0.09% Compounding Annual Return 1.848% Drawdown 1.600% Expectancy 0.222 Net Profit 0.912% Sharpe Ratio 0.451 Probabilistic Sharpe Ratio 32.884% Loss Rate 77% Win Rate 23% Profit-Loss Ratio 4.22 Alpha 0.016 Beta 0.002 Annual Standard Deviation 0.035 Annual Variance 0.001 Information Ratio -1.994 Tracking Error 0.128 Treynor Ratio 9.243 Total Fees $94.00 Estimated Strategy Capacity $7800000.00 Lowest Capacity Asset SPCE 324FMVN88B9T2|SPCE X91R7VLCNM91 |
class AlgoSeekDataDemoAlgorithm(QCAlgorithm): max_option_contract_expiry = timedelta(days=30) profit_target = 5000 option_contract_symbol_by_equity_symbol = {} hit_profit_target_symbols = [] def Initialize(self): self.SetStartDate(2021, 1, 1) self.SetEndDate(2021, 6, 30) self.SetCash(1000000) self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.Universe.DollarVolume.Top(5)) def OnData(self, data): # Subscribe to an Option contract for each underlying Equity if one isn't currently selected for symbol, option_contract in self.option_contract_symbol_by_equity_symbol.items(): if option_contract is not None or symbol in self.hit_profit_target_symbols: continue # Fetch the contracts from the OptionChainProvider contract_symbols = self.OptionChainProvider.GetOptionContractList(symbol, data.Time) # Find the latest contract expiry expiries = [symbol.ID.Date for symbol in contract_symbols if symbol.ID.Date.date() > data.Time.date() + self.max_option_contract_expiry] if len(expiries) == 0: continue furthest_expiry = max(expiries) # Select the put Option contracts with the furthest expiry and in the money selected_contract_symbols = [] for contract_symbol in contract_symbols: if contract_symbol.ID.Date == furthest_expiry and \ contract_symbol.ID.OptionRight == OptionRight.Put and \ contract_symbol.ID.StrikePrice < self.Securities[symbol].Price: selected_contract_symbols.append(contract_symbol) if len(selected_contract_symbols) == 0: continue # Select the put Option contract with the lowest strike price contract_symbol = sorted(selected_contract_symbols, key=lambda contract: contract.ID.StrikePrice)[0] self.option_contract_symbol_by_equity_symbol[symbol] = contract_symbol # Subscribe to the Option contract self.AddOptionContract(contract_symbol) # Place entry orders for symbol, option_contract in self.option_contract_symbol_by_equity_symbol.items(): if symbol in self.hit_profit_target_symbols: continue # Buy underlying Equity if not already invested if data.ContainsKey(symbol) and data[symbol] is not None and \ not self.Portfolio[symbol].Invested and not data[symbol].IsFillForward: self.MarketOrder(symbol, 100) # Buy the put Option if option_contract is not None and \ data.ContainsKey(option_contract) and \ data[option_contract] is not None and \ not self.Portfolio[option_contract].Invested and \ self.Securities[option_contract].IsTradable: self.MarketOrder(option_contract, 1) # Close the position if we've hit the take-profit level for symbol, option_contract in self.option_contract_symbol_by_equity_symbol.items(): if self.Portfolio[symbol].Invested and \ self.Portfolio[symbol].UnrealizedProfit > self.profit_target and \ symbol not in self.hit_profit_target_symbols: self.hit_profit_target_symbols.append(symbol) self.Liquidate(symbol) self.Liquidate(option_contract) def OnOrderEvent(self, order_event): # Remove the selected Option contract from our dictionary if it has expired if order_event.Status == OrderStatus.Filled and \ order_event.Symbol in self.option_contract_symbol_by_equity_symbol.values() and \ order_event.Direction == OrderDirection.Sell: self.option_contract_symbol_by_equity_symbol[order_event.Symbol.Underlying] = None def OnSecuritiesChanged(self, changes): for security in changes.AddedSecurities: if security.Type == SecurityType.Equity: self.option_contract_symbol_by_equity_symbol[security.Symbol] = None for security in changes.RemovedSecurities: if security.Type == SecurityType.Equity: if security.Symbol in self.hit_profit_target_symbols: self.hit_profit_target_symbols.remove(security.Symbol) self.Liquidate(security.Symbol) option_contract = self.option_contract_symbol_by_equity_symbol.pop(security.Symbol, None) if option_contract: self.Liquidate(option_contract)