Overall Statistics
Total Trades
10
Average Win
0.00%
Average Loss
0.00%
Compounding Annual Return
2.669%
Drawdown
0.000%
Expectancy
-0.327
Net Profit
0.288%
Sharpe Ratio
6.548
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.35
Alpha
0.002
Beta
0.026
Annual Standard Deviation
0.004
Annual Variance
0
Information Ratio
-6.172
Tracking Error
0.137
Treynor Ratio
0.943
Total Fees
$5.00
from datetime import timedelta

class ProtectiveCollarAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017, 4, 1)
        self.SetEndDate(2017, 5, 10)
        self.SetCash(10000000)
        equity = self.AddEquity("GOOG", Resolution.Minute)
        option = self.AddOption("GOOG", Resolution.Minute)
        self.underlyingsymbol = equity.Symbol

        # set our strike/expiry filter for this option chain
        option.SetFilter(-10, +10, timedelta(0), timedelta(30))
        # use the underlying equity as the benchmark
        self.SetBenchmark(self.underlyingsymbol)
        
    def OnData(self,slice):

        if not self.Portfolio[self.underlyingsymbol].Invested:
            self.Buy("GOOG",100)     # buy 100 shares of the underlying stock    
        
        options_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
        if len(options_invested) == 0: 
            optionchain = slice.OptionChains
            for i in slice.OptionChains:
                chain = i.Value
                contract_list = [x for x in chain]
                if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): 
                    return 
            
                # choose the furthest expiration date within 30 days from now on
                expiry = sorted(chain, key = lambda x: x.Expiry)[-1].Expiry
                # filter the call options contracts
                call = [x for x in chain if x.Right == 0 and x.Expiry == expiry]
                # filter the put options contracts
                put = [x for x in chain if x.Right == 1 and x.Expiry == expiry]
                # sorted the call options by strike price and choose the deep OTM one in the list
                self.otm_call = sorted(call, key = lambda x: x.Strike)[-1]
                self.otm_put = sorted(put, key = lambda x: x.Strike)[0]
                if (self.otm_call is None) or (self.otm_put is None): return
            
                self.Sell(self.otm_call.Symbol, 1) # sell the OTM call 
                self.Buy(self.otm_put.Symbol, 1) # buy the OTM put
                self.Buy("GOOG",100)     # buy 100 shares of the underlying stock
    
    def OnOrderEvent(self, orderEvent):
        self.Log(str(orderEvent))