Features
Market data sources
Pull stock, crypto, futures, and FX data from many providers with one interface
Where can you get market data, and does every provider need its own code? VBT lets you download
stock, crypto, futures, and FX data in Python from Yahoo Finance, Binance, CCXT exchanges, Alpaca,
Polygon, Databento, TradingView, and more, with the same pull and update calls and the same data
object at the end.
kwargs = dict(start="2024-01-01", end="2025-01-01", timeframe="1d")
binance = vbt.BinanceData.pull("BTCUSDT", **kwargs)
yahoo = vbt.YFData.pull("BTC-USD", **kwargs)
close = pd.concat({"Binance": binance.close, "Yahoo": yahoo.close}, axis=1)
close.head(3).round(2) Binance Yahoo
2024-01-01 00:00:00+00:00 44179.55 44167.33
2024-01-02 00:00:00+00:00 44946.91 44957.97
2024-01-03 00:00:00+00:00 42845.23 42848.18(close["Yahoo"] / close["Binance"] - 1).abs().describe().round(5) count 366.00000
mean 0.00061
std 0.00056
min 0.00000
25% 0.00020
50% 0.00042
75% 0.00086
max 0.00363
dtype: float64Two providers, two symbols, one call shape. Their closes differ by 0.04% on a typical day and by up to 0.36%, because each source aggregates its own trades. Backtest on the data you will trade.
One interface for every provider
Every provider class has the same methods. pull downloads one or many symbols for a date range and
timeframe, splitting long ranges into as many requests as the provider needs. update fetches only
what is new and appends it. The result is a Data object that holds every symbol and feature, saves
to disk, and feeds indicators and backtests directly:
data = vbt.YFData.pull(["SPY", "QQQ", "TLT"], start="2024-01-01", end="2024-06-01")
data.symbols, data.close.shape(['SPY', 'QQQ', 'TLT'], (105, 3))data = data.update(end="2024-07-01")
data.close.shape(124, 3)Data objects never change in place, so assign the result of update. With most providers, it starts
from the last stored bar, not the bar after it, because that bar may have been incomplete when it
was downloaded, and replaces it with the provider's current version.
Dates can be timestamps, strings, or phrases such as "30 days ago", and the end date is exclusive.
A symbol that fails stops the pull unless skip_on_error=True, which skips it with a warning, and a
delay between requests keeps a large download within a provider's rate limit.
Supported providers
| Provider | Class | Markets |
|---|---|---|
| Yahoo Finance | vbt.YFData | Stocks, ETFs, indexes, FX, crypto |
| Binance | vbt.BinanceData | Crypto spot and futures |
| CCXT | vbt.CCXTData | Crypto on more than 100 exchanges |
| Alpaca | vbt.AlpacaData | US stocks, crypto, options |
| Massive (formerly Polygon.io) | vbt.PolygonData | Stocks, FX, crypto |
| Databento | vbt.BentoData | Futures, equities, options |
| Alpha Vantage | vbt.AVData | Stocks, FX, crypto, and other endpoints |
| Nasdaq Data Link | vbt.NDLData | Datasets and data tables |
| TradingView | vbt.TVData | Most markets that TradingView charts |
| findatapy | vbt.FinPyData | Several sources, including Dukascopy tick data |
VBT connects to these services using your provider account where one is required. Data subscriptions
are separate from VBT PRO. Classes that use a Python client can configure it for you or reuse an
existing client, so you can keep your current credentials and connection setup. Paid providers apply
their own limits and charges, and vbt.BentoData can estimate the cost of a Databento request
before you run it. It uses Databento's historical API, not its live feed.
Polygon.io is now Massive. The VBT class is
still named vbt.PolygonData, as in the example below.
Choosing a market data source
Start with the instruments, history, and resolution your strategy needs. Daily bars are enough for many portfolio studies. An intraday strategy may need minute bars, individual trades, or bid and ask prices. The Databento and FinDataPy examples below show data beyond OHLCV, including BBO and FX ticks.
Then choose the feed and subscription that cover your market and date range. The same symbol can have different prices, sessions, or adjustments across providers. Even the opening Bitcoin comparison uses a USDT pair on Binance and USD prices on Yahoo. A common interface makes it easier to compare sources, while the provider determines which observations you receive.
Already have a data subscription or a collection of DataFrames? You can bring those into VBT too, as the custom providers section shows.
Crypto
vbt.BinanceData downloads spot klines and, with klines_type, USD-margined and coin-margined
futures, as the Binance data page shows. vbt.CCXTData reaches any
exchange that CCXT supports with the same arguments, and can search for the earliest date an
exchange still serves, since many exchanges return nothing for a range that starts before their
history does.
Stocks, futures, and FX
Yahoo Finance is the quickest start for daily stock data. Its prices are adjusted for splits and
dividends by default, which is right for returns, while auto_adjust=False disables that automatic
adjustment and keeps the adjusted close as a separate feature. VBT does not adjust prices itself, so
use adjusted data, or adjust it before backtesting across a split. For intraday history, depth, or
futures, the commercial providers in the table offer more choices, and their sections below show
each one.
You can also pull inputs beyond market prices. Alpha Vantage can return indicators such as the
Stochastic RSI example below. Nasdaq Data Link supports both time-series datasets
and datatables, selected with data_format="datatable", with table filters passed through to the
provider. This opens up research with economic and fundamental datasets alongside prices.
Data pipelines covers preparing and aligning the data
for your strategy.
TradingView
vbt.TVData downloads bars for symbols in TradingView's notation, such as NASDAQ:AAPL or
BINANCE:BTCUSDT, across stocks, futures, crypto, FX, and indexes, without an account. The
TradingView data page covers timeframes, sessions, symbol
search, and history limits.
Finding symbols
Most providers can list their symbols with list_symbols, filtered with a glob or a regular
expression, and TradingView can also list the members of an index:
vbt.BinanceData.list_symbols("BTC*USDT")['BTCDOWNUSDT', 'BTCSTUSDT', 'BTCUPUSDT', 'BTCUSDT']Symbols can be tagged with classes such as sector or asset type, which become column levels for grouping, as the Symbol classes highlight below shows.
Custom providers
Your data does not have to come from a built-in provider. Use Pandas prices directly in indicators
and backtests, or turn them into a Data object with vbt.Data.from_data. Here is a small example
with made-up closing prices, one column per asset:
existing_close = pd.DataFrame(
{"Asset A": [100.0, 102.0, 105.0], "Asset B": [50.0, 49.0, 51.0]},
index=pd.date_range("2024-01-01", periods=3, freq="D", tz="UTC"),
)
existing_data = vbt.Data.from_data(existing_close, columns_are_symbols=True)
existing_data.symbols['Asset A', 'Asset B']existing_pf = vbt.PF.from_holding(existing_data.get())
existing_pf.total_return.round(4)Asset A 0.05
Asset B 0.02
Name: total_return, dtype: float64The same approach works with DataFrames returned by another Python data library or your own loader. Keep your existing data source and use VBT for the research that follows.
Any API can become a provider. Subclass vbt.RemoteData, implement how one symbol is fetched, and
the class inherits pulling many symbols, updating, saving, and everything else on this page. Files
behind a URL or in a cloud bucket can be read with the file classes on the
Data storage and databases page.
✅ Introducing a new class for findatapy, designed to pull data from Bloomberg, Eikon, Quandl, Dukascopy, and other data sources.
vbt.FinPyData.list_symbols(data_source="dukascopy")['fx.dukascopy.tick.NYC.AUDCAD',
'fx.dukascopy.tick.NYC.AUDCHF',
'fx.dukascopy.tick.NYC.AUDJPY',
...
'fx.dukascopy.tick.NYC.USDTRY',
'fx.dukascopy.tick.NYC.USDZAR',
'fx.dukascopy.tick.NYC.ZARJPY']data = vbt.FinPyData.pull(
"fx.dukascopy.tick.NYC.EURUSD",
start="14 Jun 2016",
end="15 Jun 2016"
)
data.get() close
Date
2016-06-14 00:00:00.844000+00:00 1.128795
2016-06-14 00:00:01.591000+00:00 1.128790
2016-06-14 00:00:01.743000+00:00 1.128775
2016-06-14 00:00:02.464000+00:00 1.128770
2016-06-14 00:00:02.971000+00:00 1.128760
... ...
2016-06-14 23:59:57.733000+00:00 1.121020
2016-06-14 23:59:58.239000+00:00 1.121030
2016-06-14 23:59:58.953000+00:00 1.121035
2016-06-14 23:59:59.004000+00:00 1.121050
2016-06-14 23:59:59.934000+00:00 1.121055
[82484 rows x 1 columns]data = vbt.FinPyData.pull(
"EURUSD",
start="14 Jun 2016",
end="15 Jun 2016",
timeframe="tick",
category="fx",
data_source="dukascopy",
fields=["bid", "ask", "bidv", "askv"]
)
data.get() bid ask bidv askv
Date
2016-06-14 00:00:00.844000+00:00 1.12877 1.12882 1.00 10.12
2016-06-14 00:00:01.591000+00:00 1.12877 1.12881 1.00 1.00
2016-06-14 00:00:01.743000+00:00 1.12875 1.12880 3.11 3.00
2016-06-14 00:00:02.464000+00:00 1.12875 1.12879 2.21 1.00
2016-06-14 00:00:02.971000+00:00 1.12875 1.12877 2.21 1.00
... ... ... ... ...
2016-06-14 23:59:57.733000+00:00 1.12100 1.12104 1.24 1.50
2016-06-14 23:59:58.239000+00:00 1.12101 1.12105 9.82 1.12
2016-06-14 23:59:58.953000+00:00 1.12102 1.12105 1.50 1.12
2016-06-14 23:59:59.004000+00:00 1.12103 1.12107 1.50 1.12
2016-06-14 23:59:59.934000+00:00 1.12103 1.12108 1.87 2.25
[82484 rows x 4 columns]✅ Introducing a new class specialized in pulling data from Databento.
vbt.BentoData.set_custom_settings(
client_config=dict(
key="YOUR_KEY"
)
)
params = dict(
symbols="ESH3",
dataset="GLBX.MDP3",
start=vbt.timestamp("2022-10-28 20:30:00"),
end=vbt.timestamp("2022-10-28 21:00:00"),
schema="tbbo"
)
vbt.BentoData.get_cost(**params)1.2002885341644287e-05data = vbt.BentoData.pull(**params)
data.get() ts_event \
ts_recv
2022-10-28 20:30:59.047138053+00:00 2022-10-28 20:30:59.046914657+00:00
2022-10-28 20:37:53.112494436+00:00 2022-10-28 20:37:53.112246421+00:00
...
2022-10-28 20:59:15.075191111+00:00 2022-10-28 20:59:15.074953895+00:00
2022-10-28 20:59:34.607239899+00:00 2022-10-28 20:59:34.606984277+00:00
rtype publisher_id instrument_id \
ts_recv
2022-10-28 20:30:59.047138053+00:00 1 1 206299
2022-10-28 20:37:53.112494436+00:00 1 1 206299
...
2022-10-28 20:59:15.075191111+00:00 1 1 206299
2022-10-28 20:59:34.607239899+00:00 1 1 206299
action side depth price size flags \
ts_recv
2022-10-28 20:30:59.047138053+00:00 T B 0 3955.25 1 0
2022-10-28 20:37:53.112494436+00:00 T A 0 3955.00 1 0
...
2022-10-28 20:59:15.075191111+00:00 T A 0 3953.75 1 0
2022-10-28 20:59:34.607239899+00:00 T A 0 3954.50 2 0
ts_in_delta sequence bid_px_00 \
ts_recv
2022-10-28 20:30:59.047138053+00:00 18553 73918214 3954.75
2022-10-28 20:37:53.112494436+00:00 18334 73926240 3955.00
...
2022-10-28 20:59:15.075191111+00:00 19294 73945515 3953.75
2022-10-28 20:59:34.607239899+00:00 18701 73945932 3954.50
ask_px_00 bid_sz_00 ask_sz_00 \
ts_recv
2022-10-28 20:30:59.047138053+00:00 3955.25 1 1
2022-10-28 20:37:53.112494436+00:00 3955.75 1 1
...
2022-10-28 20:59:15.075191111+00:00 3956.00 1 1
2022-10-28 20:59:34.607239899+00:00 3956.00 4 1
bid_ct_00 ask_ct_00 symbol
ts_recv
2022-10-28 20:30:59.047138053+00:00 1 1 ESH3
2022-10-28 20:37:53.112494436+00:00 1 1 ESH3
...
2022-10-28 20:59:15.075191111+00:00 1 1 ESH3
2022-10-28 20:59:34.607239899+00:00 3 1 ESH3✅ Most data classes can retrieve the complete list of symbols available for an exchange, and optionally filter the list using a globbing or regular expression pattern. This also works for local data classes.
vbt.BinanceData.list_symbols("XRP*")['XRPAUD',
'XRPBEARBUSD',
'XRPBEARUSDT',
'XRPBIDR',
'XRPBKRW',
'XRPBNB',
'XRPBRL',
'XRPBTC',
'XRPBULLBUSD',
'XRPBULLUSDT',
'XRPBUSD',
'XRPDOWNUSDT',
'XRPETH',
'XRPEUR',
'XRPGBP',
'XRPNGN',
'XRPPAX',
'XRPRUB',
'XRPTRY',
'XRPTUSD',
'XRPUPUSDT',
'XRPUSDC',
'XRPUSDT']✅ Since VBT uses multi-indexes in Pandas, you can associate each symbol with one or more classes, such as sectors. This allows you to analyze the performance of a trading strategy relative to each class.
classes = vbt.symbol_dict({
"MSFT": dict(sector="Technology"),
"GOOGL": dict(sector="Technology"),
"META": dict(sector="Technology"),
"JPM": dict(sector="Finance"),
"BAC": dict(sector="Finance"),
"WFC": dict(sector="Finance"),
"AMZN": dict(sector="Retail"),
"WMT": dict(sector="Retail"),
"BABA": dict(sector="Retail"),
})
data = vbt.YFData.pull(
list(classes.keys()),
classes=classes,
missing_index="drop"
)
pf = vbt.PF.from_orders(
data,
size=vbt.index_dict({0: 1 / 3}),
size_type="targetpercent",
group_by="sector",
cash_sharing=True
)
pf.value.vbt.plot().show()✅ Welcome a new class specialized in pulling data from Polygon.io!
vbt.PolygonData.set_custom_settings(
client_config=dict(
api_key="YOUR_API_KEY"
)
)
data = vbt.PolygonData.pull(
"AAPL",
start="2022-12-01",
end="2023-01-01",
timeframe="30 minutes",
tz="US/Eastern"
)
data.get() Open High Low Close Volume \
Open time
2022-12-01 04:00:00-05:00 148.08 148.08 147.04 147.3700 50886.0
2022-12-01 04:30:00-05:00 147.37 147.37 147.12 147.2600 16575.0
2022-12-01 05:00:00-05:00 147.31 147.51 147.20 147.3800 20753.0
2022-12-01 05:30:00-05:00 147.43 147.56 147.38 147.3800 7388.0
2022-12-01 06:00:00-05:00 147.30 147.38 147.24 147.2400 7416.0
... ... ... ... ... ...
2022-12-30 17:30:00-05:00 129.94 130.05 129.91 129.9487 35694.0
2022-12-30 18:00:00-05:00 129.95 130.00 129.94 129.9500 15595.0
2022-12-30 18:30:00-05:00 129.94 130.05 129.94 130.0100 20287.0
2022-12-30 19:00:00-05:00 129.99 130.04 129.99 130.0000 12490.0
2022-12-30 19:30:00-05:00 130.00 130.04 129.97 129.9700 28271.0
Trade count VWAP
Open time
2022-12-01 04:00:00-05:00 1024 147.2632
2022-12-01 04:30:00-05:00 412 147.2304
2022-12-01 05:00:00-05:00 306 147.3466
2022-12-01 05:30:00-05:00 201 147.4818
2022-12-01 06:00:00-05:00 221 147.2938
... ... ...
2022-12-30 17:30:00-05:00 350 129.9672
2022-12-30 18:00:00-05:00 277 129.9572
2022-12-30 18:30:00-05:00 312 130.0034
2022-12-30 19:00:00-05:00 176 130.0140
2022-12-30 19:30:00-05:00 366 129.9941
[672 rows x 7 columns]✅ Welcome a new class specialized in pulling data from Alpha Vantage!
data = vbt.AVData.pull(
"IBM",
category="technical-indicators",
function="STOCHRSI",
params=dict(fastkperiod=14)
)
data.get() FastD FastK
1999-12-07 00:00:00+00:00 100.0000 100.0000
1999-12-08 00:00:00+00:00 100.0000 100.0000
1999-12-09 00:00:00+00:00 77.0255 31.0765
1999-12-10 00:00:00+00:00 43.6922 0.0000
1999-12-13 00:00:00+00:00 12.0197 4.9826
... ... ...
2023-01-26 00:00:00+00:00 11.7960 0.0000
2023-01-27 00:00:00+00:00 3.7773 0.0000
2023-01-30 00:00:00+00:00 4.4824 13.4471
2023-01-31 00:00:00+00:00 7.8258 10.0302
2023-02-01 16:00:01+00:00 13.0966 15.8126
[5826 rows x 2 columns]✅ Welcome a new class specialized in pulling data from Nasdaq Data Link!
data = vbt.NDLData.pull("UMICH/SOC1")
data.get() Index
Date
1952-11-30 00:00:00+00:00 86.2
1953-02-28 00:00:00+00:00 90.7
1953-08-31 00:00:00+00:00 80.8
1953-11-30 00:00:00+00:00 80.7
1954-02-28 00:00:00+00:00 82.0
... ...
2022-08-31 00:00:00+00:00 58.2
2022-09-30 00:00:00+00:00 58.6
2022-10-31 00:00:00+00:00 59.9
2022-11-30 00:00:00+00:00 56.8
2022-12-31 00:00:00+00:00 59.7
[632 rows x 1 columns]✅ Welcome a new class specialized in pulling data from Alpaca!
vbt.AlpacaData.set_custom_settings(
client_config=dict(
api_key="YOUR_API_KEY",
secret_key="YOUR_API_SECRET"
)
)
data = vbt.AlpacaData.pull(
"AAPL",
start="one week ago 00:00",
end="15 minutes ago",
timeframe="1 minute",
adjustment="all",
tz="US/Eastern"
)
data.get() Open High Low Close Volume \
Open time
2023-01-30 04:00:00-05:00 145.5400 145.5400 144.0100 144.0200 5452.0
2023-01-30 04:01:00-05:00 144.0800 144.0800 144.0000 144.0500 3616.0
2023-01-30 04:02:00-05:00 144.0300 144.0400 144.0100 144.0100 1671.0
2023-01-30 04:03:00-05:00 144.0100 144.0300 144.0000 144.0300 4721.0
2023-01-30 04:04:00-05:00 144.0200 144.0200 144.0200 144.0200 1343.0
... ... ... ... ... ...
2023-02-03 19:54:00-05:00 154.3301 154.3301 154.3301 154.3301 347.0
2023-02-03 19:55:00-05:00 154.3300 154.3400 154.3200 154.3400 1438.0
2023-02-03 19:56:00-05:00 154.3400 154.3400 154.3300 154.3300 588.0
2023-02-03 19:58:00-05:00 154.3500 154.3500 154.3500 154.3500 555.0
2023-02-03 19:59:00-05:00 154.3400 154.3900 154.3300 154.3900 3835.0
Trade count VWAP
Open time
2023-01-30 04:00:00-05:00 165 144.376126
2023-01-30 04:01:00-05:00 81 144.036336
2023-01-30 04:02:00-05:00 52 144.035314
2023-01-30 04:03:00-05:00 56 144.012680
2023-01-30 04:04:00-05:00 40 144.021854
... ... ...
2023-02-03 19:54:00-05:00 21 154.331340
2023-02-03 19:55:00-05:00 38 154.331756
2023-02-03 19:56:00-05:00 17 154.338971
2023-02-03 19:58:00-05:00 27 154.343090
2023-02-03 19:59:00-05:00 58 154.357219
[4224 rows x 7 columns]Related pages
- TradingView dataPull TradingView bars for stocks, futures, crypto, and FX, and search its symbols
- Data pipelinesAlign, update, transform, and analyze multi-symbol market data in one object
- Data storage and databasesSave and query market data in files, DuckDB, SQL databases, and ArcticDB
- Binance dataDownload Binance spot and futures klines with trade counts and taker volume
Copyright © 2021–2026 Oleg Polakow. All rights reserved.
Site content and documentation are provided for using and evaluating VectorBT PRO and for educational purposes. Any other use, including building or supporting competing products or services, requires prior written consent.