Overall Statistics |
Total Trades 1684 Average Win 0.10% Average Loss -0.17% Compounding Annual Return -100.000% Drawdown 79.300% Expectancy -0.529 Net Profit -71.108% Sharpe Ratio -0.291 Probabilistic Sharpe Ratio 7.542% Loss Rate 70% Win Rate 30% Profit-Loss Ratio 0.58 Alpha 5.473 Beta 15.622 Annual Standard Deviation 3.442 Annual Variance 11.846 Information Ratio -0.176 Tracking Error 3.331 Treynor Ratio -0.064 Total Fees $7342.50 Estimated Strategy Capacity $420000.00 Lowest Capacity Asset SPY XTN6UC1W8WDI|SPY R735QTJ8XC9X |
class ETFSimple(QCAlgorithm): def Initialize(self): self.SetStartDate(2021,9,13) self.SetCash(1000000) self.SetPortfolioConstruction(InsightWeightingPortfolioConstructionModel()) #we want our portfolio to be made up of insights self.SetExecution(ImmediateExecutionModel()) self.SetBrokerageModel(BrokerageName.AlphaStreams) #required brokerage model for submission ############################################################################ ## OPTIONS ############################################################################ self.STRIKES = 10 # no of strikes around ATM => for uni selection self.MIN_EXPIRY = 30 # min num of days to expiration => for uni selection self.MAX_EXPIRY = 60 # max num of days to expiration => for uni selection self.MIN_DELTA = 0.25 self.MAX_DELTA = 0.45 self.MIN_PREMIUM = 0.05 equity = self.AddEquity("SPY", Resolution.Minute) option = self.AddOption("SPY", Resolution.Minute) self.optionSymbol = option.Symbol # set strike/expiry filter for this option chain option.SetFilter(-self.STRIKES, self.STRIKES, timedelta(self.MIN_EXPIRY), timedelta(self.MAX_EXPIRY)) # for greeks and pricer (needs some warmup) - https://github.com/QuantConnect/Lean/blob/21cd972e99f70f007ce689bdaeeafe3cb4ea9c77/Common/Securities/Option/OptionPriceModels.cs#L81 option.PriceModel = OptionPriceModels.CrankNicolsonFD() # both European & American, automatically # this is needed for Greeks calcs self.SetWarmUp(TimeSpan.FromDays(30)) def OnData(self, slice): if (self.IsWarmingUp): return chain = slice.OptionChains.get(self.optionSymbol, None) if not chain: return # filter the put options contracts calls = [x for x in chain if x.Right == OptionRight.Call and abs(x.Greeks.Delta) > self.MIN_DELTA and abs(x.Greeks.Delta) < self.MAX_DELTA and x.BidPrice > self.MIN_PREMIUM] # sorted the contracts according to their expiration dates contracts = sorted(sorted(calls, key = lambda x: x.BidPrice, reverse=True), key = lambda x: x.Expiry) if len(contracts) == 0: return call = contracts[0].Symbol self.EmitInsights(Insight.Price(call, timedelta(self.MIN_EXPIRY), InsightDirection.Up, None, None, None, 1))