Hi... so I have once again run into issues on this function. With the help of the previous discussion I was able to consolidate hourly crypto data into daily bars; however the price properties that are consolidated into hourly consolidator functions, that due to the rolling window has the data of the previous day is still inaccessible via the on Data function, where I kind of need to get to for analysis... the trade consolidation function works..
I'm just getting confused on how to get the high low and close properties according to the crypto security to be usable in the ondata function
from QuantConnect.Data.Market import TradeBar
from datetime import timedelta
class TachyonQuantumAutosequencers(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 7, 20) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
# list of symbols we want to trade
self.symbolList = ["BTCUSD","ETHUSD","LTCUSD","BCHUSD"]
#self.symbolList = ["BTCUSD","ETHUSD","BCHUSD"]
# dictionary to hold rolling window for each symbol
self.daily = {}
#self.tradebar = {}
for name in self.symbolList:
self.cryptoSymbol = self.AddCrypto(name, Resolution.Hour, Market.GDAX).Symbol
HourlyConsolidator = TradeBarConsolidator(timedelta(hours=24))
HourlyConsolidator.DataConsolidated += self.HourlyConsolidator
self.SubscriptionManager.AddConsolidator(self.cryptoSymbol, HourlyConsolidator)
self.daily[self.cryptoSymbol] = RollingWindow[float](2)
#self.tradebar[cryptoSymbol] = RollingWindow[TradeBar](2)
#self.tradeBarWindow = RollingWindow[TradeBar](2)
def HourlyConsolidator(self, sender, bar):
symbol = bar.Symbol
close = bar.Close
volume = bar.Volume
high = bar.High
low = bar.Low
# update rolling window
self.daily[symbol].Add(close)
self.daily[symbol].Add(high)
self.daily[symbol].Add(low)
if not (self.daily[symbol].IsReady): return
self.Debug('symbol: {} close price: {} high price: {} low price: {}'.format(symbol, close,high,low))
self.Log(" ")
#self.Log('symbol: {} close price: {} high price: {} low price: {}'.format(symbol, close,high,low))
#self.Log(" ")
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
'''
#self.Debug(self.daily.keys())
# for name in self.symbolList:
# #Here I'm trying to get the trade bar data that was consolidated hourly in the 24 hour bars
# self.daily[name]
Hemanto Bairagi
Joe Bastulli I was hoping I could get some more assistance with this... if you wouldn't mind (sorry for closing the last discussion pretty new to forum controls)
Joe Bastulli
class TachyonQuantumAutosequencers(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 7, 20) # Set Start Date self.SetCash(100000) # Set Strategy Cash # string list of symbols we want to trade self.symbolList = ["BTCUSD","ETHUSD","LTCUSD","BCHUSD", "XRPUSD","BCHUSD","XLMUSD","EOSUSD", "REPUSD","XTZUSD","ETCUSD","ZRXUSD"] # dictionary to hold rolling window for each symbol self.daily = {} # list of symbol objects self.cryptoSymbols = [] for name in self.symbolList: # get symbol object symbol = self.AddCrypto(name, Resolution.Hour, Market.GDAX).Symbol # append to list self.cryptoSymbols.append(symbol) # create rolling window of len 2 self.daily[symbol] = RollingWindow[float](2) def OnData(self, data): # iterate through each object in our list for symbol in self.cryptoSymbols: # get OHLC values to use later o = data.Bars[symbol].Open h = data.Bars[symbol].High l = data.Bars[symbol].Low c = data.Bars[symbol].Close # update our rolling window self.daily[symbol].Add(c) # check if rolling window is full if not (self.daily[symbol].IsReady): return # print OHLC and last value in our window self.Debug('{} O {} H {} L {} C {} Window {}'.\ format(symbol, o, h, l, c, self.daily[symbol][1]))
I believe this is what you are trying to accomplish
Hemanto Bairagi
Joe Bastulli first of all thanks for getting back to me its been a great help...
And kind of but not really I'm trying to get the data from the previous day and compare it to the hourly data coming in from the market on the trading day hence I'm trying to consolidate 24 hourly bars into 1 bar of data for crypto currency. So basically get the close open high lows volume from the previous day, and compare it to the hourly data being coming in from the market; and make trade decisions based on that.
So I took the principles from the previous codes and applied them to here, and the data did indeed consolidate, however I get this runtime error whenever I try to debug it (I've attached the backtest btw):
Runtime Error: Trying to dynamically access a method that does not exist throws a TypeError exception. To prevent the exception, ensure each parameter type matches those required by the Add method. Please checkout the API documentation.
at OnData in main.py:line 30
:: self.window.Add(data["BTCUSD"])
TypeError : No method matches given arguments for Add (Open Stacktrace)
But yea... thats what I'm trying to accomplish (setting the previous days data as boundary conditions, to compare hourly data for intraday trading)
But yea man I'll be looking forward to your reply
Hemanto Bairagi
Joe Bastulli so I've done some research throughout the day and I was able to get the process I want using equities (so the first comment will dive into those); so the code works for SPY and it gets the previous days boundary conditions using a consolidated bar composed of 24 hourly bars; which would allow HFT; theoretcially the code could also support second resolution I suppose; but I'm not sure about Tick data... however when I try for crypto currency (just trying 1 at this point, but I'd like to scale up to the list you've provided previously provided).. it gave me the following error:
Runtime Error: Trying to dynamically access a method that does not exist throws a TypeError exception. To prevent the exception, ensure each parameter type matches those required by the Add method. Please checkout the API documentation.
at OnData in main.py:line 46
:: self.window.Add(data["BTCUSD"])
TypeError : No method matches given arguments for Add (Open Stacktrace)
I'll be attaching the BTC backtest in the next comment... but yeah I've narrowed down the issue to it being a Crypto specific issue.. that and the need to get the list back is still needed.. but yea I'll be looking forward to your feedback.
Hemanto Bairagi
So Joe Bastulli the forum says no backtests... but I took one so I'm just attaching a snapshot of the crypto code:
As you can see the only difference is Crypto is added.
Jared Broad is this perhaps a system issue (still pretty new to this)
from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Data.Consolidators import * from datetime import timedelta class VerticalParticleEngine(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 7, 20) # Set Start Date self.SetCash(100000) # Set Strategy Cash # self.AddEquity("SPY", Resolution.Minute) self.cryptoSymbol = self.AddCrypto("BTCUSD", Resolution.Hour, Market.GDAX).Symbol #self.security = self.AddEquity("SPY", Resolution.Hour, Market.USA).Symbol HourlyConsolidator = TradeBarConsolidator(timedelta(hours=24)) HourlyConsolidator.DataConsolidated += self.HourlyConsolidator self.SubscriptionManager.AddConsolidator(self.cryptoSymbol, HourlyConsolidator) #self.SubscriptionManager.AddConsolidator(self.security, HourlyConsolidator) self.window = RollingWindow[TradeBar](2) self.daily = RollingWindow[TradeBar](2) def HourlyConsolidator(self, sender, bar): self.daily.Add(bar) self.bar = bar 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 ''' self.window.Add(data["BTCUSD"]) if not (self.window.IsReady and self.daily.IsReady): return currBar = self.window[0].Close yesterdayc = self.daily[1].Close current_close_price = self.window[0].Close b_cond_upper = self.daily[1].High b_cond_low = self.daily[1].Low prev_close = self.daily[1].Close prev_open = self.daily[1].Open self.Debug("current close price: {} , upper boundary: {} , lower boundary: {}, previous close price: {}, previous open price: {} ".\ format(current_close_price, b_cond_upper, b_cond_low, prev_close, prev_open )) #self.Debug("current Bar: {} previous Bar: {}".format(currBar,yesterdayc)) # if not self.Portfolio.Invested: # self.SetHoldings("SPY", 1)
Derek Melchin
Hi Hemanto,
By default, when using an equity symbol to key the data slice passed to OnData, a TradeBar is returned. In contrast, keying with a crypto symbol returns a QuoteBar.
To access the TradeBar of a crypto security, we would need to write
data.Bars[self.cryptoSymbol]
instead of
data[self.cryptoSymbol]
See the attached backtest for reference.
Best,
Derek Melchin
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Hemanto Bairagi
Hi Derek Melchin thank you for the sample. I've been trying to expand this to multiple symbols right now as stated in the prior discussions; however I'm having some issues expanding your example to multiple symbols. I've taken your advice and used the bar instead of the symbols, however once I try to add it to the dictionary of symbols (line 38): self.daily[bar.Symbol].Add(bar)
I get run time errors... I was hoping I could get some help regarding this issue.
Sincerely Yours,
Orko Bairagi
from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Data.Consolidators import * from datetime import timedelta class TachyonQuantumAutosequencers(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 7, 1) # Set Start Date self.SetCash(100000) # Set Strategy Cash # list of symbols we want to trade self.symbolList = ["BTCUSD","ETHUSD","LTCUSD","BCHUSD"] # dictionary to hold rolling window for each symbol self.daily = {} self.cryptoSymbols = [] for name in self.symbolList: cryptoSymbol = self.AddCrypto(name, Resolution.Daily, Market.GDAX).Symbol self.cryptoSymbols.append(cryptoSymbol) dailyConsolidator = TradeBarConsolidator(timedelta(days=1)) dailyConsolidator.DataConsolidated += self.DailyConsolidator self.SubscriptionManager.AddConsolidator(cryptoSymbol, dailyConsolidator) self.daily[cryptoSymbol] = RollingWindow[float](2) def DailyConsolidator(self, sender, bar): self.daily[bar.Symbol].Add(bar) # symbol = bar.Symbol # close = bar.Close # volume = bar.Volume # # update rolling window # self.daily[symbol].Add(close) # if not (self.daily[symbol].IsReady): return # self.Debug('{} {}'.format(symbol, close)) # Accessing requested data def OnData(self, data): for symbols in self.cryptoSymbols: self.cryptoSymbol = symbols if not data.ContainsKey(self.cryptoSymbol): return self.window.Add(data.Bars[self.cryptoSymbol]) pass
Derek Melchin
Hi Hemanto,
The issue here is that
self.daily[bar.Symbol].Add(bar)
is trying to add a TradeBar to a RollingWindow that holds float objects. In line 34, we see
self.daily[cryptoSymbol] = RollingWindow[float](2)
We can fix this by chaning line 34 to
self.daily[cryptoSymbol] = RollingWindow[TradeBar](2)
Additionally, the logic in OnData requires a `window` property to be initialized, so we must add the following to the Initialize method
self.window = {} for name in self.symbolList: ... self.window[cryptoSymbol] = RollingWindow[TradeBar](2)
Lastly, in OnData, we must change how we add TradeBars to the `window` dictionary by using
self.window[symbol].Add(data.Bars[symbol])
See the attached backtest for reference.
Best,
Derek Melchin
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Derek Melchin
Hi Hemanto,
We can access bar properties from the `window` by selecting the bar and then calling the property. For example:
latest_bar = self.window[symbol][0] close_of_latest_bar = latest_bar.Close
The same can be done to access previous bar properties from the `daily` bar.
previous_daily_bar = self.daily[symbol][1] close_of_previous_daily_bar = previous_daily_bar.Close
See the attached backtest for reference.
Best,
Derek Melchin
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Samuele scarfone
Hi Derek Melchin, I was using this code and i was just wondering, how would I go about having the code choose one of the four symbols based on if it currently opened highest compared to the previous day. If that makes any sense.
-thanks
Derek Melchin
Hi Samuele,
To accomplish this, we should first increase the data resolution from daily to minute so that we can trade at the open.
cryptoSymbol = self.AddCrypto(name, Resolution.Minute, Market.GDAX).Symbol
We then save each consolidated daily bar, and calculate the overnight gap return at each market open. See the attached backtest for reference.
Best,
Derek Melchin
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Hemanto Bairagi
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!