Overall Statistics
Total Orders
2
Average Win
0.05%
Average Loss
0%
Compounding Annual Return
0.165%
Drawdown
1.700%
Expectancy
0
Start Equity
1000000
End Equity
1000495.06
Net Profit
0.050%
Sharpe Ratio
-2.386
Sortino Ratio
-2.995
Probabilistic Sharpe Ratio
27.096%
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
-0.052
Beta
0.035
Annual Standard Deviation
0.019
Annual Variance
0
Information Ratio
-1.629
Tracking Error
0.127
Treynor Ratio
-1.315
Total Fees
$4.94
Estimated Strategy Capacity
$1500000000.00
Lowest Capacity Asset
CL Y7S8YM5PTSJL
Portfolio Turnover
0.15%
from AlgorithmImports import *

class CrudeOil90DayHoldAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2023, 1, 1)
        self.SetEndDate(2023, 4, 20)
        self.SetCash(1_000_000)

        self.future = self.AddFuture(Futures.Energies.CrudeOilWTI)
        self.future.SetFilter(timedelta(85), timedelta(95))

        self.contractSymbol = None
        self.exitDate = None
        self.done = False

    def OnData(self, slice: Slice):
        if not self.done and self.contractSymbol is None and slice.FutureChains:
            chain = next(iter(slice.FutureChains.Values), None)
            if chain:
                contract = next(
                    (c for c in sorted(chain.Contracts.Values, key=lambda x: x.Expiry)
                     if c.Expiry > self.Time + timedelta(90)),
                    None
                )
                if contract:
                    self.MarketOrder(contract.Symbol, 1)
                    self.contractSymbol = contract.Symbol
                    self.exitDate = self.Time + timedelta(90)

        if self.contractSymbol and self.Time >= self.exitDate:
            self.Liquidate(self.contractSymbol)
            self.contractSymbol = None
            self.done = True