Hi Bronx,
I've been working with FX data a lot and have the same problem between QuantConnect (QC) and TradingView (TV) daily data. Below is what I've found and how I've worked around the problem so far.
To my knowledge, the following are true, which I think is consistent with your experience:
- TV and Oanda data (i.e., data taken directly from an Oanda account or the Oanda API) always agree for all time frames.
- QC and TV data agree for hourly bars and below
- QC and TV data disagree for daily bars, whether the daily bars are taken directly from QC or consolidated from, e.g., hourly QC bars
I think, but am not sure, that (3) may be a result of how QC constructs FX data, but if I am wrong, someone please correct me. Regardless, I think the overarching reason is that the FX is a 24/5 market, but the generally accepted "close" happens at 5pm NYC time instead of midnight NYC time, and consolidators don't take this into account. Therefore, this is basically what I do in the research and backtest environments.
- Research Environment: When I want daily bars, I construct them from hourly bars instead of pull daily bars directly from qb.History (I would show you an example, but right now no one can open research notebooks). The trick is to add 7 hours to each hourly bar's timestamp before consolidating so the code "thinks" the day ends at midnight, but in reality ends at 5pm NYC time. As a side note, when you do this, you'll get 5 daily bars per week instead of 6, as desired.
- Backtest Environment: Again, I construct daily data from hourly/minute bars, but here I will use scheduled events. For example, if you want to know the previous day's high and low, you can do something like the code snippet below.
I hope this helps. If anyone has better solutions, please let us know!
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(17, 0), self.SetPrevDayHighLow)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.Every(timedelta(hours=1)), self.CurrDayHighLow)
def SetPrevDayHighLow(self):
"""At the trading day's close, set previous extrema to the current day's extrema."""
# Don't update on weekend days
if self.Time.weekday() > 4:
return
for symbol in self.symbols:
self.prevHigh[symbol] = self.currHigh[symbol]
self.prevLow[symbol] = self.currLow[symbol]
self.currHigh[symbol] = None
self.currLow[symbol] = None
def TradeAndCurrDayHighLow(self):
"""For the trading day, update that day's high and low prices."""
for symbol in self.symbols:
# Check if data exist for that symbol.
if not self.CurrentSlice.ContainsKey(symbol):
continue
high = self.CurrentSlice[symbol].High
low = self.CurrentSlice[symbol].Low
if self.currHigh[symbol] is None or high > self.currHigh[symbol]:
self.currHigh[symbol] = high
if self.currLow[symbol] is None or low < self.currLow[symbol]:
self.currLow[symbol] = low