Overall Statistics |
Total Trades 4360 Average Win 0.02% Average Loss -0.04% Compounding Annual Return -1.055% Drawdown 2.000% Expectancy -0.017 Net Profit -1.365% Sharpe Ratio -0.457 Probabilistic Sharpe Ratio 2.159% Loss Rate 39% Win Rate 61% Profit-Loss Ratio 0.61 Alpha 0 Beta 0 Annual Standard Deviation 0.016 Annual Variance 0 Information Ratio -0.457 Tracking Error 0.016 Treynor Ratio 0 Total Fees $9374.00 Estimated Strategy Capacity $33000000.00 Lowest Capacity Asset NQ Y9CDFY0C6TXD Portfolio Turnover 234.54% |
#region imports import pytz from AlgorithmImports import * from datetime import time #endregion class SimpleNQExample(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 1, 1) # Set Start Date self.SetEndDate(2023, 4, 18) self.SetCash(1000000) # Set Strategy Cash self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.SetTimeZone("America/New_York") # Set up the future we're looking at future = Futures.Indices.NASDAQ100EMini self._continuousContract = self.AddFuture(future, dataNormalizationMode = DataNormalizationMode.BackwardsRatio, dataMappingMode = DataMappingMode.OpenInterest, contractDepthOffset = 0, extendedMarketHours = True) self.commod = self._continuousContract.Symbol self._continuousContract.SetFilter(timedelta(days=1), timedelta(days=60)) # Set up a short-period EMA on 1-minute bar qqqequityconsolidator = TradeBarConsolidator(timedelta(minutes = 1)) qqqequityconsolidator.DataConsolidated += self.qqqequityHandler self.qqqema = ExponentialMovingAverage(9) self.RegisterIndicator(self.commod, self.qqqema, qqqequityconsolidator) self.qqqema_past = IndicatorExtensions.Of(Delay(1), self.qqqema) self.qqqema_slope = IndicatorExtensions.Minus(self.qqqema, self.qqqema_past) # Set up a long-period EMA on 1-minute bar self.qqqemalong = ExponentialMovingAverage(150) self.RegisterIndicator(self.commod, self.qqqemalong, qqqequityconsolidator) self.qqqemalong_past = IndicatorExtensions.Of(Delay(1), self.qqqemalong) self.qqqemalong_slope = IndicatorExtensions.Minus(self.qqqemalong, self.qqqemalong_past) # Set up a 14-period RSI on 1-minute bar self.qqqrsi = RelativeStrengthIndex(14) self.RegisterIndicator(self.commod, self.qqqrsi, qqqequityconsolidator) self.sma_qqqrsi = IndicatorExtensions.SMA(self.qqqrsi, 5) self.sma_qqqrsi_past = IndicatorExtensions.Of(Delay(1), self.sma_qqqrsi) self.qqqrsi_slope = IndicatorExtensions.Minus(self.sma_qqqrsi, self.sma_qqqrsi_past) # Set up a Momentum indicator on 1-minute bar self.qqqmomentum = Momentum(9) self.RegisterIndicator(self.commod, self.qqqmomentum, qqqequityconsolidator) self.ema_qqqmom = IndicatorExtensions.EMA(self.qqqmomentum, 3) self.ema_qqqmom_past = IndicatorExtensions.Of(Delay(1), self.ema_qqqmom) self.qqqmom_slope = IndicatorExtensions.Minus(self.ema_qqqmom, self.ema_qqqmom_past) # Set up an Ultimate Oscillator indicator on 1-minute bar self.qqqUA = UltimateOscillator(7, 14, 28) self.RegisterIndicator(self.commod, self.qqqUA, qqqequityconsolidator) self.ema_qqqUA = IndicatorExtensions.EMA(self.qqqUA, 3) self.ema_qqqUA_past = IndicatorExtensions.Of(Delay(1), self.ema_qqqUA) self.qqqUA_slope = IndicatorExtensions.Minus(self.ema_qqqUA, self.ema_qqqUA_past) self.qqqequityslopeshort = dict() self.qqqequityslopeshort[0] = 0 self.emaslopelong = dict() self.emaslopelong[0] = 0 self.qqqslope_rsi = dict() self.qqqslope_rsi[0] = 0 self.qqqslope_mom = dict() self.qqqslope_mom[0] = 0 self.qqqslope_UA = dict() self.qqqslope_UA[0] = 0 self.tradingnumber = dict() self.tradingnumber[0] = 0 def emaUpdated(self, sender, updated): '''Adds updated values to rolling window''' self.emaWin.Add(updated) def qqqequityHandler(self, sender, consolidated): if self.IsWarmingUp or not self.qqqema_slope.IsReady: return self.qqqequityslopeshort[0] = self.qqqema_slope.Current.Value self.emaslopelong[0] = self.qqqemalong_slope.Current.Value self.qqqslope_rsi[0] = self.qqqrsi_slope.Current.Value self.qqqslope_mom[0] = self.qqqmom_slope.Current.Value self.qqqslope_UA[0] = self.qqqUA_slope.Current.Value def OnData(self, data: Slice): if not data.ContainsKey(self.commod): return futures_invested = [holding.Symbol for holding in self.Portfolio.Values if holding.Type == SecurityType.Future and holding.Invested] futures_invested_short = [(symbol, holding.Quantity) for symbol, holding in self.Portfolio.items() if holding.Type == SecurityType.Future and holding.Symbol.SecurityType == SecurityType.Future and holding.IsShort] futures_invested_long = [(symbol, holding.Quantity) for symbol, holding in self.Portfolio.items() if holding.Type == SecurityType.Future and holding.Symbol.SecurityType == SecurityType.Future and holding.IsLong] futures_invested_long1 = [symbol for symbol, holding in self.Portfolio.items() if holding.Type == SecurityType.Future and holding.Symbol.SecurityType == SecurityType.Future and holding.IsLong] futures_invested_short1 = [symbol for symbol, holding in self.Portfolio.items() if holding.Type == SecurityType.Future and holding.Symbol.SecurityType == SecurityType.Future and holding.IsShort] slopelong = self.emaslopelong[0] slopeshort = self.qqqequityslopeshort[0] slope_rsi = self.qqqslope_rsi[0] momslope = self.qqqslope_mom[0] UAslope = self.qqqslope_UA[0] RSI = self.sma_qqqrsi.Current.Value current_time = self.Time.time() trading_start = time(8, 0) trading_end = time(19, 30) #trading_allowed = trading_start <= current_time <= trading_end trading_not_allowed = current_time > trading_end trading_allowed = trading_start <= current_time <= trading_end and self.Time.weekday() != 6 if self.tradingnumber[0] == 0 and RSI < 30: self.tradingnumber[0] = 1 if self.tradingnumber[0] == 0 and RSI > 70: self.tradingnumber[0] = 3 if trading_allowed and self.tradingnumber[0] == 1: if slopeshort > 0 and slope_rsi > 0 and not futures_invested_short1: self.MarketOrder(self._continuousContract.Mapped, -1) self.Log("Going long") self.tradingnumber[0] = 2 if self.tradingnumber[0] == 2 and slopeshort < 0 and slope_rsi < 0: for symbol, quantity in futures_invested_short: self.MarketOrder(symbol, -quantity) self.tradingnumber[0] = 0 if trading_allowed and self.tradingnumber[0] == 3: if slopeshort < 0 and slope_rsi < 0 and not futures_invested_long1: self.MarketOrder(self._continuousContract.Mapped, 1) self.Log("Going short") self.tradingnumber[0] = 4 if self.tradingnumber[0] == 4 and slopeshort > 0 and slope_rsi > 0: for symbol, quantity in futures_invested_long: self.MarketOrder(symbol, -quantity) # Liquidate the short position self.tradingnumber[0] = 0 friday_close_time = time(16, 58) if self.Time.weekday() == 4 and current_time == friday_close_time: for symbol in futures_invested: self.MarketOrder(symbol, -self.Portfolio[symbol].Quantity) # Liquidate the position self.tradingnumber[0] = 0 #self.Log("10 EMA slope: {0}, 12RSI5SMA Slope: {1}, Histo: {2}".format(round(slope, 2), round(slope_rsi, 2), round(slope_macd_histogram, 2)))