Overall Statistics |
Total Trades 39 Average Win 0.02% Average Loss 0% Compounding Annual Return 0.082% Drawdown 0.000% Expectancy 0 Net Profit 0.320% Sharpe Ratio 1.674 Probabilistic Sharpe Ratio 99.562% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.001 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.043 Tracking Error 0.265 Treynor Ratio 306.191 Total Fees $25.00 |
from Execution.ImmediateExecutionModel import ImmediateExecutionModel import pandas as pd class CalibratedUncoupledRadiator(QCAlgorithm): ''' If SPY is within a certain % of its 52W high, write a call option that is a certain $ above the opening price. If the option gets assigned, do a limit order for covering at the assignment price. Pre ''' # Paramaters callOtmAmount = 6 withinYearlyHighPct = 10 spy = None spyOption = None spyCoverOrderTicket = None yearlyHigh = None days = 0 def Initialize(self): self.SetStartDate(2007, 1, 1) self.SetEndDate(2020, 11, 19) self.SetCash(100000) #self.callOtmAmount = int(self.GetParameter("callOtmAmount")) # TODO deal with missing parameter self.spy = self.AddEquity("SPY", Resolution.Minute) self.spy.SetDataNormalizationMode(DataNormalizationMode.Raw) # Required for working with options self.spy.SetLeverage(4) self.UniverseSettings.MinimumTimeInUniverse = 10 self.yearlyHigh = self.MAX(self.spy.Symbol, 252, Resolution.Daily) history = self.History(self.spy.Symbol, 252, Resolution.Daily) for bar in history.itertuples(): self.yearlyHigh.Update(bar.Index[1], bar.high) self.Debug("SPY yearly high warmed up, value = " + str(self.yearlyHigh.Current.Value)) self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday), self.TimeRules.AfterMarketOpen("SPY", 1), self.OpeningBar) self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Wednesday, DayOfWeek.Friday), self.TimeRules.BeforeMarketClose("SPY", 0), self.ClosingBar) self.SetExecution(ImmediateExecutionModel()) def OpeningBar(self): for holding in self.Portfolio.Values: if holding.Symbol != self.spy.Symbol and holding.Invested: self.Error("Assignment/expiration failed") self.Quit() self.spyOption = None if not self.IsMarketOpen(self.spy.Symbol): self.Debug("Market not open, returning") return self.LogPortfolio() if self.Portfolio[self.spy.Symbol].Invested: self.Liquidate(self.spy.Symbol) ''' if self.spyCoverOrderTicket is None: self.Debug("Assigned, placing limit order to cover") self.spyCoverOrderTicket = self.LimitOrder(self.spy.Symbol, -1 * self.Portfolio["SPY"].Quantity, self.Portfolio["SPY"].AveragePrice) return ''' high = self.yearlyHigh.Current.Value if 100 * (high - self.Securities[self.spy.Symbol].Close)/high > self.withinYearlyHighPct: self.Debug("Too far away from yearly high: " + str(self.Securities[self.spy.Symbol].Close) + " vs " + str(high)) return options = self.OptionChainProvider.GetOptionContractList(self.spy.Symbol, self.Time) if options is None or len(options) == 0: self.Error("No options found") return callsExpiringToday = [o for o in options if o.ID.Date.date() == self.Time.date() and o.ID.OptionRight == OptionRight.Call] sortedByStrike = sorted(callsExpiringToday, key = lambda o: o.ID.StrikePrice) for option in sortedByStrike: id = option.ID if id.StrikePrice >= self.Securities[self.spy.Symbol].Open + self.callOtmAmount: self.spyOption = self.AddOptionContract(option, Resolution.Minute) self.Debug(str(id.Date) + " " + str(id.StrikePrice) + " " + str(id.OptionRight)) break ''' if self.days > 30: self.Quit() self.days = self.days+1 ''' def ClosingBar(self): self.spyOption = None def OnData(self, slice): if self.spyOption is not None and self.Securities[self.spyOption.Symbol].Price != 0: self.MarketOrder(self.spyOption.Symbol, -5) self.spyOption = None return def OnOrderEvent(self, orderEvent): self.Debug(str(orderEvent)) if not self.spyCoverOrderTicket is None and orderEvent.OrderId == self.spyCoverOrderTicket.OrderId and self.spyCoverOrderTicket.Status == OrderStatus.Filled: self.Debug("covered!") self.spyCoverOrderTicket = None def LogPortfolio(self): for symbol in self.Portfolio.Keys: holding = self.Portfolio[symbol] if holding.Invested: self.Debug(str(symbol) + " " + str(holding.Quantity) + " @ " + str(holding.AveragePrice))