Overall Statistics |
Total Trades 106 Average Win 2.02% Average Loss -1.19% Compounding Annual Return 35.036% Drawdown 11.700% Expectancy 0.121 Net Profit 6.860% Sharpe Ratio 1.075 Probabilistic Sharpe Ratio 48.857% Loss Rate 58% Win Rate 42% Profit-Loss Ratio 1.70 Alpha 0.059 Beta 1.271 Annual Standard Deviation 0.252 Annual Variance 0.064 Information Ratio 0.569 Tracking Error 0.183 Treynor Ratio 0.213 Total Fees $106.00 Estimated Strategy Capacity $1800000.00 Lowest Capacity Asset SPY Y6GZIMV0GG5I|SPY R735QTJ8XC9X Portfolio Turnover 2.15% |
# region imports from AlgorithmImports import * # endregion # ------------------------------------------------------------ TICKER = "SPY"; PERIOD = 3 # ------------------------------------------------------------ class MeasuredMagentaDogfish(QCAlgorithm): def Initialize(self): self.SetSecurityInitializer(lambda x: x.SetDataNormalizationMode(DataNormalizationMode.Raw)) self.SetStartDate(2023, 1, 1) # Set Start Date self.SetCash(10000) # Set Strategy Cash self.equity = self.AddEquity(TICKER, Resolution.Minute).Symbol self.SetBenchmark(TICKER) ## Set up options chain option = self.AddOption(TICKER, Resolution.Minute) self.symbol = option.Symbol self.call = TICKER # Initialize the call contract self.qty = 1 # number of contracts traded option.SetFilter(self.UniverseFunc) def UniverseFunc(self, universe): return universe.IncludeWeeklys().Strikes(-1, 1).Expiration(timedelta(0), timedelta(15)) # Enter at 9:45 am each morning def OnData(self, slice): if self.Time.hour == 9 and self.Time.minute == 45: self.BuyCalls(slice) # Check position P&L and set TP and SL def OnEndOfDay(self, symbol): self.Liquidate(tag="Close positions at EOD") def BuyCalls(self,slice): self.Log("FINDING options chain...") if slice.OptionChains.Count == 0: return self.Log("FOUND options chain...") for i in slice.OptionChains: if i.Key != self.symbol: continue chain = i.Value call = [x for x in chain if x.Right == 0] # filter the call options contracts # sorted the contracts according to their expiration dates and choose the ATM options contracts = sorted(sorted(call, key = lambda x: x.Expiry, reverse=False), key = lambda x: abs(chain.Underlying.Price - x.Strike)) df = pd.DataFrame([[x.Right,x.Strike,x.Expiry,x.BidPrice,x.AskPrice] for x in chain], index=[x.Symbol.Value for x in chain], columns=['type(call 0, put 1)', 'strike', 'expiry', 'ask price', 'bid price']) self.Log(str(df)) if len(contracts) == 0: return self.Log("Length of contract is NOT zero, entering order...") contract = contracts[0] # select the closest expiry contract self.call = contract.Symbol self.Buy(self.call, self.qty) # buy the call option self.tradeLimit = 1