Overall Statistics
Total Trades
73
Average Win
0%
Average Loss
0%
Compounding Annual Return
4717.525%
Drawdown
9.900%
Expectancy
0
Net Profit
11.200%
Sharpe Ratio
84.456
Probabilistic Sharpe Ratio
77.340%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
70.779
Beta
3.566
Annual Standard Deviation
0.918
Annual Variance
0.843
Information Ratio
87.273
Tracking Error
0.867
Treynor Ratio
21.744
Total Fees
$135.05
Estimated Strategy Capacity
$680000.00
from datetime import timedelta

from QuantConnect.Algorithm import *
from QuantConnect.Data import *
from QuantConnect import *


class WTICrudeOilFuturesOptionsUniverseAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2020, 5, 1)
        self.SetEndDate(2020, 5, 10)
        self.SetCash(1000000)

        # METHOD 1 (recommended) -- using universes
        # ---------------------------
        # We need to add the future first. We can configure it afterwards,
        # and then we use it to add futures options.
        cl = self.AddFuture("CL", Resolution.Minute, Market.NYMEX)
        # We want only contracts with more than 10 days until expiry 
        # and a maximum of 120 days until expiry
        cl.SetFilter(timedelta(days=10), timedelta(days=120))

        # Adds Futures options contracts for CL with the matching filter below,
        # for all futures contracts that match the filter set above.
        #
        # We only include futures options that are 5 away from the strike price
        # closest to the price of the asset, which means we will
        # have 5 ITM contracts, and 5 OTM contracts for both calls and puts,
        # giving us 20 futures options contract per futures contract
        #
        # We use `cl.Symbol` to add CL futures options here, because Lean
        # identifies assets based on their `Symbol`. 
        #
        # To read more on Symbols and how they work, visit: 
        # https://www.quantconnect.com/docs/key-concepts/security-identifiers
        self.AddFutureOption(cl.Symbol, self.FilterFutureOptionContract)

    def FilterFutureOptionContract(self, filterUniverse):
        return filterUniverse.Strikes(-5, +5)

    def OnData(self, data):
        if self.Portfolio.Invested:
            return

        # Loop through all futures options contracts that were loaded.
        # We long calls, and short the puts that were loaded.
        for chain in data.OptionChains.Values:
            for contract in chain.Contracts.Values:
                # The contract's strike, right, and style can all be accessed
                # from the `Symbol` object as well, if you don't have access
                # to the `OptionContract` object. 
                #
                #   strike: contract.Symbol.ID.StrikePrice
                #   right:  contract.Symbol.ID.OptionRight
                #   style:  contract.Symbol.ID.OptionStyle
                #
                if contract.Right == OptionRight.Call:
                    # Buy 1 CL call contract
                    self.MarketOrder(contract.Symbol, 1)
                else:
                    # Short 1 CL put contract
                    self.MarketOrder(contract.Symbol, -1)