Overall Statistics |
Total Trades 12 Average Win 2.45% Average Loss -0.21% Compounding Annual Return 209.621% Drawdown 37.500% Expectancy 1.119 Net Profit 136.003% Sharpe Ratio 2.088 Loss Rate 83% Win Rate 17% Profit-Loss Ratio 11.72 Alpha -0.009 Beta 0.939 Annual Standard Deviation 0.618 Annual Variance 0.382 Information Ratio -2.135 Tracking Error 0.044 Treynor Ratio 1.376 Total Fees $10.21 |
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 from decimal import Decimal from functools import reduce import QuantConnect.Securities.Option import QuantConnect.Securities.Equity from QuantConnect.Securities.Option import OptionHolding from QuantConnect.Securities.Equity import EquityHolding class GaboOptionsIssues04(QCAlgorithm): def Initialize(self): # self.SetStartDate(2016, 3, 27) # self.SetEndDate(2016, 4, 5) self.SetStartDate(2012, 1, 1) self.SetEndDate(2018, 1, 1) self.SetCash(100000) self.option = self.AddOption("SVXY") self.equity = self.AddEquity("SVXY", Resolution.Minute) self.slice = None # set our strike/expiry filter for this option chain self.option.SetFilter(-100, +0, timedelta(14), timedelta(40)) # use the underlying equity as the benchmark self.SetBenchmark("SVXY") self.Schedule.On( self.DateRules.EveryDay(self.option.Symbol.Value), self.TimeRules.AfterMarketOpen( self.option.Symbol.Value, 200), Action(self.buy_underlying) ) self.Schedule.On( self.DateRules.MonthStart(self.option.Symbol.Value), self.TimeRules.BeforeMarketClose( self.option.Symbol.Value, 40), Action(self.buy_option) ) def buy_underlying(self): if not self.Securities[self.equity.Symbol.Value].Invested: buy_pct = 0.95 self.Log('Buying %f%% of %s' % (buy_pct, self.equity.Symbol.Value)) self.SetHoldings(self.equity.Symbol.Value, buy_pct) return def buy_option(self): self.Log('On buy_option method') underlaying_chains = list(filter( lambda chain: chain.Key.Underlying == self.equity.Symbol, self.slice.OptionChains, )) if len(underlaying_chains) == 0: self.Log('No option contract for underlying %s.' % self.equity.Symbol.Value) return underlying_chain = underlaying_chains[0].Value # Keep only the puts puts = list(filter( lambda opt: opt.Right == OptionRight.Put, underlying_chain, )) # Compute the min and max strike price underlying_price = self.equity.Price min_strike = underlying_price * Decimal(.8) max_strike = underlying_price * Decimal(.9) # Keep the option between the threshold strikes opt_in_strike = list(filter( lambda opt: opt.Strike >= min_strike and \ opt.Strike <= max_strike, puts, )) # Filter options without volume opt_volume = list(filter( lambda opt: opt.Volume > 0, opt_in_strike, )) # Sort by priority priority_contracts = sorted( opt_volume, key=lambda opt: opt.Volume, reverse=True, ) if len(priority_contracts) == 0: self.Log('No option volume') return contract = priority_contracts[0] qty = 1 self.Log('Buy %d lot of %s' % (qty, contract.Symbol.Value)) self.MarketOrder(contract.Symbol, qty) def OnData(self, slice): self.slice = slice