Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -2.048 Tracking Error 0.119 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
from AlgorithmImports import * class alpha_1_day(AlphaModel): def __init__(self, ndx): self.symbol = None self.level = None self.symbol_data = {} self.ndx = ndx self.last_consolidation_time = None self.minute = 0 def Update(self, algorithm, data): insights = [] # Very important function handling consolidation if self.last_consolidation_time is not None and self.minute != self.last_consolidation_time.minute: self.minute = self.last_consolidation_time.minute # Update the minute value for symbol in self.symbol_data.keys(): if symbol in data and data[symbol] is not None: bar = data[symbol] #algorithm.Debug(f'Symbol: {symbol}, Open: {bar.Open}, Close: {bar.Close}') if 'level' in self.symbol_data[symbol] and self.symbol_data[symbol]['level'] is not None: algorithm.Debug(self.symbol_data[symbol]['level']) #algorithm.Plot("Breakout Price", f"{symbol} Day Open", self.symbol_data[symbol]['level']) # Generate insights for /NQ only if symbol.Value == "/NQ": if bar.Close > symbol_info['level']: algorithm.Debug(symbol) #insights.append(Insight(symbol.Value, timedelta(minutes=20), InsightType.Price, InsightDirection.Up)) elif bar.Close <= symbol_info['level']: #insights.append(Insight.Price(symbol, timedelta(days=1), InsightDirection.Flat)) pass return insights def consolidation_handler(self, sender, bar): self.last_consolidation_time = bar.Time def OnSecuritiesChanged(self, algorithm, changes): # Set symbol and add to the algorithm for security in changes.AddedSecurities: # Notice that I have made literally the same if statement in main.py in OnSecurititesChanged function # It seems that main.py is still passing some contracts other than NDX and /NQ # Therefore I double check and make sure no other contract than /NQ and NDX can pass further # In Live trading this will likely pose a problem and will need to be fixed # Question 1: why are other contracs reaching here? # Question 2: how to handle the fact that QC has a max of 10 active series. What does that mean? if security.Symbol == "/NQ" or security.Symbol == "NDX": self.symbol_data[security.Symbol] = {} self.consolidator = TradeBarConsolidator(timedelta(minutes=15)) self.consolidator.DataConsolidated += self.consolidation_handler algorithm.SubscriptionManager.AddConsolidator(security.Symbol, self.consolidator) algorithm.Schedule.On(algorithm.DateRules.EveryDay(), algorithm.TimeRules.AfterMarketOpen(self.ndx, 5), Action(lambda: self.SetLevel(algorithm, security.Symbol))) # Liquidate positions at the end of the month for /NQ only algorithm.Schedule.On(algorithm.DateRules.EveryDay(), algorithm.TimeRules.BeforeMarketClose(self.ndx, 5), Action(lambda: self.LiquidatePositions(algorithm))) for security in changes.RemovedSecurities: if security.Symbol in self.symbol_data: self.symbol_data.pop(security.Symbol) def SetLevel(self, algorithm, symbol): for symbol in self.symbol_data.keys(): if symbol.Value == "NDX": # check if the symbol is "NDX" history = algorithm.History(symbol, 1, Resolution.Minute) if not history.empty: self.symbol_data[symbol]['level'] = history.loc[str(symbol)].open[0] def LiquidatePositions(self, algorithm): #algorithm.Liquidate(self.symbol) #self.level = None pass
from AlgorithmImports import * class alpha_1_month(AlphaModel): def __init__(self, ndx): self.symbol = None self.level = None self.symbol_data = {} self.ndx = ndx self.last_consolidation_time = None self.minute = 0 def Update(self, algorithm, data): insights = [] # Very important function handling consolidation if self.last_consolidation_time is not None and self.minute != self.last_consolidation_time.minute: self.minute = self.last_consolidation_time.minute # Update the minute value for symbol in self.symbol_data.keys(): if symbol in data and data[symbol] is not None: bar = data[symbol] #algorithm.Debug(f'Symbol: {symbol}, Open: {bar.Open}, Close: {bar.Close}') if 'level' in self.symbol_data[symbol] and self.symbol_data[symbol]['level'] is not None: algorithm.Plot("Breakout Price", f"{symbol} Month Open", self.symbol_data[symbol]['level']) algorithm.Plot("Breakout Price", "NDX Price Close", bar.Close) # Generate insights for /NQ only if symbol.Value == "/NQ": if bar.Close > symbol_info['level']: algorithm.Debug(symbol) #insights.append(Insight(symbol.Value, timedelta(minutes=20), InsightType.Price, InsightDirection.Up)) elif bar.Close <= symbol_info['level']: #insights.append(Insight.Price(symbol, timedelta(days=1), InsightDirection.Flat)) pass return insights def consolidation_handler(self, sender, bar): self.last_consolidation_time = bar.Time def OnSecuritiesChanged(self, algorithm, changes): # Set symbol and add to the algorithm for security in changes.AddedSecurities: # Notice that I have made literally the same if statement in main.py in OnSecurititesChanged function # It seems that main.py is still passing some contracts other than NDX and /NQ # Therefore I double check and make sure no other contract than /NQ and NDX can pass further # In Live trading this will likely pose a problem and will need to be fixed # Question 1: why are other contracs reaching here? # Question 2: how to handle the fact that QC has a max of 10 active series. What does that mean? if security.Symbol == "/NQ" or security.Symbol == "NDX": self.symbol_data[security.Symbol] = {} self.consolidator = TradeBarConsolidator(timedelta(minutes=15)) self.consolidator.DataConsolidated += self.consolidation_handler algorithm.SubscriptionManager.AddConsolidator(security.Symbol, self.consolidator) algorithm.Schedule.On(algorithm.DateRules.MonthStart(self.ndx), algorithm.TimeRules.At(0, 0), Action(lambda: self.SetLevel(algorithm, security.Symbol))) # Liquidate positions at the end of the month for /NQ only algorithm.Schedule.On(algorithm.DateRules.MonthEnd(self.ndx), algorithm.TimeRules.BeforeMarketClose(self.ndx, 10), Action(lambda: self.LiquidatePositions(algorithm))) for security in changes.RemovedSecurities: if security.Symbol in self.symbol_data: self.symbol_data.pop(security.Symbol) def SetLevel(self, algorithm, symbol): for symbol in self.symbol_data.keys(): if symbol.Value == "NDX": # check if the symbol is "NDX" history = algorithm.History(symbol, 1, Resolution.Minute) if not history.empty: self.symbol_data[symbol]['level'] = history.loc[str(symbol)].open[0] def LiquidatePositions(self, algorithm): #algorithm.Liquidate(self.symbol) #self.level = None pass
from AlgorithmImports import * class alpha_1_week(AlphaModel): def __init__(self, ndx): self.symbol = None self.level = None self.symbol_data = {} self.ndx = ndx self.last_consolidation_time = None self.minute = 0 def Update(self, algorithm, data): insights = [] # Very important function handling consolidation if self.last_consolidation_time is not None and self.minute != self.last_consolidation_time.minute: self.minute = self.last_consolidation_time.minute # Update the minute value for symbol in self.symbol_data.keys(): if symbol in data and data[symbol] is not None: bar = data[symbol] #algorithm.Debug(f'Symbol: {symbol}, Open: {bar.Open}, Close: {bar.Close}') if 'level' in self.symbol_data[symbol] and self.symbol_data[symbol]['level'] is not None: algorithm.Debug(self.symbol_data[symbol]['level']) #algorithm.Plot("Breakout Price", f"{symbol} Week Open", self.symbol_data[symbol]['level']) # Generate insights for /NQ only if symbol.Value == "/NQ": if bar.Close > symbol_info['level']: algorithm.Debug(symbol) #insights.append(Insight(symbol.Value, timedelta(minutes=20), InsightType.Price, InsightDirection.Up)) elif bar.Close <= symbol_info['level']: #insights.append(Insight.Price(symbol, timedelta(days=1), InsightDirection.Flat)) pass return insights def consolidation_handler(self, sender, bar): self.last_consolidation_time = bar.Time def OnSecuritiesChanged(self, algorithm, changes): # Set symbol and add to the algorithm for security in changes.AddedSecurities: # Notice that I have made literally the same if statement in main.py in OnSecurititesChanged function # It seems that main.py is still passing some contracts other than NDX and /NQ # Therefore I double check and make sure no other contract than /NQ and NDX can pass further # In Live trading this will likely pose a problem and will need to be fixed # Question 1: why are other contracs reaching here? # Question 2: how to handle the fact that QC has a max of 10 active series. What does that mean? if security.Symbol == "/NQ" or security.Symbol == "NDX": self.symbol_data[security.Symbol] = {} self.consolidator = TradeBarConsolidator(timedelta(minutes=15)) self.consolidator.DataConsolidated += self.consolidation_handler algorithm.SubscriptionManager.AddConsolidator(security.Symbol, self.consolidator) algorithm.Schedule.On(algorithm.DateRules.Every(1), algorithm.TimeRules.AfterMarketOpen(self.ndx, 5), Action(lambda: self.SetLevel(algorithm, security.Symbol))) # Liquidate positions at the end of the month for /NQ only algorithm.Schedule.On(algorithm.DateRules.Every(5), algorithm.TimeRules.BeforeMarketClose(self.ndx, 5), Action(lambda: self.LiquidatePositions(algorithm))) for security in changes.RemovedSecurities: if security.Symbol in self.symbol_data: self.symbol_data.pop(security.Symbol) def SetLevel(self, algorithm, symbol): for symbol in self.symbol_data.keys(): if symbol.Value == "NDX": # check if the symbol is "NDX" history = algorithm.History(symbol, 1, Resolution.Minute) if not history.empty: self.symbol_data[symbol]['level'] = history.loc[str(symbol)].open[0] def LiquidatePositions(self, algorithm): #algorithm.Liquidate(self.symbol) #self.level = None pass
from AlgorithmImports import * from alpha_1_month import alpha_1_month as Month from alpha_1_week import alpha_1_week as Week from alpha_1_day import alpha_1_day as Day from datetime import datetime, timedelta class MyAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 1, 1) self.SetEndDate(2023, 12, 31) self.SetCash(1000000) self.ndx = self.AddIndex("NDX", Resolution.Minute).Symbol self.qqq = self.AddFuture(Futures.Indices.NASDAQ100EMini, Resolution.Minute) self.qqq.SetFilter(timedelta(0), timedelta(180)) self.contract = None # Track symbols in our universe self.universe_symbols = [self.ndx] # Set algorithm framework models self.SetUniverseSelection(ManualUniverseSelectionModel(self.universe_symbols)) # Add Alpha model # Repeat this line if we want to add more alpha models (for each timeframe for example) self.AddAlpha(Month(self.ndx)) self.AddAlpha(Week(self.ndx)) self.AddAlpha(Day(self.ndx)) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetRiskManagement(NullRiskManagementModel()) self.SetExecution(ImmediateExecutionModel()) def OnData(self, data): pass # for symbol in self.universe_symbols: # if symbol in data and data[symbol] is not None: # self.Plot("Data Chart", str(symbol), data[symbol].Close) # ndx_close = data[self.ndx].Close if self.ndx in data and data[self.ndx] is not None else 0 # nq_close = data[self.qqq.Symbol].Close if self.qqq.Symbol in data and data[self.qqq.Symbol] is not None else 0 def OnSecuritiesChanged(self, changes): added_contracts = [x for x in changes.AddedSecurities if x.Symbol.SecurityType == SecurityType.Future] if added_contracts: self.contract = sorted(added_contracts, key=lambda x: x.Expiry, reverse=True)[0] # Pass through only continuous future contract data (probably not suitable for live trading, but for plotting it's good) if self.contract.Symbol == "/NQ": # Append symbol to out universe symbols array which then goes to the manual universe selection model self.universe_symbols.append(self.contract.Symbol)