Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-0.604
Tracking Error
0.278
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
from AlgorithmImports import *

class FutureOptionDataAlgorithm(QCAlgorithm):
    
    option_contract_by_underlying_future_contract = {}
    
    def Initialize(self):
        self.SetStartDate(2020, 1, 1)
        self.SetEndDate(2020, 12, 31)
        self.SetCash(100000)

        self.SetWarmup(30, Resolution.Daily)
        self.SetSecurityInitializer(self.CustomSecurityInitializer)

        # Requesting data
        gold_futures = self.AddFuture(Futures.Grains.SRWWheat, Resolution.Minute)
        gold_futures.SetVolatilityModel(StandardDeviationOfReturnsVolatilityModel(30))
        gold_futures.SetFilter(0, 180)
        option = self.AddFutureOption(gold_futures.Symbol, lambda universe: universe.Strikes(-5, +5)
                                                                           .Expiration(timedelta(days=0), timedelta(days=180))
                                                                           .OnlyApplyFilterAtMarketOpen())

                                                                           

    def OnData(self, data):

        if self.IsWarmingUp:
            return

        for kvp in data.OptionChains:
            # Liquidate underlying Future contract after Option assignment
            #underlying_future_contract = kvp.Key.Underlying
            #if self.Portfolio[underlying_future_contract].Invested:
            #    self.Liquidate(underlying_future_contract)
            #    self.option_contract_by_underlying_future_contract.pop(underlying_future_contract)
            
            chain = kvp.Value
            chain = [contract for contract in chain if self.Securities[contract.Symbol].IsTradable]
            
            contracts = [x for x in  chain if x.Right == 1 and x.Strike <  x.UnderlyingLastPrice]
            self.Debug(f"{len(contracts)}")
            
            '''

            # Continue if chain is empty or already invested in an Option on this Futures contract
            if not chain or underlying_future_contract in self.option_contract_by_underlying_future_contract:
                continue
            # Select the Option contract with the lowest strike price
            contract = sorted(chain, key = lambda x: x.Strike)[0]

            option = self.AddOptionContract(contract.Symbol)
            option.PriceModel = OptionPriceModels.CrankNicolsonFD()

            self.Debug(f"Delta {contract.Greeks.Delta}")
            self.MarketOrder(contract.Symbol, 1)
            self.option_contract_by_underlying_future_contract[kvp.Key.Underlying] = contract
            '''

    def CustomSecurityInitializer(self, security: Security) -> None:
                
        security.SetMarketPrice(self.GetLastKnownPrice(security))
        if security.Type == SecurityType.FutureOption:
            history = self.History(security.Symbol, 30, Resolution.Daily)
            security.PriceModel = OptionPriceModels.CrankNicolsonFD()
            if security.Underlying != None:
                underlying = self.AddFuture(security.Underlying.Symbol, Resolution.Minute)
                underlying.SetVolatilityModel(StandardDeviationOfReturnsVolatilityModel(30))
                underlying_history = self.History(underlying.Symbol, 30, Resolution.Daily)
 
    def OnSecuritiesChanged(self, changes):
        # when & why to use this? Do I have a universe...
        pass