Overall Statistics |
Total Trades 8 Average Win 32.60% Average Loss -21.43% Compounding Annual Return -2.394% Drawdown 39.300% Expectancy 0.261 Net Profit -2.587% Sharpe Ratio 0.162 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.52 Alpha 0.076 Beta 0.005 Annual Standard Deviation 0.469 Annual Variance 0.22 Information Ratio 0.186 Tracking Error 0.825 Treynor Ratio 14.891 Total Fees $72.00 |
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. # Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from datetime import timedelta ### <summary> ### This example demonstrates how to add options for a given underlying equity security. ### It also shows how you can prefilter contracts easily based on strikes and expirations, and how you ### can inspect the option chain to pick a specific option contract to trade. ### </summary> ### <meta name="tag" content="using data" /> ### <meta name="tag" content="options" /> ### <meta name="tag" content="filter selection" /> class BasicTemplateOptionsAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 1) self.SetEndDate(2018, 1, 30) self.SetCash(100000) self.AddEquity("SPXL", Resolution.Minute) self.AddEquity("SPXS", Resolution.Minute) option = self.AddOption("SPXL") self.option_symbol_bull = option.Symbol # set our strike/expiry filter for this option chain option.SetFilter(-1, +1, timedelta(180), timedelta(720)) # use the underlying equity as the benchmark self.SetBenchmark("SPXL") option_bear = self.AddOption("SPXS") self.option_symbol_bear = option_bear.Symbol #self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Monday), self.TimeRules.At(10, 0), self.Rebalance) # set our strike/expiry filter for this option chain option_bear.SetFilter(-1, +1, timedelta(180), timedelta(720)) def OnData(self,slice): price_bull = 12 price_bear = 13 weight_bull_init = 0.33333 weight_bear_init = 0.66667 weight_bull = (round((weight_bull_init*100000/(price_bull*100)), 0)) weight_bear = (round((weight_bear_init*100000/(price_bear*100)), 0)) self.Log(f"Bull: {weight_bull}") #Print out the current number of options bull self.Log(f"Bear: {weight_bear}") #Print out the current number of options bear self.TradeOptions(slice, weight_bull, weight_bear) def TradeOptions(self, slice, weight_bull, weight_bear): if self.Portfolio.Invested: return chain = slice.OptionChains.GetValue(self.option_symbol_bull) if chain is None: return # we sort the contracts to find at the money (ATM) contract with farthest expiration contracts_put = sorted(sorted(sorted(chain, \ key = lambda x: abs(chain.Underlying.Price - x.Strike)), \ key = lambda x: x.Expiry, reverse=True), \ key = lambda x: x.Right, reverse=True) chain2 = slice.OptionChains.GetValue(self.option_symbol_bull) if chain2 is None: return contracts_call = sorted(sorted(sorted(chain2, \ key = lambda x: abs(chain2.Underlying.Price - x.Strike)), \ key = lambda x: x.Expiry, reverse=True), \ key = lambda x: x.Right, reverse=False) chain3 = slice.OptionChains.GetValue(self.option_symbol_bear) if chain3 is None: return # we sort the contracts to find at the money (ATM) contract with farthest expiration contracts_bear_put = sorted(sorted(sorted(chain3, \ key = lambda x: abs(chain3.Underlying.Price - x.Strike)), \ key = lambda x: x.Expiry, reverse=True), \ key = lambda x: x.Right, reverse=True) chain4 = slice.OptionChains.GetValue(self.option_symbol_bear) if chain4 is None: return # we sort the contracts to find at the money (ATM) contract with farthest expiration contracts_bear_call = sorted(sorted(sorted(chain4, \ key = lambda x: abs(chain4.Underlying.Price - x.Strike)), \ key = lambda x: x.Expiry, reverse=True), \ key = lambda x: x.Right, reverse=False) # if found, trade it if len(contracts_put) == 0: return symbol_bull_put = contracts_put[0].Symbol self.MarketOrder(symbol_bull_put, weight_bull) #self.MarketOnCloseOrder(symbol_bull_put, -1) if len(contracts_call) == 0: return symbol_bull_call = contracts_call[0].Symbol self.MarketOrder(symbol_bull_call, -weight_bull) #self.MarketOnCloseOrder(symbol_bull_call, 1) if len(contracts_bear_put) == 0: return symbol_bear_put = contracts_bear_put[0].Symbol self.MarketOrder(symbol_bear_put, weight_bear) #self.MarketOnCloseOrder(symbol_bear_put, -1) if len(contracts_bear_call) == 0: return symbol_bear_call = contracts_bear_call[0].Symbol self.MarketOrder(symbol_bear_call, -weight_bear) #self.MarketOnCloseOrder(symbol_bear_call, 1) def OnOrderEvent(self, orderEvent): self.Log(str(orderEvent)) # def Rebalance(self): # calendar = self.TradingCalendar.GetDaysByType(TradingDayType.OptionExpiration, self.Time, self.EndDate) # expiries = [i.Date for i in calendar] # if len(expiries) == 0: return # self.lastest_expiry = expiries[0] # if (self.lastest_expiry - self.Time).days <= 5: # self.SetHoldings("OEF", 1)