Back

Crypto data previous day consolidation, using Hourly data

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]

 

Update Backtest







0

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.


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)

1


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

0

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

0


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. 

 

0


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)

 

0

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

0

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.


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

 

0

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

0

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.


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

0

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.


Update Backtest





0

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.


Loading...

This discussion is closed