Overall Statistics |
Total Trades 1364 Average Win 30.63% Average Loss -0.43% Compounding Annual Return -71.921% Drawdown 88.200% Expectancy -0.681 Net Profit -88.092% Sharpe Ratio -0.98 Probabilistic Sharpe Ratio 0.007% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 71.54 Alpha -0.636 Beta 0.603 Annual Standard Deviation 0.53 Annual Variance 0.281 Information Ratio -1.37 Tracking Error 0.52 Treynor Ratio -0.861 Total Fees $2523.40 Estimated Strategy Capacity $83000000.00 Lowest Capacity Asset ES XMXYBDF3IXHD |
from AlgorithmImports import * class ContinuousFutureRegressionAlgorithm(QCAlgorithm): '''Basic template algorithm simply initializes the date range and cash''' 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.SetStartDate(2020, 1, 1) self.SetEndDate(2022, 5, 1) self._mappings = [] self._lastDateLog = -1 self._continuousContract = self.AddFuture(Futures.Indices.SP500EMini, Resolution.Minute, dataNormalizationMode = DataNormalizationMode.BackwardsRatio, dataMappingMode = DataMappingMode.LastTradingDay, # change to openinterest contractDepthOffset= 0) self._currentMappedSymbol = self._continuousContract.Symbol self.indicators = { 'sma': self.SMA(self._continuousContract.Symbol, 11, Resolution.Minute), 'ema': self.EMA(self._continuousContract.Symbol, 60, Resolution.Minute), # 'atr': AverageTrueRange(14) } self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(13, 0), self.StartOfDay) # set to 13:00 self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 0), self.EndOfDay) self.TradingTime = False def StartOfDay(self): self.TradingTime = True def EndOfDay(self): self.TradingTime = False # if self.Portfolio.Invested: # self.Liquidate(tag='Liquidate all') def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' if len(data.Keys) != 1: raise ValueError(f"We are getting data for more than one symbols! {','.join(data.Keys)}") for changedEvent in data.SymbolChangedEvents.Values: if changedEvent.Symbol == self._continuousContract.Symbol: self._mappings.append(str(changedEvent)) self.Log(f"SymbolChanged event: {changedEvent}") if self._currentMappedSymbol == self._continuousContract.Mapped: raise ValueError(f"Continuous contract current symbol did not change! {self._continuousContract.Mapped}") self.Liquidate(self.Securities[self._currentMappedSymbol].Symbol, tag='Switching Symbol') self._currentMappedSymbol = self._continuousContract.Mapped contract = self.Securities[self._continuousContract.Mapped] if not contract.HasData: return # bar = data[self._continuousContract.Mapped.Symbol] # bar = data[self._continuousContract.Mapped] # bar = data[contract] # bar = data[contract.Symbol] # bar = data.bar[contract.Symbol] open_orders = self.Transactions.GetOpenOrders(contract.Symbol) if self.indicators['sma'].Current.Value > self.indicators['ema'].Current.Value: if not self.Portfolio.Invested and len(open_orders) == 0 and self.TradingTime: quantity = 1 # make quantity dynamic ? self.entryPrice = contract.BidPrice + 1 self.entryTicket = self.StopMarketOrder(contract.Symbol, quantity, self.entryPrice) def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: return contract = self.Securities[self._continuousContract.Mapped] if self.entryTicket is not None and self.entryTicket.OrderId == orderEvent.OrderId: quantity = self.Portfolio[contract.Symbol].Quantity # stopPrice = self.entryPrice - 1 # self.entryTicket.AverageFillPrice - 1 stop_price = self.entryTicket.AverageFillPrice - 2 self.stopTicket = self.StopMarketOrder(contract.Symbol, -quantity, stop_price, 'Exit by SL') def OnSecuritiesChanged(self, changes): self.Debug(f"{self.Time}-{changes}") def OnEndOfAlgorithm(self): self.Debug(f'mappings={self._mappings}')