Hello All, 

I was wondering if someone could help me with this: 

I am trying to create daily consolidated prices (tradebars) rolling windows for a list of tickers, say : ["SPY", "TLT", "BND"]. Would this script do the trick? In the current script, I have two different classes, one for prices rolling windows, and another for the indicator rolling window. After which, I combine two dictionaries containing results of the indicator and prices rolling windows into one dictionary. I feel there should be an easier way of doing that resulting in a cleaner code. 

How can we combine both the price daily rolling windows and the indicator (ADX in this case) daily rolling window in the same class?

Also, Is there a fast way to calculate, let's say, the 3 day high (i.e. the highest price the stock reached in the last 3 days? 

The resolution in this code is hourly, also can be minutes. 

The resolution for the price and indicator rolling windows should be daily. 

Thanks a lot.

 

from collections import defaultdict
class MyAlgorithm(QCAlgorithm):

def Initialize(self):

self.SetStartDate(2019,1,1)
self.SetCash(100000)
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)

tickers = ["SPY", "TLT", "BND"]

# Creates empty dictionary to later hold daily Tradebar price rolling windows
self.symbolData_window = {}
# Creates empty dictionary to later hold ADX daily values
self.symbolData = {}

for ticker in tickers:

self.equity = self.AddEquity(ticker, Resolution.Hour)
self.equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
self.equity.SetLeverage(1.0)


symbol_window = self.equity.Symbol
symbol = self.equity.Symbol


# Consolidating lower resolution data into daily data for daily rolling windows
consolidator_daily = TradeBarConsolidator(timedelta(days = 1))
consolidator_daily.DataConsolidated += self.OnDailyData
self.SubscriptionManager.AddConsolidator(symbol_window, consolidator_daily)


# Creating symbol data for respective symbol
self.symbolData_window[symbol_window] = SymbolData_window(self, symbol_window)


# Creates daily ADX rolling windows
self.symbolData[symbol] = SymbolData(self, symbol)

self.SetWarmUp(100)


# Adding daily bar data to 4, 3, 2 etc.. rolling windows
def OnDailyData(self, sender, bar):

self.symbolData_window[bar.Symbol].window4.Add(bar)
self.symbolData_window[bar.Symbol].window3.Add(bar)
self.symbolData_window[bar.Symbol].window2.Add(bar)


def OnData(self, data):


for symbol, value in self.symbolData.items():
if not data.ContainsKey(symbol.Value):
return

for symbol, value in self.symbolData_window.items():
if not data.ContainsKey(symbol.Value):
return

for symbol, value in self.symbolData_window.items():

value.window4.Add(data[symbol.Value])
value.window3.Add(data[symbol.Value])
value.window2.Add(data[symbol.Value])

if self.IsWarmingUp:
return


# ADX rolling window ready
if not all([symbol.IsReady for symbol in self.symbolData.values()]):
return

# Merging both dictionaries for ADX and daily rolling windows together on same key:
self.symbolData_combined = defaultdict(list)

for d in (self.symbolData, self.symbolData_window):
for key, value in d.items():
self.symbolData_combined[key].append(value)

for symbol, value in self.symbolData_combined.items():

if value[1].window4[0].High > value[1].window4[1].High > value[1].window4[2].High > value[1].window4[3].High and value[0].adxWindow[0] > value[0].adxWindow[1]:
self.SetHoldings(symbol, 1/3)
else:
if self.Portfolio[symbol].Invested == True:
self.Liquidate(symbol)


class SymbolData:

def __init__(self, algorithm, symbol):

self.algorithm = algorithm
self.symbol = symbol


# Defining indicator (ADX in this case)
self.adx = algorithm.ADX(symbol, 14, Resolution.Daily)

# Defining rolling window to hold indicator points
self.adxWindow = RollingWindow[IndicatorDataPoint](2)

# Setting event handler
self.adx.Updated += self.OnAdxUpdated


def OnAdxUpdated(self, sender, updated):

if self.adx.IsReady:
# Adding updated indicator data (ADX data) to rolling window
self.adxWindow.Add(updated)

@property
def IsReady(self):
return self.adx.IsReady and self.adxWindow.IsReady



class SymbolData_window:

def __init__(self, algorithm, symbol):

self.algorithm = algorithm
self.symbol = symbol

self.window4 = RollingWindow[TradeBar](4)
self.window3 = RollingWindow[TradeBar](3)
self.window2 = RollingWindow[TradeBar](2)