Overall Statistics |
Total Trades 105 Average Win 6.60% Average Loss -1.20% Compounding Annual Return 47.653% Drawdown 49.200% Expectancy 3.740 Net Profit 609.746% Sharpe Ratio 1.234 Probabilistic Sharpe Ratio 50.436% Loss Rate 27% Win Rate 73% Profit-Loss Ratio 5.52 Alpha 0.213 Beta 1.796 Annual Standard Deviation 0.399 Annual Variance 0.159 Information Ratio 1.16 Tracking Error 0.29 Treynor Ratio 0.274 Total Fees $639.75 Estimated Strategy Capacity $0.0000000000000000000000000001 Lowest Capacity Asset SPY XRX5OFMJ9L5Y|SPY R735QTJ8XC9X |
from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from datetime import timedelta from QuantConnect.Securities.Option import OptionPriceModels class DCAintoLEAPs(QCAlgorithm): def Initialize(self): self.SetStartDate(2016, 6, 1) self.SetEndDate(2021, 6, 10) self.SetWarmUp(90, Resolution.Daily) self.UniverseSettings.SetLeverage = 1 self.num_buys = 24 self.amt_per_txn = 500000//24 self.SetCash(500000) self.AddEquity("SPY", Resolution.Daily) option = self.AddOption("SPY") option.PriceModel = OptionPriceModels.CrankNicolsonFD() self.option_symbol = option.Symbol # set our strike/expiry filter for this option chain option.SetFilter(self.UniverseFunc) # use the underlying equity as the benchmark self.SetBenchmark("SPY") self.contracts = None self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 10), self.OnDataTrade) self.Schedule.On(self.DateRules.WeekStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 10), self.sell_expiring) def UniverseFunc(self, universe): return universe.IncludeWeeklys().Strikes(-100000, 100000).Expiration(timedelta(380), timedelta(545)) def OnData(self,slice): if not (self.Time.hour == 9 and self.Time.minute == 38): return for kvp in slice.OptionChains: if kvp.Key != self.option_symbol: continue chain = kvp.Value chain = [x for x in chain if x.Right == OptionRight.Call and 380 <= (x.Expiry-self.Time).days <= 545] closest_expiry_beyond_1y = sorted(chain,key = lambda x: x.Expiry)[0].Expiry chain = [x for x in chain if x.Expiry == closest_expiry_beyond_1y] contracts = sorted(chain, key = lambda x: abs(x.Greeks.Delta-0.4)) self.contracts = contracts def sell_expiring(self): # Sell calls that are expiring within a week leaps = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option] for x in leaps: if (self.Securities[x].Expiry.date() - self.Time.date()).days <= 14: self.Liquidate(x) def OnDataTrade(self): # Buy calls if len(self.contracts) == 0: pass symbol = self.contracts[0].Symbol self.MarketOrder(symbol, (self.amt_per_txn/100)//self.contracts[0].AskPrice) x = self.contracts[0] columns=['idx', 'type(call 0, put 1)', 'strike', 'expiry', 'ask price', 'bid price', 'delta', x.Symbol.Value,\ x.Right,float(x.Strike),x.Expiry,float(x.BidPrice),float(x.AskPrice),float(x.Greeks.Delta)] self.Log(str(columns)) def OnOrderEvent(self, orderEvent): self.Log(str(orderEvent))