Overall Statistics |
Total Trades 17 Average Win 0.00% Average Loss 0.00% Compounding Annual Return 0.127% Drawdown 0.000% Expectancy 1.162 Net Profit 0.006% Sharpe Ratio 7.374 Probabilistic Sharpe Ratio 96.437% Loss Rate 56% Win Rate 44% Profit-Loss Ratio 3.86 Alpha 0.001 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.579 Tracking Error 0.064 Treynor Ratio 9.233 Total Fees $9.00 |
from datetime import timedelta class BullCallSpreadAlgorithm(QCAlgorithm): FB = None SB = None TB = None LB = None def Initialize(self): self.SetStartDate(2018, 7,12) self.SetEndDate(2018, 7, 30) self.SetCash(600000) equity = self.AddEquity("SPY", Resolution.Minute) option = self.AddOption("SPY", Resolution.Minute) self.optionMultiplier = option.ContractMultiplier self.symbol = option.Symbol self.costs = {} # set our strike/expiry filter for this option chain option.SetFilter(self.UniverseFunc) self.Consolidate("SPY", timedelta(minutes=15), self.OnDataConsolidated) self.SetBenchmark(equity.Symbol) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(15, 30), self.ClosePositions) def OnData(self,slice): if self.Portfolio["SPY"].Quantity != 0: self.Liquidate() optionchain = slice.OptionChains for i in slice.OptionChains: if i.Key != self.symbol: continue chains = i.Value contract_list = [x for x in chains] if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): return if (not self.Portfolio.Invested) and (self.Time.hour==10) and (self.Time.minute==00): if (self.SB.Close > self.FB.High) and (self.FB.High > self.SB.Low > self.FB.Low): self.SELLPUT(optionchain) if (not self.Portfolio.Invested) and (self.Time.hour==10) and (self.Time.minute==00): if (self.SB.Close < self.FB.Low) and (self.FB.High > self.SB.High > self.FB.Low): self.SELLCALL(optionchain) def SELLPUT(self,optionchain): for i in optionchain: if i.Key != self.symbol: continue chain = i.Value expiry = sorted(chain,key = lambda x: x.Expiry,reverse=True)[-1].Expiry put = [i for i in chain if i.Expiry == expiry and i.Right == 1] hi=[] for i in put: if i.Strike<=self.FB.Low: hi.append(i) hi=sorted(hi,key = lambda x : x.Strike) put_contracts = sorted(hi,key = lambda x : abs(x.Strike -self.FB.Low)) #self.Debug(str(self.Time) + ":" + "this is the current time") if len(put_contracts) == 0: continue if str(self.Time)[0:10]==str(put_contracts[0].Expiry)[0:10]: if len(put_contracts)>7: self.put_low = put_contracts[0] self.buy_put=put_contracts[6] self.Sell(self.put_low.Symbol, 1) self.Buy(self.buy_put.Symbol,1) def SELLCALL(self,optionchain): for i in optionchain: if i.Key != self.symbol: continue chain = i.Value expiry = sorted(chain,key = lambda x: x.Expiry,reverse=True)[-1].Expiry call = [i for i in chain if i.Expiry == expiry and i.Right == 0] hi=[] for i in call: if i.Strike>=self.FB.High: hi.append(i) hi=sorted(hi,key = lambda x : x.Strike) call_contracts = sorted(hi,key = lambda x : abs(x.Strike -self.FB.High)) if len(call_contracts) == 0: continue if str(self.Time)[0:10]==str(call_contracts[0].Expiry)[0:10]: if len(call_contracts)>=7: self.call_low = call_contracts[0] self.buy_call=call_contracts[6] self.Sell(self.call_low.Symbol, 1) self.Buy(self.buy_call.Symbol,1) def OnDataConsolidated(self, bar): if bar.Time.hour == 9 and bar.Time.minute == 30: self.FB = bar #self.Debug("yes") if bar.Time.hour == 9 and bar.Time.minute ==45: self.SB = bar def OnOrderEvent(self, orderEvent): if orderEvent.Status == OrderStatus.Filled and orderEvent.Symbol.SecurityType == SecurityType.Option: q = orderEvent.FillQuantity p = orderEvent.FillPrice m = self.optionMultiplier cashflow = q * p * m if self.Portfolio[orderEvent.Symbol].Invested: self.costs[orderEvent.Symbol] = cashflow else: pnl = -(self.costs[orderEvent.Symbol] + cashflow) def ClosePositions(self): self.SB = None self.FB = None def UniverseFunc(self, universe): # include weekly contracts return universe.IncludeWeeklys().Expiration(TimeSpan.FromDays(0),TimeSpan.FromDays(3)).Strikes(-10,10)