| Overall Statistics |
|
Total Trades 223 Average Win 0.47% Average Loss -0.90% Compounding Annual Return 4.201% Drawdown 27.600% Expectancy 0.425 Net Profit 50.959% Sharpe Ratio 0.371 Probabilistic Sharpe Ratio 1.854% Loss Rate 6% Win Rate 94% Profit-Loss Ratio 0.52 Alpha 0.051 Beta 0.003 Annual Standard Deviation 0.134 Annual Variance 0.018 Information Ratio 0.845 Tracking Error 0.586 Treynor Ratio 14.487 Total Fees $18702.00 |
from QuantConnect.Securities.Option import OptionPriceModels
from datetime import timedelta
class HorizontalDynamicCoil(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2011, 1, 1) # Set Start Date
self.SetCash(1000000) # Set Strategy Cash
self.SQQQOption = self.AddOption("SQQQ")
self.SQQQOption.PriceModel = OptionPriceModels.CrankNicolsonFD()
self.SQQQOption.SetFilter(-50, 0, timedelta(8), timedelta(15))
self.SQQQOption.SetLeverage(100)
# self.TMVOption = self.AddOption("TMV")
# self.TMVOption.PriceModel = OptionPriceModels.CrankNicolsonFD()
# self.TMVOption.SetFilter(-50, 0, timedelta(5), timedelta(15))
self.LongOption = self.ShortOption = False
self.NumContracts = 0
self.SetBenchmark('SQQQ')
self.long_delta = float(self.GetParameter("long_delta"))
self.short_delta = float(self.GetParameter("short_delta"))
self.DefaultOrderProperties.TimeInForce = TimeInForce.Day
def OnData(self, data):
if self.Time.hour == 15 and self.Time.minute == 30:
option_invested = [x for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
equity_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type!=SecurityType.Option]
if len(equity_invested) > 0:
self.Debug(equity_invested[0])
self.Liquidate(equity_invested[0])
if len(option_invested) < 2:
self.LongOption = self.ShortOption = False
for option in option_invested:
if int(option.Value.IsLong) == 1:
if (option.Key.ID.Date - self.Time).days < 128:
self.Debug(f'Closed {-option.Value.Quantity} contracts Strike {option.Key.ID.StrikePrice} Underlying {self.Securities[option.Key.ID.Underlying.Symbol].Price} {self.Time}')
self.MarketOrder(option.Key, -option.Value.Quantity)
else:
self.LongOption = True
elif int(option.Value.IsLong) == 0:
if (option.Key.ID.Date - self.Time).days < 1 and (option.Key.ID.StrikePrice > self.Securities[option.Key.ID.Underlying.Symbol].Price):
self.Debug(f'Closed {-option.Value.Quantity} contracts Strike {option.Key.ID.StrikePrice} Underlying {self.Securities[option.Key.ID.Underlying.Symbol].Price} {self.Time}')
self.MarketOrder(option.Key, -option.Value.Quantity)
else:
self.ShortOption = True
if self.ShortOption is False:
self.ShortOptions(data)
# if self.LongOption is False:
# self.LongOptions(data)
# self.CalendarSpread(data)
# self.LongOptions(data)
def CalendarSpread(self, data):
for i in data.OptionChains:
chain = i.Value
# filter the call options contracts
puts = [x for x in chain if x.Right == OptionRight.Put]
if self.LongOption is False:
long_contract = sorted(sorted(puts,
key = lambda x: abs(x.Greeks.Delta - self.long_delta)),
key = lambda x: x.Expiry, reverse=True)[0]
if abs(long_contract.Greeks.Delta - self.long_delta) < 0.1:
mid_price = (long_contract.AskPrice + long_contract.BidPrice) / 2
self.NumContracts = int(100000 / 100.0 / mid_price)
self.MarketOrder(long_contract.Symbol, self.NumContracts)
self.Debug(f'Num contracts {self.NumContracts} Mid Price {mid_price:.2f} Strike {long_contract.Strike} Underlying {long_contract.UnderlyingLastPrice} Delta {long_contract.Greeks.Delta} TTE {long_contract.Expiry - self.Time} Expiry {long_contract.Expiry}')
if self.ShortOption is False:
short_contract = sorted(sorted(puts,
key = lambda x: abs(x.Greeks.Delta - self.short_delta)),
key = lambda x: x.Expiry)[0]
if (short_contract.Expiry - self.Time).days <= 7 and abs(short_contract.Greeks.Delta - self.short_delta) < 0.049:
self.MarketOrder(short_contract.Symbol, -self.NumContracts)
mid_price = (short_contract.AskPrice + short_contract.BidPrice) / 2
self.Debug(f'Num contracts {self.NumContracts} Mid Price {mid_price:.2f} Strike {short_contract.Strike} Underlying {short_contract.UnderlyingLastPrice} Delta {short_contract.Greeks.Delta} TTE {short_contract.Expiry - self.Time} Expiry {short_contract.Expiry}')
def ShortOptions(self, data):
for i in data.OptionChains:
chain = i.Value
# filter the call options contracts
puts = [x for x in chain if x.Right == OptionRight.Put]
# puts = [put for put in puts ]
# sorted the contracts according to their expiration dates and choose the ATM options
short_contract = sorted(sorted(puts,
key = lambda x: abs(x.Greeks.Delta - self.short_delta)),
# key = lambda x: abs((x.Strike - x.UnderlyingLastPrice) / x.Strike + 0.1)),
key = lambda x: x.Expiry)[0]
TTE = short_contract.Expiry - self.Time
if abs(short_contract.Greeks.Delta - self.short_delta) > 0.049 or TTE.days >= 15: return
# TTE = short_contract.Expiry - self.Time
# if TTE.days >= 8 or TTE.days <= 3: return
mid_price = (short_contract.AskPrice + short_contract.BidPrice) / 2
num_contracts = int(1000000 / 100.0 / short_contract.Strike)
self.Debug(f'Num contracts {num_contracts} Mid Price {mid_price:.2f} Strike {short_contract.Strike} Underlying {short_contract.UnderlyingLastPrice} Delta {short_contract.Greeks.Delta} TTE {TTE} Expiry {short_contract.Expiry}')
# self.LimitOrder(short_contract.Symbol, -num_contracts, mid_price)
self.MarketOrder(short_contract.Symbol, -num_contracts)
def LongOptions(self, data):
for i in data.OptionChains:
chain = i.Value
# filter the call options contracts
puts = [x for x in chain if x.Right == OptionRight.Put]
# sorted the contracts according to their expiration dates and choose the ATM options
long_contract = sorted(sorted(puts,
# key = lambda x: abs((x.Strike - x.UnderlyingLastPrice) / x.Strike + 0.2)),
key = lambda x: abs(x.Greeks.Delta - self.long_delta)),
key = lambda x: x.Expiry, reverse=True)[0]
if abs(long_contract.Greeks.Delta - self.long_delta) > 0.1: return
mid_price = (long_contract.AskPrice + long_contract.BidPrice) / 2
num_contracts = int(100000 / 100.0 / mid_price)
self.Debug(f'Num contracts {num_contracts} Mid Price {mid_price} Strike {long_contract.Strike} Underlying {long_contract.UnderlyingLastPrice} Delta {long_contract.Greeks.Delta} TTE {long_contract.Expiry - self.Time} Expiry {long_contract.Expiry}')
# self.LimitOrder(self.put, -num_contracts, mid_price)
self.MarketOrder(long_contract.Symbol, num_contracts)