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)