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
-6.593
Tracking Error
0.034
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, 28)
        self.SetEndDate(2020, 1, 30)
        self.SetCash(100000)

        # Requesting data
        gold_futures = self.AddFuture(Futures.Metals.Gold, Resolution.Daily)
        gold_futures.SetFilter(20, 60)
        self.AddFutureOption(gold_futures.Symbol, lambda universe: universe.Strikes(-2, +2)
                                                                           .CallsOnly()
                                                                           .Expiration(20,60)
                                                                           )
        
        #.OnlyApplyFilterAtMarketOpen()
    def OnData(self, slice: Slice):
        for kvp in slice.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)
                #self.Debug(f"IV: {option_contract_by_underlying_future_contract.ImpliedVolatility} Strike: {option_contract_by_underlying_future_contract.Strike} Underlying: {option_contract_by_underlying_future_contract.UnderlyingLastPrice} Expo: {option_contract_by_underlying_future_contract.Expiry} Date: {slice.Time}")
            
            chain = kvp.Value
            chain = [contract for contract in chain if self.Securities[contract.Symbol].IsTradable]
            
            # 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:
                contract = sorted(sorted(chain, key = lambda x: x.Strike), key = lambda x: x.Expiry, reverse=False)[0]
                self.Debug(f"IV: {contract.ImpliedVolatility} Strike: {contract.Strike} Underlying: {contract.UnderlyingLastPrice} Expo: {contract.Expiry} Date: {slice.Time}")
                continue

            # Select the Option contract with the lowest strike price
            contract = sorted(sorted(chain, key = lambda x: x.Strike), key = lambda x: x.Expiry, reverse=False)[0]

            
            self.MarketOrder(contract.Symbol, 1)
            self.option_contract_by_underlying_future_contract[kvp.Key.Underlying] = contract
            self.Debug(f"IV: {contract.ImpliedVolatility} Strike: {contract.Strike} Underlying: {contract.UnderlyingLastPrice} Expo: {contract.Expiry} Date: {slice.Time}")
        
        
    def OnSecuritiesChanged(self, changes: SecurityChanges):
        for security in changes.AddedSecurities:
            if security.Type == SecurityType.FutureOption:
                # Historical data
                history = self.History(security.Symbol, 10, Resolution.Daily)
                #self.Debug(f"We got {len(history)} from our history request for {security.Symbol}")