Overall Statistics
Total Trades
968
Average Win
0.65%
Average Loss
-0.73%
Compounding Annual Return
-97.541%
Drawdown
78.400%
Expectancy
-0.307
Net Profit
-71.229%
Sharpe Ratio
-0.719
Probabilistic Sharpe Ratio
3.771%
Loss Rate
63%
Win Rate
37%
Profit-Loss Ratio
0.88
Alpha
-1.126
Beta
2.15
Annual Standard Deviation
1.181
Annual Variance
1.394
Information Ratio
-0.852
Tracking Error
1.147
Treynor Ratio
-0.395
Total Fees
$1998.00
Estimated Strategy Capacity
$4000000.00
Lowest Capacity Asset
CL JL
class ContinuousFutureRegressionAlgorithm(QCAlgorithm):
    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
        self.SetCash(100000)
        self.SetStartDate(2020, 9, 1)
        self.SetEndDate(2021, 1, 1)

        self._lastDateLog = -1
        self._continuousContract = self.AddFuture(Futures.Energies.CrudeOilWTI,
                                                  dataNormalizationMode = DataNormalizationMode.BackwardsRatio,
                                                  dataMappingMode = DataMappingMode.OpenInterest,
                                                  contractDepthOffset = 0)
        self.slow_sma = self.SMA(self._continuousContract.Symbol, 50, Resolution.Hour)
        self.fast_sma = self.SMA(self._continuousContract.Symbol, 200, Resolution.Hour)
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Midnight, self.PlotPrices);

        self.SetWarmUp(200, Resolution.Hour)


    def PlotPrices(self):
        if self._continuousContract.HasData:
            self.Plot(self._continuousContract.Symbol.ID.Symbol, self._continuousContract.Symbol.ID.Symbol, self._continuousContract.Price)
            self.Plot(self._continuousContract.Symbol.ID.Symbol, "Slow", self.slow_sma.Current.Value)
            self.Plot(self._continuousContract.Symbol.ID.Symbol, "Fast", self.fast_sma.Current.Value)
            

    def OnData(self, data):
        if self.IsWarmingUp: return 

        for changedEvent in data.SymbolChangedEvents.Values:
            if changedEvent.Symbol == self._continuousContract.Symbol:
                self.Log(f"SymbolChanged event: {changedEvent}")

        if self.fast_sma > self.slow_sma:
            self.SetHoldings(self._continuousContract.Symbol, 1)

        else:
            if self.fast_sma < self.slow_sma:
                self.SetHoldings(self._continuousContract.Symbol, -1)     


        if self._lastDateLog != self.Time.month:
            self._lastDateLog = self.Time.month
            response = self.History( [ self._continuousContract.Symbol ], 60 * 24 * 90)
            if response.empty:
                raise ValueError("Unexpected empty history response")


    def OnOrderEvent(self, orderEvent):
        if orderEvent.Status == OrderStatus.Filled:
            self.Debug("Purchased Stock: {0}".format(orderEvent.Symbol))