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