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