Datasets
Key Concepts
Key History Concepts
The historical data API has many different options to give you the greatest flexibility in how to apply it to your algorithm.
Time Period Options
You can request historical data based on a trailing number of bars, a trailing period of time, or a defined period of time. If you request data in a defined period of time, the DateTime
datetime
objects you provide are based in the notebook time zone.
Return Formats
Each asset class supports slightly different data formats. When you make a history request, consider what data returns. Depending on how you request the data, history requests return a specific data type. For example, if you don't provide Symbol
objects, you get Slice
objects that contain all of the assets you created subscriptions for in the notebook.
The most popular return type is a DataFrame
. If you request a DataFrame
, LEAN unpacks the data from Slice
objects to populate the DataFrame
. If you intend to use the data in the DataFrame
to create TradeBar
or QuoteBar
objects, request that the history request returns the data type you need. Otherwise, LEAN will waste computational resources populating the DataFrame
.
Time Index
When your history request returns a DataFrame
, the timestamps in the DataFrame
are based on the data time zone. When your history request returns a TradeBars
, QuoteBars
, Ticks
, or Slice
object, the Time
time
properties of these objects are based on the notebook time zone, but the EndTime
end_time
properties of the individual TradeBar
, QuoteBar
, and Tick
objects are based on the data time zonedata time zone. The EndTime
end_time
is the end of the sampling period and when the data is actually available. For daily US Equity data, this results in data points appearing on Saturday and skipping Monday.
Request Data
The simplest form of history request is for a known set of Symbol
objects.
History requests return slightly different data depending on the overload you call. The data that returns is in ascending order from oldest to newest.
Single Symbol History Requests
To request history for a single asset, pass the asset Symbol
to the History
history
method. The return type of the method call depends on the history request [Type]
<Type>
. The following table describes the return type of each request [Type]
<Type>
:
Request Type | Return Data Type |
---|---|
No argument | DataFrame List<TradeBar> |
TradeBar | List[TradeBars] List<TradeBar> |
QuoteBar | List[QuoteBars] List<QuoteBar> |
Tick | List[Ticks] List<Tick> |
alternativeDataClass (ex: CBOE ) | List[alternativeDataClass] (ex: List[CBOE] )List<alternativeDataClass> (ex: List<CBOE> ) |
Each row of the DataFrame represents the prices at a point in time. Each column of the DataFrame is a property of that price data (for example, open, high, low, and close (OHLC)). If you request a DataFrame object and pass TradeBar
as the first argument, the DataFrame that returns only contains the OHLC and volume columns. If you request a DataFrame object and pass QuoteBar
as the first argument, the DataFrame that returns contains the OHLC of the bid and ask and it contains OHLC columns, which are the respective means of the bid and ask OHLC values. If you request a DataFrame and don't pass TradeBar
or QuoteBar
as the first arugment, the DataFrame that returns contains columns for all of the data that's available for the given resolution.
# EXAMPLE 1: Requesting By Bar Count: 5 bars at the security resolution: vix_symbol = qb.add_data(CBOE, "VIX", Resolution.DAILY).symbol cboe_data = qb.history[CBOE](vix_symbol, 5) btc_symbol = qb.add_crypto("BTCUSD", Resolution.MINUTE).symbol trade_bars = qb.history[TradeBar](btc_symbol, 5) quote_bars = qb.history[QuoteBar](btc_symbol, 5) trade_bars_df = qb.history(TradeBar, btc_symbol, 5) quote_bars_df = qb.history(QuoteBar, btc_symbol, 5) df = qb.history(btc_symbol, 5) # Includes trade and quote data
// EXAMPLE 1: Requesting By Bar Count: 5 bars at the security resolution: var vixSymbol = qb.AddData<CBOE>("VIX", Resolution.Daily).Symbol; var cboeData = qb.History<CBOE>(vixSymbol, 5); var btcSymbol = qb.AddCrypto("BTCUSD", Resolution.Minute).Symbol; var tradeBars = qb.History<TradeBar>(btcSymbol, 5); var quoteBars = qb.History<QuoteBar>(btcSymbol, 5); var tradeBars2 = qb.History(btcSymbol, 5);
# EXAMPLE 2: Requesting By Bar Count: 5 bars with a specific resolution: trade_bars = qb.history[TradeBar](btc_symbol, 5, Resolution.DAILY) quote_bars = qb.history[QuoteBar](btc_symbol, 5, Resolution.MINUTE) trade_bars_df = qb.history(TradeBar, btc_symbol, 5, Resolution.MINUTE) quote_bars_df = qb.history(QuoteBar, btc_symbol, 5, Resolution.MINUTE) df = qb.history(btc_symbol, 5, Resolution.MINUTE) # Includes trade and quote data
// EXAMPLE 2: Requesting By Bar Count: 5 bars with a specific resolution: var tradeBars = qb.History<TradeBar>(btcSymbol, 5, Resolution.Daily); var quoteBars = qb.History<QuoteBar>(btcSymbol, 5, Resolution.Minute); var tradeBars2 = qb.History(btcSymbol, 5, Resolution.Minute);
# EXAMPLE 3: Requesting By a Trailing Period: 3 days of data at the security resolution: eth_symbol = qb.add_crypto('ETHUSD', Resolution.TICK).symbol ticks = qb.history[Tick](eth_symbol, timedelta(days=3)) ticks_df = qb.history(eth_symbol, timedelta(days=3)) vix_data = qb.history[CBOE](vix_symbol, timedelta(days=3)) trade_bars = qb.history[TradeBar](btc_symbol, timedelta(days=3)) quote_bars = qb.history[QuoteBar](btc_symbol, timedelta(days=3)) trade_bars_df = qb.history(TradeBar, btc_symbol, timedelta(days=3)) quote_bars_df = qb.history(QuoteBar, btc_symbol, timedelta(days=3)) df = qb.history(btc_symbol, timedelta(days=3)) # Includes trade and quote data
// EXAMPLE 3: Requesting By a Trailing Period: 3 days of data at the security resolution: var ethSymbol = qb.AddCrypto("ETHUSD", Resolution.Tick).Symbol; var ticks = qb.History<Tick>(ethSymbol, TimeSpan.FromDays(3)); var cboeData = qb.History<CBOE>(vixSymbol, TimeSpan.FromDays(3)); var tradeBars = qb.History<TradeBar>(btcSymbol, TimeSpan.FromDays(3)); var quoteBars = qb.History<QuoteBar>(btcSymbol, TimeSpan.FromDays(3)); var tradeBars2 = qb.History(btcSymbol, TimeSpan.FromDays(3));
# EXAMPLE 4: Requesting By a Trailing Period: 3 days of data with a specific resolution: trade_bars = qb.history[TradeBar](btc_symbol, timedelta(days=3), Resolution.DAILY) quote_bars = qb.history[QuoteBar](btc_symbol, timedelta(days=3), Resolution.MINUTE) ticks = qb.history[Tick](eth_symbol, timedelta(days=3), Resolution.TICK) trade_bars_df = qb.history(TradeBar, btc_symbol, timedelta(days=3), Resolution.DAILY) quote_bars_df = qb.history(QuoteBar, btc_symbol, timedelta(days=3), Resolution.MINUTE) ticks_df = qb.history(eth_symbol, timedelta(days=3), Resolution.TICK) df = qb.history(btc_symbol, timedelta(days=3), Resolution.HOUR) # Includes trade and quote data # Important Note: Period history requests are relative to "now" notebook time.
// EXAMPLE 4: Requesting By a Trailing Period: 3 days of data with a specific resolution: var tradeBars = qb.History<TradeBar>(btcSymbol, TimeSpan.FromDays(3), Resolution.Daily); var quoteBars = qb.History<QuoteBar>(btcSymbol, TimeSpan.FromDays(3), Resolution.Minute); var ticks = qb.History<Tick>(ethSymbol, TimeSpan.FromDays(3), Resolution.Tick); var tradeBars2 = qb.History(btcSymbol, TimeSpan.FromDays(3), Resolution.Minute);
# EXAMPLE 5: Requesting By a Defined Period: 3 days of data at the security resolution: start_time = datetime(2022, 1, 1) end_time = datetime(2022, 1, 4) vix_data = qb.history[CBOE](vix_symbol, start_time, end_time) trade_bars = qb.history[TradeBar](btc_symbol, start_time, end_time) quote_bars = qb.history[QuoteBar](btc_symbol, start_time, end_time) ticks = qb.history[Tick](eth_symbol, start_time, end_time) trade_bars_df = qb.history(TradeBar, btc_symbol, start_time, end_time) quote_bars_df = qb.history(QuoteBar, btc_symbol, start_time, end_time) ticks_df = qb.history(Tick, eth_symbol, start_time, end_time) df = qb.history(btc_symbol, start_time, end_time) # Includes trade and quote data
// EXAMPLE 5: Requesting By a Defined Period: 3 specific days of data at the security resolution: var startTime = new DateTime(2022, 1, 1); var endTime = new DateTime(2022, 1, 4); var cboeData = qb.History<CBOE>(vixSymbol, startTime, endTime); var tradeBars = qb.History<TradeBar>(btcSymbol, startTime, endTime); var quoteBars = qb.History<QuoteBar>(btcSymbol, startTime, endTime); var ticks = qb.History<Tick>(ethSymbol, startTime, endTime); var tradeBars2 = qb.History(btcSymbol, startTime, endTime);
# EXAMPLE 6: Requesting By a Defined Period: 3 days of data with a specific resolution: trade_bars = qb.history[TradeBar](btc_symbol, start_time, end_time, Resolution.DAILY) quote_bars = qb.history[QuoteBar](btc_symbol, start_time, end_time, Resolution.MINUTE) ticks = qb.history[Tick](eth_symbol, start_time, end_time, Resolution.TICK) trade_bars_df = qb.history(TradeBar, btc_symbol, start_time, end_time, Resolution.DAILY) quote_bars_df = qb.history(QuoteBar, btc_symbol, start_time, end_time, Resolution.MINUTE) ticks_df = qb.history(eth_symbol, start_time, end_time, Resolution.TICK) df = qb.history(btc_symbol, start_time, end_time, Resolution.HOUR) # Includes trade and quote data
// EXAMPLE 6: Requesting By a Defined Period: 3 days of data with a specific resolution: var tradeBars = qb.History<TradeBar>(btcSymbol, startTime, endTime, Resolution.Daily); var quoteBars = qb.History<QuoteBar>(btcSymbol, startTime, endTime, Resolution.Minute); var ticks = qb.History<Tick>(ethSymbol, startTime, endTime, Resolution.Tick); var tradeBars2 = qb.History(btcSymbol, startTime, endTime, Resolution.Minute);
Multiple Symbol History Requests
To request history for multiple symbols at a time, pass an array of Symbol
objects to the same API methods shown in the preceding section. The return type of the method call depends on the history request [Type]
<Type>
. The following table describes the return type of each request [Type]
<Type>
:
Request Type | Return Data Type |
---|---|
No argument | DataFrame List<Slice> |
TradeBar | List[TradeBars] List<TradeBars> |
QuoteBar | List[QuoteBars] List<QuoteBars> |
Tick | List[Ticks] List<Ticks> |
alternativeDataClass (ex: CBOE ) | List[Dict[Symbol, alternativeDataClass]] (ex: List[Dict[Symbol, CBOE]] )List<Dictionary<Symbol, alternativeDataClass>> (ex: List<Dictionary<Symbol, CBOE>> ) |
The Slice
return type provides a container that supports all data types. For example, a history request for Forex QuoteBars
and Equity TradeBars
has the Forex data under slices.QuoteBars
and the Equity data under slices.Bars
.
# EXAMPLE 7: Requesting By Bar Count for Multiple Symbols: 2 bars at the security resolution: vix = qb.add_data[CBOE]("VIX", Resolution.DAILY).symbol v3m = qb.add_data[CBOE]("VIX3M", Resolution.DAILY).symbol cboe_data = qb.history[CBOE]([vix, v3m], 2) ibm = qb.add_equity("IBM", Resolution.MINUTE).symbol aapl = qb.add_equity("AAPL", Resolution.MINUTE).symbol trade_bars_list = qb.history[TradeBar]([ibm, aapl], 2) quote_bars_list = qb.history[QuoteBar]([ibm, aapl], 2) trade_bars_df = qb.history(TradeBar, [ibm, aapl], 2) quote_bars_df = qb.history(QuoteBar, [ibm, aapl], 2) df = qb.history([ibm, aapl], 2) # Includes trade and quote data
// EXAMPLE 7: Requesting By Bar Count for Multiple Symbols: 2 bars at the security resolution: var vixSymbol = qb.AddData<CBOE>("VIX", Resolution.Daily).Symbol; var v3mSymbol = qb.AddData<CBOE>("VIX3m", Resolution.Daily).Symbol; var cboeData = qb.History<CBOE>(new[] { vix, v3m }, 2); var ibm = qb.AddEquity("IBM", Resolution.Minute).Symbol; var aapl = qb.AddEquity("AAPL", Resolution.Minute).Symbol; var tradeBarsList = qb.History<TradeBar>(new[] { ibm, aapl }, 2); var quoteBarsList = qb.History<QuoteBar>(new[] { ibm, aapl }, 2);
# EXAMPLE 8: Requesting By Bar Count for Multiple Symbols: 5 bars with a specific resolution: trade_bars_list = qb.history[TradeBar]([ibm, aapl], 5, Resolution.DAILY) quote_bars_list = qb.history[QuoteBar]([ibm, aapl], 5, Resolution.MINUTE) trade_bars_df = qb.history(TradeBar, [ibm, aapl], 5, Resolution.DAILY) quote_bars_df = qb.history(QuoteBar, [ibm, aapl], 5, Resolution.MINUTE) df = qb.history([ibm, aapl], 5, Resolution.DAILY) # Includes trade data only. No quote for daily equity data
// EXAMPLE 8: Requesting By Bar Count for Multiple Symbols: 5 bars with a specific resolution: var tradeBarsList = qb.History<TradeBar>(new[] { ibm, aapl }, 5, Resolution.Minute); var quoteBarsList = qb.History<QuoteBar>(new[] { ibm, aapl }, 5, Resolution.Minute);
# EXAMPLE 9: Requesting By Trailing Period: 3 days of data at the security resolution: ticks = qb.history[Tick]([eth_symbol], timedelta(days=3)) trade_bars = qb.history[TradeBar]([btc_symbol], timedelta(days=3)) quote_bars = qb.history[QuoteBar]([btc_symbol], timedelta(days=3)) trade_bars_df = qb.history(TradeBar, [btc_symbol], timedelta(days=3)) quote_bars_df = qb.history(QuoteBar, [btc_symbol], timedelta(days=3)) df = qb.history([btc_symbol], timedelta(days=3)) # Includes trade and quote data
// EXAMPLE 9: Requesting By Trailing Period: 3 days of data at the security resolution: var ticks = qb.History<Tick>(new[] {ethSymbol}, TimeSpan.FromDays(3)); var tradeBars = qb.History<TradeBar>(new[] {btcSymbol}, TimeSpan.FromDays(3)); var quoteBars = qb.History<QuoteBar>(new[] {btcSymbol}, TimeSpan.FromDays(3)); var tradeBars2 = qb.History(new[] {btcSymbol}, TimeSpan.FromDays(3));
# EXAMPLE 10: Requesting By Defined Period: 3 days of data at the security resolution: trade_bars = qb.history[TradeBar]([btc_symbol], start_time, end_time) quote_bars = qb.history[QuoteBar]([btc_symbol], start_time, end_time) ticks = qb.history[Tick]([eth_symbol], start_time, end_time) trade_bars_df = qb.history(TradeBar, btc_symbol, start_time, end_time) quote_bars_df = qb.history(QuoteBar, btc_symbol, start_time, end_time) ticks_df = qb.history(Tick, eth_symbol, start_time, end_time) df = qb.history([btc_symbol], start_time, end_time) # Includes trade and quote data
// EXAMPLE 10: Requesting By Defined Period: 3 days of data at the security resolution: var tradeBars = qb.History<TradeBar>(new[] {btcSymbol}, startTime, endTime); var quoteBars = qb.History<QuoteBar>(new[] {btcSymbol}, startTime, endTime); var ticks = qb.History<Tick>(new[] {ethSymbol}, startTime, endTime); var tradeBars2 = qb.History(new[] {btcSymbol}, startTime, endTime);
If you request data for multiple securities and you use the Tick
TICK
request type, each Ticks
object in the list of results only contains the last tick of each security for that particular timeslice.
All Symbol History Requests
You can request history for all the securities you have created subscriptions for in your notebook session. The parameters are very similar to other history method calls, but the return type is an array of Slice objects. The Slice
object holds all of the results in a sorted enumerable collection that you can iterate over with a loop.
# EXAMPLE 11: Requesting 5 bars for all securities at their respective resolution: # Create subscriptions qb.add_equity("IBM", Resolution.DAILY) qb.add_equity("AAPL", Resolution.DAILY) # Request history data and enumerate results slices = qb.history(5) for s in slices: print(str(s.time) + " AAPL:" + str(s.bars["AAPL"].close) + " IBM:" + str(s.bars["IBM"].close))
// EXAMPLE 11: Requesting 5 bars for all securities at their respective resolution: // Set up the universe qb.AddEquity("IBM", Resolution.Daily); qb.AddEquity("AAPL", Resolution.Daily); // Request history data and enumerate results: var slices = qb.History(5); foreach (var s in slices) { var aaplClose = s.Bars["AAPL"].Close; var ibmClose = s.Bars["IBM"].Close; Console.WriteLine($"{s.Time} AAPL: {aaplClose} IBM: {ibmClose}"); }
# EXAMPLE 12: Requesting 5 minutes for all securities: slices = qb.history(timedelta(minutes=5), Resolution.MINUTE) for s in slices: print(str(s.time) + " AAPL:" + str(s.bars["AAPL"].close) + " IBM:" + str(s.bars["IBM"].close)) # timedelta history requests are relative to "now" in notebook Time. If you request this data at 16:05, it returns an empty array because the market is closed.
// EXAMPLE 12: Requesting 24 hours of hourly data for all securities: var slices = qb.History(TimeSpan.FromHours(24), Resolution.Hour); foreach (var s in slices) { var aaplClose = s.Bars["AAPL"].Close; var ibmClose = s.Bars["IBM"].Close; Console.WriteLine($"{s.Time} AAPL: {aaplClose} IBM: {ibmClose}"); } // TimeSpan history requests are relative to "now" in notebook Time.
Assumed Default Values
The following table describes the assumptions of the History API:
Argument | Assumption |
---|---|
Resolution | LEAN guesses the resolution you request by looking at the securities you already have in your notebook. If you have a security subscription in your notebook with a matching Symbol , the history request uses the same resolution as the subscription. If you don't have a security subscription in your notebook with a matching Symbol , Resolution.Minute Resolution.MINUTE is the default. |
Bar type | If you don't specify a type for the history request, TradeBar is the default. If the asset you request data for doesn't have TradeBar data, specify the QuoteBar type to receive history. |
Additional Options
The History
history
method accepts the following additional arguments:
Argument | Data Type | Description | Default Value |
---|---|---|---|
fillForward fill_forward | bool? bool/NoneType | True to fill forward missing data. Otherwise, false. If you don't provide a value, it uses the fill forward mode of the security subscription. | null None |
extendedMarketHours extended_market_hours | bool? bool/NoneType | True to include extended market hours data. Otherwise, false. | null None |
dataMappingMode data_mapping_mode | DataMappingMode? DataMappingMode/NoneType | The contract mapping mode to use for the security history request. | null None |
dataNormalizationMode data_normalization_mode | DataNormalizationMode? DataNormalizationMode/NoneType | The price scaling mode to use for US Equities or continuous Futures contracts. If you don't provide a value, it uses the data normalization mode of the security subscription. | null None |
contractDepthOffset contract_depth_offset | int? int/NoneType | The desired offset from the current front month for continuous Futures contracts. | null None |
future = qb.add_future(Futures.Currencies.BTC) history = qb.history( tickers=[future.symbol], start=qb.time - timedelta(days=15), end=qb.time, resolution=Resolution.MINUTE, fill_forward=False, extended_market_hours=False, dataMappingMode=DataMappingMode.OPEN_INTEREST, dataNormalizationMode=DataNormalizationMode.RAW, contractDepthOffset=0)
var future = qb.AddFuture(Futures.Currencies.BTC); var history = qb.History( symbols: new[] {future.Symbol}, start: qb.Time - TimeSpan.FromDays(15), end: qb.Time, resolution: Resolution.Minute, fillForward: false, extendedMarketHours: false, dataMappingMode: DataMappingMode.OpenInterest, dataNormalizationMode: DataNormalizationMode.Raw, contractDepthOffset: 0);
Resolutions
Resolution is the duration of time that's used to sample a data source. The Resolution
enumeration has the following members:
The default resolution for market data is Minute
MINUTE
. To set the resolution for a security, pass the resolution
argument when you create the security subscription.
qb.AddEquity("SPY", Resolution.Daily);
qb.add_equity("SPY", Resolution.DAILY)
When you request historical data, the History
history
method uses the resolution of your security subscription. To get historical data with a different resolution, pass a resolution
argument to the History
history
method.
history = qb.history(spy, 10, Resolution.MINUTE)
var history = qb.history(spy, 10, Resolution.MINUTE);
Markets
The datasets integrated into the Dataset Market cover many markets. The Market
enumeration has the following members:
LEAN can usually determine the correct market based on the ticker you provide when you create the security subscription. To manually set the market for a security, pass a market
argument when you create the security subscription.
qb.AddEquity("SPY", market: Market.USA);
qb.add_equity("SPY", market=Market.USA)
Fill Forward
Fill forward means if there is no data point for the current sample, LEAN uses the previous data point. Fill forward is the default data setting. To disable fill forward for a security, set the fillForward
fill_forward
argument to false when you create the security subscription.
qb.AddEquity("SPY", fillForward: false);
qb.add_equity("SPY", fill_forward=False)
When you request historical data, the History
history
method uses the fill forward setting of your security subscription. To get historical data with a different fill forward setting, pass a fillForward
fill_forward
argument to the History
history
method.
var history = qb.History(qb.Securities.Keys, qb.Time-TimeSpan.FromDays(10), qb.Time, fillForward: true);
history = qb.history(qb.securities.keys(), qb.time-timedelta(days=10), qb.time, fillForward=True)
Extended Market Hours
By default, your security subscriptions only cover regular trading hours. To subscribe to pre and post-market trading hours for a specific asset, enable the extendedMarketHours
extended_market_hours
argument when you create the security subscription.
AddEquity("SPY", extendedMarketHours: true);
self.add_equity("SPY", extended_market_hours=True)
You only receive extended market hours data if you create the subscription with minute, second, or tick resolution. If you create the subscription with daily or hourly resolution, the bars only reflect the regular trading hours.
When you request historical data, the History
history
method uses the extended market hours setting of your security subscription. To get historical data with a different extended market hours setting, pass an extendedMarketHours
extended_market_hours
argument to the History
history
method.
var history = qb.History(qb.Securities.Keys, qb.Time-TimeSpan.FromDays(10), qb.Time, extendedMarketHours: false);
history = qb.history(qb.securities.keys(), qb.time-timedelta(days=10), qb.time, extended_market_hours=False)
Look-Ahead Bias
In the Research Environment, all the historical data is directly available. In backtesting, you can only access the data that is at or before the algorithm time. If you make a history request for the previous 10 days of data in the Research Environment, you get the previous 10 days of data from today's date. If you request the same data in a backtest, you get the previous 10 days of data from the algorithm time.
Consolidate Data
History requests usually return data in one of the standard resolutions. To analyze data on custom time frames like 5-minute bars or 4-hour bars, you need to aggregate it. Consider an example where you make a history call for minute resolution data and want to create 5-minute resolution data.
qb = QuantBook() symbol = qb.add_equity("SPY").symbol start_date = datetime(2018, 4, 1) end_date = datetime(2018, 7, 15) history = qb.history(symbol, start_date, end_date, Resolution.MINUTE)
var qb = new QuantBook(); var symbol = qb.AddEquity("SPY").Symbol; var startDate = new DateTime(2018, 4, 1); var endDate = new DateTime(2018, 7, 15); var history = qb.History(symbol, startDate, endDate, Resolution.Minute); foreach (var slice in history) { foreach (var key in slice.Keys) { Console.WriteLine($"{slice.Time} :: {slice[key].ToString()}"); } }
To aggregate the data, use a consolidator or the pandas
resample method.
To aggregate the data, use a consolidator.
Consolidators
The following snippet demonstrates how to use a consolidator to aggregate data:
// Set up a consolidator and a RollingWindow to save the data var consolidator = new TradeBarConsolidator(TimeSpan.FromDays(7)); var window = new RollingWindow<TradeBar>(20); // Attach a consolidation handler method that saves the consolidated bars in the RollingWindow consolidator.DataConsolidated += (sender, consolidated) => { window.Add(consolidated); }; // Iterate the historical market data and feed each bar into the consolidator foreach(var bar in history) { consolidator.Update(bar); }
# Set up a consolidator and a RollingWindow to save the data consolidator = TradeBarConsolidator(timedelta(7)) window = RollingWindow[TradeBar](20) # Attach a consolidation handler method that saves the consolidated bars in the RollingWindow def on_data_consolidated(sender, bar): window.add(bar) consolidator.data_consolidated += on_data_consolidated # Iterate the historical market data and feed each bar into the consolidator for bar in history.itertuples(): tradebar = TradeBar(bar.index[1], bar.index[0], bar.open, bar.high, bar.low, bar.close, bar.volume) consolidator.update(tradebar)
Resample Method
The resample
method converts the frequency of a time series DataFrame into a custom frequency. The method only works on DataFrame objects that have a datetime
index. The History
history
method returns a DataFrame with a multi-index. The first index is a Symbol
index for each security and the second index is a time index for the timestamps of each row of data. To make the DataFrame compatible with the resample
method, call the reset_index method to drop the Symbol
index.
# Drop level 0 index (Symbol index) from the DataFrame history.reset_index(level = 0, drop = True, inplace=True)
The resample
method returns a Resampler
object, which needs to be downsampled using one of the pandas downsampling computations. For example, you can use the Resampler.ohlc downsampling method to aggregate price data.
When you resample a DataFrame with the ohlc
downsampling method, it creates an OHLC row for each column in the DataFrame. To just calculate the OHLC of the close column, select the close column before you resample the DataFrame. A resample offset of 5T corresponds to a 5-minute resample. Other resampling offsets include 2D = 2 days, 5H = 5 hours, and 3S = 3 seconds.
close_prices = history["close"] offset = "5T" close_5min_ohlc = close_prices.resample(offset).ohlc()
Common Errors
If the history request returns an empty DataFrame and you try to slice it, it throws an exception. To avoid issues, check if the DataFrame contains data before slicing it.
df = qb.history(symbol, 10).close # raises exception if the request is empty def get_safe_history_closes(symbols): if not symbols: print(f'No symbols') return False, None df = qb.history(symbols, 100, Resolution.DAILY) if df.empty: print(f'Empy history for {symbols}') return False, None return True, df.close.unstack(0)
If you run the Research Environment on your local machine and history requests return no data, check if your data directory contains the data you request. To download datasets, see Download.