Overall Statistics |
Total Trades 6 Average Win 0.04% Average Loss -0.01% Compounding Annual Return 0.102% Drawdown 0.000% Expectancy 1.052 Net Profit 0.009% Sharpe Ratio 1.051 Probabilistic Sharpe Ratio 50.587% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 3.10 Alpha 0 Beta -0.003 Annual Standard Deviation 0.001 Annual Variance 0 Information Ratio 2.37 Tracking Error 0.228 Treynor Ratio -0.375 Total Fees $4.00 |
from datetime import timedelta class BullCallSpreadAlgorithm(QCAlgorithm): FB = None SB = None TB = None LB = None def Initialize(self): self.SetStartDate(2016, 1,1) self.SetEndDate(2016, 2, 27) self.SetCash(600000) equity = self.AddEquity("SPY", Resolution.Minute) option = self.AddOption("SPY", Resolution.Minute) self.symbol = option.Symbol # set our strike/expiry filter for this option chain option.SetFilter(-10,10, timedelta(0), timedelta(30)) self.Consolidate("SPY", timedelta(minutes=30), self.OnDataConsolidated) self.SetBenchmark(equity.Symbol) self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(15, 30), self.ClosePositions) def OnData(self,slice): 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==30): 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==30): if (self.SB.Close < self.FB.Low) and (self.FB.High > self.SB.High > self.FB.Low): self.SELLCALL(optionchain) if (not self.Portfolio.Invested) and (self.Time.hour==11) and (self.Time.minute==00): if (self.TB.Close > self.FB.High) and (self.FB.High > self.TB.Low > self.FB.Low): self.SELLPUT(optionchain) if (not self.Portfolio.Invested) and (self.Time.hour==11) and (self.Time.minute==00): if (self.TB.Close < self.FB.Low) and (self.FB.High > self.TB.High > self.FB.Low): self.SELLCALL(optionchain) if (not self.Portfolio.Invested) and (self.Time.hour==11) and (self.Time.minute==30): if (self.LB.Close > self.FB.High) and (self.FB.High > self.LB.Low > self.FB.Low): self.SELLPUT(optionchain) if (not self.Portfolio.Invested) and (self.Time.hour==11) and (self.Time.minute==30): if (self.LB.Close < self.FB.Low) and (self.FB.High > self.LB.High > self.FB.Low): self.SELLCALL(optionchain) #create a different method def SELLPUT(self,optionchain): for i in optionchain: if i.Key != self.symbol: continue chain = i.Value # sorted the optionchain by expiration date and choose the closest date by adding reverse=True and using index[-1] 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: self.Debug("svbbvhbfvs0" + str(i) + "strik price" + str(i.Strike) + "fb.low" + str(self.FB.Low)) hi.append(i) hi=sorted(hi,key = lambda x : x.Strike) for j in (hi): self.Debug("hiii"+str(j.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 # put option contract with least strike price difference beetween fb.low strike##check self.put_low = put_contracts[0] self.buy_put=put_contracts[8] 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 # filter the CALL options from the contracts expires on that date#CALL ==0 call = [i for i in chain if i.Expiry == expiry and i.Right == 0] # sorted the contracts according to their strike prices hi=[] for i in call: if i.Strike>=self.FB.High: self.Debug("svbbvhbfvs0" + str(i) + "strik price" + str(i.Strike) + "fb.low" + str(self.FB.High)) hi.append(i) hi=sorted(hi,key = lambda x : x.Strike) for j in (hi): self.Debug("hiii"+str(j.Strike)) call_contracts = sorted(hi,key = lambda x : abs(x.Strike -self.FB.High)) self.Debug(str(self.Time) + ":" + "this is the current time") if len(call_contracts) == 0: continue self.call_low = call_contracts[0] self.buy_call=call_contracts[8] 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 == 10 and bar.Time.minute == 0: self.SB = bar self.Debug("yesss") if bar.Time.hour == 10 and bar.Time.minute == 30: self.TB =bar if bar.Time.hour == 11 and bar.Time.minute == 00: self.LB =bar self.Debug("fblow" +" "+ str(self.FB.Low) +" "+ str( self.FB.High )+"2nd l h c"+" "+str( self.SB.Low) +" "+ str( self.SB.High)+" "+str( self.SB.Close)+" "+"3rd l h c"+" "+str( self.TB.Low) + " "+str( self.TB.High)+" "+str( self.TB.Close)+"4th l h c"+" "+str( self.LB.Low) +" "+ str( self.LB.High)+" "+str( self.LB.Close)) def OnOrderEvent(self, orderEvent): self.Log(str(orderEvent)) def ClosePositions(self): #2. Set self.FB to None, and liquidate SPY self.SB = None self.FB = None self.TB = None self.Lb = None self.Debug("bye")