Overall Statistics
Total Trades
5520
Average Win
0.40%
Average Loss
-0.70%
Compounding Annual Return
-96.258%
Drawdown
99.000%
Expectancy
-0.154
Net Profit
-96.292%
Sharpe Ratio
-0.305
Probabilistic Sharpe Ratio
4.632%
Loss Rate
46%
Win Rate
54%
Profit-Loss Ratio
0.58
Alpha
-0.84
Beta
1.466
Annual Standard Deviation
1.731
Annual Variance
2.997
Information Ratio
-0.429
Tracking Error
1.725
Treynor Ratio
-0.36
Total Fees
$11088.90
Estimated Strategy Capacity
$160000000.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(2019, 1, 1)
        self.SetEndDate(2020, 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, 20, Resolution.Daily)
        self.fast_sma = self.SMA(self._continuousContract.Symbol, 5, Resolution.Daily)
        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Midnight, self.PlotPrices);

        self.SetWarmUp(20, Resolution.Daily)


    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))