| 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.symbol = option.Symbol
# 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):
self.Log(str(orderEvent))
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)