Overall Statistics
Total Trades
3
Average Win
0%
Average Loss
0%
Compounding Annual Return
-4.276%
Drawdown
16.000%
Expectancy
0
Net Profit
-15.744%
Sharpe Ratio
-1.046
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.044
Beta
0.226
Annual Standard Deviation
0.038
Annual Variance
0.001
Information Ratio
-1.533
Tracking Error
0.038
Treynor Ratio
-0.177
Total Fees
$3.00
import numpy as np
import decimal as d
from datetime import timedelta
import datetime
#import datetime
### <summary>
### Basic template algorithm simply initializes the date range and cash. This is a skeleton
### framework you can use for designing an algorithm.
### </summary>
class BasicTemplateAlgorithm(QCAlgorithm):
    '''Basic template algorithm simply initializes the date range and cash'''

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        '''Initialie the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2014, 1, 1)  #Set Start Date
        self.SetEndDate(2017,12,1)    #Set End Date
        self.SetCash(1000000)           #Set Strategy Cash
        # Find more symbols here: http://quantconnect.com/data
        self.osymbol = "XOM"
        equity = self.AddEquity("XOM", Resolution.Minute)
        self.stock = equity.Symbol
        option = self.AddOption("XOM", Resolution.Minute)
        self.symbol = option.Symbol
        # set our strike/expiry filter for this option chain
        option.SetFilter(-5, 5, timedelta(20), timedelta(35))
        #direcitonal indicators
        self._macdHistogram = RollingWindow[float](12)
        # Creates a Rolling Window indicator to keep the 2 TradeBar
        self._bbupwindow = RollingWindow[d.Decimal](12)    # For other security types, use QuoteBar
        self._bbmidwindow = RollingWindow[d.Decimal](12)    # For other security types, use QuoteBar
        self._bblowindow = RollingWindow[d.Decimal](12)    # For other security types, use QuoteBar
        
        self._keltnerupwindow = RollingWindow[d.Decimal](12)    # For other security types, use QuoteBar
        self._keltnermidwindow = RollingWindow[d.Decimal](12)    # For other security types, use QuoteBar
        self._keltnerlowindow = RollingWindow[d.Decimal](12)    # For other security types, use QuoteBar
        self._mom = RollingWindow[float](12)
        
        self._macd = self.MACD(self.osymbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
        self._bb = self.BB(self.osymbol, 20, 2,  MovingAverageType.Simple, Resolution.Daily)
        self._keltner = self.KCH(self.osymbol, 20, d.Decimal(1.5), MovingAverageType.Simple, Resolution.Daily)  #its working NOW !!! 
        self._mom1 = self.MOM(self.osymbol, 20, Resolution.Daily)
    def bullSqueeze(self, data):
        a = True
        for num in range(0,5):
            if self._bbupwindow[num] < self._keltnerupwindow[num] and self._bblowindow[num] > self._keltnerlowindow[num]:
                a = True
            else:
                return False
        if a == True:
            if self._mom[4] < self._mom[0] and self._macdHistogram[3] < self._macdHistogram[0]:
                return True
    def bearishSqueeze(self,data):
        a = True
        for num in range(0,5):
            if self._bbupwindow[num] < self._keltnerupwindow[num] and self._bblowindow[num] > self._keltnerlowindow[num]:
                a = True
            else:
                return False
        if a == True:
            if self._mom[4] > self._mom[0] and self._macdHistogram[3] > self._macdHistogram[0]:
                return True
    def bullishTradeCheck(self, data):
        if self._mom[2] > self._mom[0] or self._macdHistogram[2] > self._macdHistogram[0]:
            return True
    def bearishTradeCheck(self, data):
        if self._mom[2] < self._mom[0] or self._macdHistogram[2] < self._macdHistogram[0]:
            return True
    def OnData(self, slice):
        #'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
        #if not self.Portfolio.Invested:
        self._macdHistogram.Add(self._macd.Histogram.Current.Value)
        self._mom.Add(self._mom1.Current.Value)
        self._bbupwindow.Add(self._bb.UpperBand.Current.Value)
        self._bbmidwindow.Add(self._bb.MiddleBand.Current.Value)
        self._bblowindow.Add(self._bb.LowerBand.Current.Value)
        self._keltnerupwindow.Add(self._keltner.UpperBand.Current.Value)
        self._keltnermidwindow.Add(self._keltner.MiddleBand.Current.Value)
        self._keltnerlowindow.Add(self._keltner.LowerBand.Current.Value)
        
        if not self._keltner.IsReady: return
        if not self.Portfolio.Invested:
            if self.bullSqueeze(slice) == True:
                self.Log("Bullish squeeze")
                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 there is no contracts in this optionchain, pass the instance
                    if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): 
                        return  
                    self.TradeCallOptions(optionchain)
            elif self.bearishSqueeze(slice) == True: 
                self.Log("Bearish squeeze")
                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 there is no contracts in this optionchain, pass the instance
                    if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): 
                        return   
                     # if there is no securities in portfolio, trade the options
                    self.TradePutOptions(optionchain)
        else:
            option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
            for a in option_invested:
                if self.Securities[a].Invested:
                    #self.Transactions.CancelOpenOrders(a)
                    open_orders = self.Transactions.GetOpenOrders(a)
                    if len(open_orders) == 0:
                        if a.ID.OptionRight == OptionRight.Call:
                            if self.Time.date() == (self.Securities[a].Expiry.date()+timedelta(1)):
                                self.LimitOrder(a, -(self.quantityC), self.Securities[a].BidPrice)
                                #self.Transactions.CancelOpenOrders(a)
                            elif self.bullishTradeCheck(slice) == True:
                                self.LimitOrder(a, -(self.quantityC), self.Securities[a].BidPrice)
                                #self.Transactions.CancelOpenOrders(a)
                        elif a.ID.OptionRight == OptionRight.Put:
                            if self.Time.date() == (self.Securities[a].Expiry.date()+timedelta(1)):
                                self.LimitOrder(a, -(self.quantityP), self.Securities[a].BidPrice)
                               # self.Transactions.CancelOpenOrders(a)
                            elif self.bearishTradeCheck(slice) ==True:
                                self.LimitOrder(a, -(self.quantityP), self.Securities[a].BidPrice)
                                #self.Transactions.CancelOpenOrders(a)
        #if self.Portfolio.Invested:
        
    def OnOrderEvent(self, orderEvent):
        self.Log("order event")
        self.Log(str(orderEvent))
    def TradeCallOptions(self,optionchain):
    
         for i in optionchain:
            self.Log("in trade options function")
            if i.Key != self.symbol: continue
            chain = i.Value
            # sorted the optionchain by expiration date and choose the furthest date
            expiry = sorted(chain,key = lambda x: x.Expiry, reverse=True)[0].Expiry
            # filter the call options from the contracts expires on that date
            call = [i for i in chain if i.Expiry == expiry and i.Right == 0]
            # sorted the contracts according to their strike prices 
            call_contracts = sorted(call,key = lambda x: x.Strike)    
            if len(call_contracts) == 0: continue
            self.call = call_contracts[0]
            self.quantityC = self.CalculateOrderQuantity(self.call.Symbol, .05)
            self.LimitOrder(self.call.Symbol, int(self.quantityC), self.call.AskPrice)
    def TradePutOptions(self,optionchain):
    
         for i in optionchain:
            self.Log("in trade options function")
            if i.Key != self.symbol: continue
            chain = i.Value
            # sorted the optionchain by expiration date and choose the furthest date
            expiry = sorted(chain,key = lambda x: x.Expiry, reverse=True)[0].Expiry
            # filter the call options from the contracts expires on that date
            put = [i for i in chain if i.Expiry == expiry and i.Right == 1]
            # sorted the contracts according to their strike prices 
            put_contracts = sorted(put,key = lambda x: x.Strike)    
            if len(put_contracts) == 0: continue
            self.put = put_contracts[0]
            self.quantityP = self.CalculateOrderQuantity(self.put.Symbol, .05)
            self.LimitOrder(self.put.Symbol, int(self.quantityP), self.put.AskPrice)