Overall Statistics
# region imports
from AlgorithmImports import *
# endregion

class OptionIndicatorAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2022, 11, 5)
        self.option = self.add_option("spy").symbol

    def on_securities_changed(self, changes):
        for security in [x for x in changes.added_securities if x.type == SecurityType.OPTION]:
            if security.cache.properties.contains_key('iv'):
                continue
            symbol = security.symbol
            right = OptionRight.CALL if symbol.id.option_right == OptionRight.PUT else OptionRight.PUT

            mirror_symbol = Symbol.create_option(symbol.id.underlying.symbol, symbol.id.market, symbol.id.option_style, right, symbol.id.strike_price, symbol.id.date)
            ##
            security.iv = self.iv(symbol, mirror_symbol, resolution=Resolution.MINUTE, dividend_yield=0.1)

        #The option indicators accept a fixed dividend yield value. The mean dividend yield for SPY (proxy to SPX) was 0.1 in the last five years.
            security.d = self.d(symbol, mirror_symbol, resolution=Resolution.MINUTE)
            security.g = self.g(symbol, mirror_symbol, resolution=Resolution.MINUTE)
            security.v = self.v(symbol, mirror_symbol, resolution=Resolution.MINUTE)
            security.r = self.r(symbol, mirror_symbol, resolution=Resolution.MINUTE)
            security.t = self.t(symbol, mirror_symbol, resolution=Resolution.MINUTE)
            
    def on_data(self, slice: Slice):
        if self.portfolio.invested:
            if self.portfolio[self.option.underlying].invested:
                self.liquidate()
            return
        chain = slice.option_chains.get(self.option)
        if chain:
            # select the contract with the hightest implied volatility
            contract = sorted([x for x in chain],
                key=lambda x: self.securities[x.symbol].iv.current.value, reverse=True)[0]
            option = self.securities[contract.symbol]
            iv = option.iv.current.value
            delta = option.d.current.value
            gamma = option.g.current.value
            vega = option.v.current.value
            rho = option.r.current.value
            theta = option.t.current.value
            self.market_order(contract.symbol, 1, tag=f"IV = {iv:.2f}, Delta = {delta:.2f}, Gamma = {gamma:.2f}, Vega = {vega:.2f}, Rho = {rho:.2f}, Theta = {theta:.2f}")