| Overall Statistics |
|
Total Trades 15 Average Win 0% Average Loss -0.10% Compounding Annual Return 71.027% Drawdown 3.400% Expectancy -1 Net Profit 2.839% Sharpe Ratio 3.495 Probabilistic Sharpe Ratio 69.550% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha 0.052 Beta 1.433 Annual Standard Deviation 0.141 Annual Variance 0.02 Information Ratio 1.606 Tracking Error 0.116 Treynor Ratio 0.345 Total Fees $118.92 Estimated Strategy Capacity $190000.00 Lowest Capacity Asset QQQ XTN6URUB74XY|QQQ RIWIV7K5Z9LX Portfolio Turnover 13.25% |
# region imports
from AlgorithmImports import *
# endregion
class FormalBlackAnguilline(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 11, 1) # Set Start Date
self.SetEndDate(2021, 11, 19) # Set End Date
self.SetCash(2000000) # Set Strategy Cash
equity = self.AddEquity("QQQ",Resolution.Daily) # Add the underlying stock: Google
option = self.AddOption("QQQ",Resolution.Daily) # Add the option corresponding to underlying stock
self.symbol = option.Symbol
self.stock = equity.Symbol
option.SetFilter(-6,-6, timedelta(0), timedelta(25))
self.trade = 1
self.contract = None
self.size = 203
self.sign = -1
def OnData(self, slice: Slice) -> None:
# Buy and sell on first day
if self.trade == 1:
chain = slice.OptionChains.get(self.symbol)
if chain:
self.Debug(f"underlying price: {chain.Underlying.Price}")
self.contract = [x for x in chain if x.Expiry==DateTime(2021,11,19) and x.Right == 0][0]
self.Debug(str(self.Time)+" "+str(self.contract.Strike))
# Calculate volatility of the security
daily_returns = self.History(self.stock, 25, Resolution.Daily)['close'].pct_change()[1:]
self.sign = -1
volatility = daily_returns.std()*365**0.5
self.Debug(str(volatility)+" "+str(self.contract.ImpliedVolatility))
# Compare Actual and Implied Vol, actual>inplied, long option and vice versa
if volatility > self.contract.ImpliedVolatility:
self.sign = 1
self.trade+=1
self.size=self.size*self.sign
# Place Order
self.MarketOrder(self.contract.Symbol, self.size)
self.MarketOrder(self.stock,-100*self.size*self.contract.Greeks.Delta)
self.previous = self.contract.Greeks.Delta
# region imports
from AlgorithmImports import *
# endregion
class FormalBlackAnguilline(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 11, 1) # Set Start Date
self.SetEndDate(2021, 11, 19) # Set End Date
self.SetCash(2000000) # Set Strategy Cash
equity = self.AddEquity("QQQ",Resolution.Daily) # Add the underlying stock: Google
option = self.AddOption("QQQ",Resolution.Daily) # Add the option corresponding to underlying stock
self.symbol = option.Symbol
self.stock = equity.Symbol
option.SetFilter(timedelta(0), timedelta(25))
self.trade = 1
self.contract = None
self.size = 120
self.sign = -1
def OnData(self, slice: Slice) -> None:
# Buy and sell on first day
if self.trade == 1:
chain = slice.OptionChains.get(self.symbol)
if chain:
#self.Debug(f"underlying price: {chain.Underlying.Price}")
contract_list = [x for x in chain if x.Expiry==DateTime(2021,11,19) and x.Right == 0 and x.Strike>x.UnderlyingLastPrice]
self.lowest_call = sorted(contract_list, key= lambda x: x.Strike)[0].Strike
self.contract = [contract for contract in contract_list if contract.Strike == self.lowest_call][0]
# Calculate volatility of the security
daily_returns = self.History(self.stock, 25, Resolution.Daily)['close'].pct_change()[1:]
self.sign = -1
volatility = daily_returns.std()*365**0.5
#self.Debug(str(volatility)+" "+str(self.contract.ImpliedVolatility))
# Compare Actual and Implied Vol, actual>inplied, long option and vice versa
if volatility > self.contract.ImpliedVolatility:
self.sign = 1
self.trade+=1
self.size=self.size*self.sign
# Place Order
self.MarketOrder(self.contract.Symbol, self.size)
self.MarketOrder(self.stock,-100*self.size*self.contract.Greeks.Delta)
self.Debug(str(self.contract.Greeks.Delta))
self.previous = self.contract.Greeks.Delta
else:
chain = slice.OptionChains.get(self.symbol)
if chain:
contract_list = [x for x in chain if x.Expiry==DateTime(2021,11,19) and x.Right == 0 and x.Strike>x.UnderlyingLastPrice]
self.lowest_call = sorted(contract_list, key= lambda x: x.Strike)[0].Strike
self.contract = [contract for contract in contract_list if contract.Strike == self.lowest_call][0]
self.MarketOrder(self.stock,-100*self.size*(self.contract.Greeks.Delta-self.previous))
self.previous = self.contract.Greeks.Delta# region imports
from AlgorithmImports import *
# endregion
class FormalBlackAnguilline(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 10, 14)
self.SetEndDate(2022, 10, 14)
self.SetCash(100000) # Set Strategy Cash
aapl = self.AddEquity("AAPL", Resolution.Hour)
VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30, Resolution.Hour)
self.symbol = aapl.Symbol
contracts = [
Symbol.CreateOption(self.symbol, Market.USA, OptionStyle.American, OptionRight.Call, 145, datetime(2022, 11, 18)),
#Symbol.CreateOption(self.symbol, Market.USA, OptionStyle.American, OptionRight.Call, 377, datetime(2022, 10, 5))
]
for contract in contracts:
option = self.AddOptionContract(contract, Resolution.Hour)
option.PriceModel = OptionPriceModels.BjerksundStensland()
self.SetWarmUp(31)
self.df = pd.DataFrame()
def OnData(self, data: Slice):
if self.IsWarmingUp: return
equity = self.Securities[self.symbol]
for canonical_symbol, chain in data.OptionChains.items():
for contract in chain:
greeks = contract.Greeks
data = {
"IV" : contract.ImpliedVolatility,
"Delta": greeks.Delta,
"Gamma": greeks.Gamma,
"Vega": greeks.Vega,
"Rho": greeks.Rho,
"Theta": greeks.Theta,
"LastPrice": contract.LastPrice,
"Close": self.Securities[contract.Symbol].Close,
"theoreticalPrice" : contract.TheoreticalPrice,
"underlyingPrice": equity.Close,
"underlyingVolatility": equity.VolatilityModel.Volatility
}
symbol = contract.Symbol
right = "Put" if symbol.ID.OptionRight == 1 else "Call"
index = pd.MultiIndex.from_tuples([(symbol.ID.Date, symbol.ID.StrikePrice, right, symbol.Value, self.Time)], names=["expiry", "strike", "type", "symbol", "endTime"])
self.df = pd.concat([self.df, pd.DataFrame(data, index=index)])
self.Debug( " Time: " + str(self.Time) + " Implied Vol: "+str(data["IV"])+" Price: "+str(data["Close"]))
def OnEndOfAlgorithm(self):
pass
#self.ObjectStore.Save("price-models/backtest-df", self.df.sort_index().to_csv())
# region imports
from AlgorithmImports import *
# endregion
class FormalBlackAnguilline(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 10, 17)
self.SetEndDate(2022, 10, 17)
self.SetCash(100000) # Set Strategy Cash
aapl = self.AddEquity("AAPL", Resolution.Hour)
VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30, Resolution.Hour)
self.symbol = aapl.Symbol
contracts = [
#Symbol.CreateOption(self.symbol, Market.USA, OptionStyle.American, OptionRight.Call, 145, datetime(2022, 11, 18)),
Symbol.CreateOption(self.symbol, Market.USA, OptionStyle.American, OptionRight.Put, 130, datetime(2022, 11, 11))
]
for contract in contracts:
option = self.AddOptionContract(contract, Resolution.Hour)
option.PriceModel = OptionPriceModels.BjerksundStensland()
self.SetWarmUp(31)
self.df = pd.DataFrame()
def OnData(self, data: Slice):
if self.IsWarmingUp: return
equity = self.Securities[self.symbol]
for canonical_symbol, chain in data.OptionChains.items():
for contract in chain:
greeks = contract.Greeks
data = {
"IV" : contract.ImpliedVolatility,
"Delta": greeks.Delta,
"Gamma": greeks.Gamma,
"Vega": greeks.Vega,
"Rho": greeks.Rho,
"Theta": greeks.Theta,
"LastPrice": contract.LastPrice,
"Close": self.Securities[contract.Symbol].Close,
"theoreticalPrice" : contract.TheoreticalPrice,
"underlyingPrice": equity.Close,
"underlyingVolatility": equity.VolatilityModel.Volatility
}
symbol = contract.Symbol
right = "Put" if symbol.ID.OptionRight == 1 else "Call"
index = pd.MultiIndex.from_tuples([(symbol.ID.Date, symbol.ID.StrikePrice, right, symbol.Value, self.Time)], names=["expiry", "strike", "type", "symbol", "endTime"])
self.df = pd.concat([self.df, pd.DataFrame(data, index=index)])
self.Debug( " Time: " + str(self.Time) + " Implied Vol: "+str(data["IV"])+" Price: "+str(data["Close"]))
def OnEndOfAlgorithm(self):
pass
#self.ObjectStore.Save("price-models/backtest-df", self.df.sort_index().to_csv())
# region imports
from AlgorithmImports import *
# endregion
class FormalBlackAnguilline(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 11, 1) # Set Start Date
self.SetEndDate(2021, 11, 19) # Set End Date
self.SetCash(2000000) # Set Strategy Cash
equity = self.AddEquity("QQQ",Resolution.Daily) # Add the underlying stock: Google
option = self.AddOption("QQQ",Resolution.Daily) # Add the option corresponding to underlying stock
self.symbol = option.Symbol
self.stock = equity.Symbol
option.SetFilter(timedelta(0), timedelta(25))
self.trade = 1
self.contract = None
self.size = 203
self.sign = -1
def OnData(self, slice: Slice) -> None:
# Buy and sell on first day
if self.trade == 1:
chain = slice.OptionChains.get(self.symbol)
if chain:
#self.Debug(f"underlying price: {chain.Underlying.Price}")
contract_list = [x for x in chain if x.Expiry==DateTime(2021,11,19) and x.Right == 0 and x.Strike>x.UnderlyingLastPrice]
self.lowest_call = sorted(contract_list, key= lambda x: x.Strike)[0].Strike
self.contract = [contract for contract in contract_list if contract.Strike == self.lowest_call][0]
# Calculate volatility of the security
daily_returns = self.History(self.stock, 25, Resolution.Daily)['close'].pct_change()[1:]
self.sign = -1
volatility = daily_returns.std()*365**0.5
#self.Debug(str(volatility)+" "+str(self.contract.ImpliedVolatility))
# Compare Actual and Implied Vol, actual>inplied, long option and vice versa
if volatility > self.contract.ImpliedVolatility:
self.sign = 1
self.trade+=1
self.size=self.size*self.sign
# Place Order
self.MarketOrder(self.contract.Symbol, self.size)
self.MarketOrder(self.stock,-100*self.size*self.contract.Greeks.Delta)
self.Debug(str(self.contract.Greeks.Delta))
self.previous = self.contract.Greeks.Delta
else:
chain = slice.OptionChains.get(self.symbol)
if chain:
contract_list = [x for x in chain if x.Expiry==DateTime(2021,11,19) and x.Right == 0 and x.Strike>x.UnderlyingLastPrice]
self.lowest_call = sorted(contract_list, key= lambda x: x.Strike)[0].Strike
self.contract = [contract for contract in contract_list if contract.Strike == self.lowest_call][0]
self.MarketOrder(self.stock,-100*self.size*(self.contract.Greeks.Delta-self.previous))
self.previous = self.contract.Greeks.Delta# region imports
from AlgorithmImports import *
# endregion
class FormalBlackAnguilline(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 10, 17) # Set Start Date
self.SetEndDate(2022, 10, 17) # Set End Date
self.SetCash(50000) # Set Strategy Cash
equity = self.AddEquity("AAPL",Resolution.Hour) # Add the underlying stock: Google
option = self.AddOption("AAPL",Resolution.Hour) # Add the option corresponding to underlying stock
self.symbol = option.Symbol
option.SetFilter( timedelta(58), timedelta(62))
def OnData(self, slice: Slice) -> None:
chain = slice.OptionChains.get(self.symbol)
if chain:
self.Log(f"underlying price: {chain.Underlying.Price}")
data=[[x.Strike,x.ImpliedVolatility] for x in chain if (x.Strike==125 or x.Strike == 130) and x.Expiry==DateTime(2022,12,16) and x.Right == 1]
self.Debug("Time: "+str(self.Time)+" Strike: "+str(13/20*data[1][0]+7/20*data[0][0])+" Implied Vol: "+str(13/20*data[1][1]+7/20*data[0][1]))