Overall Statistics |
Total Trades 106 Average Win 2.18% Average Loss -0.50% Compounding Annual Return -40.713% Drawdown 15.000% Expectancy 1.167 Net Profit -5.654% Sharpe Ratio -0.849 Sortino Ratio -1.232 Probabilistic Sharpe Ratio 24.809% Loss Rate 60% Win Rate 40% Profit-Loss Ratio 4.37 Alpha -0.732 Beta -1.382 Annual Standard Deviation 0.255 Annual Variance 0.065 Information Ratio 0.435 Tracking Error 0.361 Treynor Ratio 0.157 Total Fees $0.00 Estimated Strategy Capacity $380000.00 Lowest Capacity Asset SPXW Y6E4PYLX0PKE|SPX 31 Portfolio Turnover 2.38% |
# region imports from AlgorithmImports import * # endregion ''' PROBLEM STATEMENT: https://www.quantconnect.com/forum/discussion/8399/optionstrategies-limit-orders/p1 REFERENCES: https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/IndexOptionIronCondorAlgorithm.py https://github.com/QuantConnect/Lean/blob/83f9499b4a8faf3a1344b6f22284a35ba91d2e1b/Common/Securities/Option/StrategyMatcher/OptionStrategyDefinitions.cs#L61-L70 https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/order-types/combo-limit-orders ''' class CrawlingAsparagusButterfly(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 2, 1) self.SetEndDate(2023, 3, 13) self.SetCash(100000) ticker = self.AddIndex("SPX", Resolution.Minute).Symbol option = self.AddIndexOption(ticker, "SPXW", Resolution.Minute) self.spy = option.Symbol option.SetFilter(lambda x: x.WeeklysOnly().Strikes(-5, 5).Expiration(0, 14)) def OnData(self, data: Slice): if self.Portfolio.Invested: return chain = data.OptionChains.get(self.spy) if not chain: return # get minimum expiry expiry = min([x.Expiry for x in chain]) chain = [x for x in chain if x.Expiry == expiry] # sort by strike to get K1 and K2 where K2>K1 to make a call spread calls = sorted([x for x in chain if x.Right == OptionRight.Call], key=lambda x: x.Strike, reverse=True) if len(calls) < 2 : return # create Bear call legs #short C1(K1) and long C2(K2) self.Log(f"Strike Call 1 Leg (short): {calls[-1].Strike} | Strike Call 2 Leg (Long): {calls[0].Strike} | Expiry: {calls[0].Expiry}") self.Log(f"Strike spread: {calls[0].Strike - calls[-1].Strike}") legs = [ Leg.Create(calls[-1].Symbol, -1), Leg.Create(calls[0].Symbol, 1), ] # Calculate limit price limit_price = round(sum([self.Securities[leg.Symbol].Close for leg in legs]) * 0.95, 2) # Place order self.ComboLimitOrder(legs, 1, limit_price)