Hi 

Thanks in advanced.  I am still new and suspect I am not coding the strategy the correct way or maybe there is a better way.  In fact I am sure it should be done with consolidators, but not sure how.

As you will see from the code I have automatic daily Bollinger Band indicator that is being applied to multiple stocks.  What I want is a have is an indicator say the Daily Bollinger Bands calculated at the close and the result made available at the close.  So I can then have the strategy place an order in the after market trading. 

However it looks like the following is happening: 

  1. The Automatic Bollinger band indicator is not calculated until midnight, not at the market close. 
  2. The automatic Bollinger Band Updated event appears to not occur until the next day at the end of the first bar of the next day.  Being 4:01 if pre-market trading data is on and 9:31 if pre-market data is off.
  3. The Updated event does not appear to have a way to know which underlying assest that trigger the Updated Bollinger Band event.  

 

What I would like is to have the Automatic Indicator say Bollinger Band.  Calculate at the market close and be available after the maket close 16:45 for after market trading.

I would also like to calculate indicators before the market close using the latest days OHLC to that point during the day.   This at 30 minutes before the end of the day it would recalculate the daily indicator.  This would all the strategy to scan multiple stock and determine if a stock had met the indicator requirements.

I think could be done by with each minute bar updating my own OHLCV variables as the day progresses. After 4:00PM using data history loading it into a rolling window and then creating a fake bar from the daily calculated variables and adding that to the rolling window.  Finally calculating the indicator value of the rolling windows.   Happy to use arries, dataframes or other object if Rolling Windows are not right.

However I am sure there is a better way using consolidators to do this.  Below there is my code to show how I discovered the indicators appear to update and midnight and are not open till the first bar of the next day.

I have also include my code to do the method above.  But can not do the following steps:

  1. Load data from the history into a rolling window,
  2. Create a fake daily bar and load into a rolling window.
  3. Calculate and incidator of a rolling window.

 

Ideally I would like to have is my rolling windows are dictionaries.  So I can load up multiple stocks with rolling window as dictionary entries and each minute check if the rolling window for the dictionary is populated.

 if the last entry was not the close of the previous delete the entry from the rolling windows and add the fake bar before calculating the indicator. This will save reloading the history data for every chosen stock every minute.

Excuse me for not hard coding any values.  Make maintenance of code easier.

 

Could not find the answers in the Discussion wondering if anyone know how to do this.  Habit form my old C programming days.

 

Thank you from a newbee

main.py (Show the daily indicator is not calculated until midnight and does not trigger an event until the first bar the next day.)

#region imports
from AlgorithmImports import *
#endregion

class OptionsPolarity(QCAlgorithm):

    def Initialize(self):


		self.starting_date = datetime.date(2022, 11, 1)
		self.ending_date = datetime.date(2022, 11, 25)    
		self.starting_cash = 20000
		self.benchmark_ticker = "SPY"

		self.universe_tickers = ["SPY", "AAPL", "CMG", "TSLA", "SLB", "NFLX"]

		self.bb_period = 20               
		self.bb_std_dev = 75              
		self.bb_windows_periods = 200      

		self.asset_minutes = dict()
		self.asset_symbols = dict()

		self.bb_indicators = dict()

		self.current_date = None
		self.current_time = None


		self.last_date = None
		self.last_time = None

		self.last_day = -1
		self.new_day = None

		self.bb_new_bar = False

		self.current_ticker = None
		self.current_ticker_price = None

		self.current_days_open = dict()
		self.current_days_high = dict()
		self.current_days_lower = dict()
		self.current_days_close = dict()

        self.SetStartDate(self.starting_date)
        self.SetEndDate(self.ending_date)    
        self.SetCash(self.starting_cash)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, \
                               AccountType.Cash)

        for local_ticker in self.universe_tickers:

            self.current_ticker = local_ticker  
          
            self.asset_minutes[self.current_ticker] = self.AddEquity(self.current_ticker, Resolution.Minute, Market.USA, True, 0, True)

            self.asset_symbols[self.current_ticker] = self.asset_minutes[self.current_ticker].Symbol
 
            self.bb_indicators[self.current_ticker] = self.BB(self.asset_symbols[self.current_ticker], self.bb_period, self.bb_std_dev, MovingAverageType.Simple, Resolution.Daily)
        
            self.bb_indicators[self.current_ticker].Updated += self.bb_indicators_updated

        self.SetWarmUp(TimeSpan.FromDays(self.bb_windows_periods + self.bb_period))

        self.SetBenchmark(self.benchmark_ticker)

    def bb_indicators_updated(self, sender, updated):
        self.bb_new_bar = True
        self.current_date = self.Time.date()
        self.current_time = self.Time.time()     
        self.Debug("BB Updated Event occured Date and Time: " + str(self.current_date) + " " + str(self.current_time)) 
        self.Debug("bb_indicators_Updated sender: " + str(sender))
        self.Debug("bb_indicators_Updated updated: " + str(updated))


    def OnData(self,slice):

        self.current_date = self.Time.date()
        self.current_time = self.Time.time()

        if self.bb_new_bar == True:
            self.Debug("First Backtest Bar After New  BB Update Event")
            self.Debug("Current Bar Closing Date and Time: " + str(self.current_date) + " " + str(self.current_time))
            self.Debug("Last Bar Closing Date and Time: " + str(self.last_date) + " " + str(self.last_time))

        if self.Time.day != self.last_day:
            self.last_day = self.Time.day
            self.new_day = True
            self.day_count = self.day_count + 1
            self.Debug("New Day")
            self.Debug("Bar Closing Date and Time: " + str(self.current_date) + " " + str(self.current_time))

        self.last_date = self.Time.date()
        self.last_time = self.Time.time()

        self.bb_new_bar = False
        self.new_day = False
        
        for local_ticker in self.universe_tickers:
            continue 
50626_1671018468.jpg

 

main.py (this is my attempt to solve my challenge)

(Commented out the code at the end.  It does not work but should show what I am trying to do.

#region imports
from AlgorithmImports import *
#endregion

from datetime import datetime
from datetime import timedelta

import self

class OptionsPolarity(QCAlgorithm):

    def Initialize(self):

        self.starting_date = datetime.date(2022, 11, 1)
        self.ending_date = datetime.date(2022, 11, 25)    
        self.starting_cash = 20000
        self.benchmark_ticker = "SPY"

        self.universe_tickers = ["SPY"], "AAPL", "FB", "TSLA", "FAS", "NFLX"]

        self.asset_analysis_period = 120

        self.bb_period = 20               
        self.bb_std_dev = 75              
        self.bb_windows_periods = 30 #200     

        self.asset_minutes = dict()
        self.asset_symbols = dict()
        self.asset_bars = dict()
        self.asset_windows = dict()

        self.bb_indicators = dict()

        self.current_date = None
        self.current_time = None
        self.current_datetime = None

        self.last_date = None
        self.last_time = None

        self.last_day = -1
        self.new_day = None
        self.day_count = 0

        self.current_ticker = None

        self.is_market_open = None
        self.was_market_open = None
        self.market_just_opened = None
        self.market_just_closed = None

        self.current_ticker_price = None

        self.current_days_open = dict()
        self.current_days_high = dict()
        self.current_days_lower = dict()
        self.current_days_close = dict()
        self.current_days_volume = dict()

        self.SetStartDate(self.starting_date)
        self.SetEndDate(self.ending_date)    
        self.SetCash(self.starting_cash)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, \
                               AccountType.Cash)

        for local_ticker in self.universe_tickers:

            self.current_ticker = local_ticker  

            self.asset_minutes[self.current_ticker] = self.AddEquity(self.current_ticker, Resolution.Minute, Market.USA, True, 0, True)

            self.asset_symbols[self.current_ticker] = self.asset_minutes[self.current_ticker].Symbol

            self.asset_bars[self.current_ticker] = self.History([self.current_ticker], TimeSpan.FromDays(self.bb_windows_periods), Resolution.Daily)
                    
            self.asset_windows = RollingWindow[TradeBar](self.bb_windows_periods)

        if self.asset_analysis_period > self.bb_windows_periods + self.bb_period:
            self.SetWarmUp(TimeSpan.FromDays(self.asset_analysis_period))
        else:
            self.SetWarmUp(TimeSpan.FromDays(self.bb_windows_periods + self.bb_period))

        self.SetBenchmark(self.benchmark_ticker)



    def OnData(self,slice):

        self.current_date = self.Time.date()
        self.current_time = self.Time.time()
        self.current_datetime = datetime.combine(self.current_date, self.current_time)

        if self.Time.day != self.last_day:
            self.last_day = self.Time.day
            self.new_day = True
            self.day_count = self.day_count + 1

        for local_ticker in self.universe_tickers: 

            self.current_ticker = local_ticker  

            self.is_market_open = self.IsMarketOpen(self.current_ticker)

            self.market_just_opened = False \
                    if self.is_market_open and not self.was_market_open else True 
            self.market_just_closed = False \
                    if not self.is_market_open and self.was_market_open else True

            self.current_ticker_price = self.Securities[self.current_ticker].Price 

            if self.market_just_opened:
                self.current_days_open[self.current_ticker] = self.current_ticker_price
                self.current_days_high[self.current_ticker] = self.current_ticker_price
                self.current_days_lower[self.current_ticker] = self.current_ticker_price
                self.current_days_close[self.current_ticker] = self.current_ticker_price 
                self.current_days_volume[self.current_ticker] = self.Securities[self.current_ticker].Volume
            elif  self.is_market_open or self.market_just_closed:
                if self.current_days_high[self.current_ticker] < self.current_ticker_price:
                    self.current_days_high[self.current_ticker] = self.current_ticker_price
                if self.current_days_lower[self.current_ticker] > self.current_ticker_price:
                    self.current_days_lower[self.current_ticker] = self.current_ticker_price
                    self.current_days_close[self.current_ticker] = self.current_ticker_price
                self.current_days_volume[self.current_ticker] = \
                    self.current_days_volume[self.current_ticker] + \
                    self.Securities[self.current_ticker].Volume

            if  self.is_market_open:
                self.trading_hours = self.Securities[self.current_ticker].Exchange.Hours
                self.current_open = self.trading_hours.GetNextMarketOpen(self.Time, False)
                self.current_close = self.trading_hours.GetNextMarketClose(self.current_open, False)
            
                self.thirty_minutes_before_close = self.current_close - timedelta(minutes=30)
                
                if self.thirty_minutes_before_close.strftime('%H:%M') <= self.current_datetime.strftime('%H:%M'):
                    pass
                    #if not self.tradeBarWindow.IsReady:
                    #    for i in range(self.bb_windows_periods, 1, -1):
                            
                            #This of course does not work.  But hope it show what am trying to do
                    #        self.asset_windows[self.current_ticker].Add( \
                    #                self.asset_bars[self.current_ticker][i])
                        
                    #else:  
                            
                        #This of course does not work.  But hope it show what am trying to do 
                        #self.asset_windows[self.current_ticker].Delete
                    
                        #This of course does not work.  But hope it show what am trying to do 
                        #self.asset_windows[self.current_ticker].Add(self.current_datetime,\
                        #        self.current_days_open[self.current_ticker], \
                        #        self.current_days_high[self.current_ticker], \ 
                        #        self.current_days_low[self.current_ticker], \
                        #        self.current_days_close[self.current_ticker], \
                        #        self.current_days_volume[self.current_ticker])
  
                        #This of course does not work.  But hope it show what am trying to do                               
                        #self.bb_indicators[self.current_ticker] = self.BB( \
                        #        self.asset_windows[self.current_ticker], \
                        #        bb_period[self.current_ticker], \
                        #        bb_std_dev[self.current_ticker], Resolution.Daily)
                    

        self.last_date = self.current_date
        self.last_time = self.current_time

        self.was_market_open = self.is_market_open

        self.bb_new_bar = False
        self.new_day = False