Overall Statistics |
Total Trades 70 Average Win 1.77% Average Loss -1.29% Compounding Annual Return 33.868% Drawdown 8.100% Expectancy 0.156 Net Profit 6.570% Sharpe Ratio 1.22 Probabilistic Sharpe Ratio 52.079% Loss Rate 51% Win Rate 49% Profit-Loss Ratio 1.38 Alpha 0.122 Beta 1.056 Annual Standard Deviation 0.205 Annual Variance 0.042 Information Ratio 0.897 Tracking Error 0.144 Treynor Ratio 0.237 Total Fees $70.00 Estimated Strategy Capacity $81000.00 Lowest Capacity Asset SPY Y6TSBE5T7HIE|SPY R735QTJ8XC9X Portfolio Turnover 3.81% |
# region imports from AlgorithmImports import * # endregion # ------------------------------------------------------------ TICKER = "SPY"; PERIOD = 3 # ------------------------------------------------------------ class MeasuredMagentaDogfish(QCAlgorithm): def Initialize(self): 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) self.SetSecurityInitializer(self.security_initializer) ## Set up options chain option = self.AddOption(TICKER, Resolution.Minute) self.symbol = option.Symbol option.SetFilter(-10, 10, timedelta(0), timedelta(days = 15)) self.call = TICKER # Initialize the call contract self.qty = 1 # number of contracts traded def security_initializer(self, security): # * SecurityType.Index & SecurityType.IndexOption security.SetDataNormalizationMode(DataNormalizationMode.Raw) security.SetMarketPrice(self.GetLastKnownPrice(security)) # 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