| 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")