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