# 市场数据源 (/zh/features/data/market-data-sources)

从哪里获取市场数据，每个提供商都要单独写代码吗？VBT 让您在 Python 中从 Yahoo Finance、Binance、CCXT
交易所、Alpaca、Polygon、Databento、TradingView 等来源下载股票、加密货币、期货和外汇数据，使用相同的 `pull`、`update` 调用，并最终获得同样的数据对象。

```python title="Download one year of Bitcoin from Binance and from Yahoo Finance"
>>> 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)  # (1)
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: float64
```

1.  两个日收盘价的差距，占价格的比例。

两个提供商、两个标的、相同的调用形式。通常两者收盘价相差 0.04%，最大达 0.36%，因为各来源分别聚合自己的成交。请使用您实际交易所依据的数据回测。

## 所有提供商使用同一接口 \[#one-interface-for-every-provider]

每个提供商类都有相同方法。`pull` 按日期区间和周期下载一个或多个标的，将长区间拆为提供商需要的多次请求。`update` 只获取新增内容并追加。结果是包含所有标的和特征的 `Data`
对象，可保存到磁盘，并直接供指标和回测使用：

```python title="Download several symbols and update them later"
>>> 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")  # (1)
>>> data.close.shape
(124, 3)
```

1.  从最后一根已存 K 线开始获取，并追加新行。

数据对象从不原地修改，因此请对 `update` 的结果赋值。多数提供商从最后一根已存 K 线而非其下一根开始，因为下载时该 K 线可能尚未完成，需要用提供商当前版本替换。

日期可以是时间戳、字符串或 `"30 days ago"` 等短语，结束日期不包含在结果内。某个标的失败会终止拉取，除非设置
`skip_on_error=True`，以发出警告并跳过它。请求间延迟可让大量下载符合提供商速率限制。

## 支持的提供商 \[#supported-providers]

| 提供商                   | 类                 | 市场                     |
| --------------------- | ----------------- | ---------------------- |
| Yahoo Finance         | `vbt.YFData`      | 股票、ETF、指数、外汇、加密货币      |
| Binance               | `vbt.BinanceData` | 加密货币现货和期货              |
| CCXT                  | `vbt.CCXTData`    | 超过 100 家交易所的加密货币       |
| Alpaca                | `vbt.AlpacaData`  | 美股、加密货币、期权             |
| Massive（原 Polygon.io） | `vbt.PolygonData` | 股票、外汇、加密货币             |
| Databento             | `vbt.BentoData`   | 期货、股票、期权               |
| Alpha Vantage         | `vbt.AVData`      | 股票、外汇、加密货币及其他接口        |
| Nasdaq Data Link      | `vbt.NDLData`     | 数据集和数据表                |
| TradingView           | `vbt.TVData`      | TradingView 图表涵盖的大多数市场 |
| findatapy             | `vbt.FinPyData`   | 多个来源，包括 Dukascopy 逐笔数据 |

需要账户的服务，VBT 使用您自己的提供商账户连接。数据订阅独立于 VBT PRO。使用 Python
客户端的类可以为您配置客户端，也可复用已有客户端，保留当前凭据和连接设置。付费提供商有自己的限制和收费，`vbt.BentoData` 可在请求前估算 Databento 成本。它使用
Databento 历史 API，而非实时行情流。

[Polygon.io 现已更名为 Massive](https://www.massive.com/blog/polygon-is-now-massive)。VBT 类仍名为
`vbt.PolygonData`，如下方示例。

## 选择市场数据源 \[#choosing-a-market-data-source]

先确定策略需要的交易品种、历史长度和分辨率。许多投资组合研究使用日 K 线即可。日内策略可能需要分钟 K 线、逐笔成交或买卖报价。下方 [Databento](#databento) 和
[FinDataPy](#findatapy) 示例展示 OHLCV 之外的数据，包括最优买卖报价（BBO）和外汇逐笔数据。

然后选择覆盖市场和日期区间的行情源及订阅。同一标的在不同提供商处，价格、交易时段或调整方式可能不同。即使开头的比特币比较，也在 Binance 使用 USDT 交易对，在 Yahoo
使用美元价格。统一接口便于比较来源，而实际接收哪些观测由提供商决定。

已有数据订阅或一组 DataFrame？也可以将其引入 VBT，详见[自定义提供商](#custom-providers)部分。

## 加密货币 \[#crypto]

`vbt.BinanceData` 下载现货 K 线，并通过 `klines_type` 支持 U 本位和币本位期货，如
[Binance 数据](/zh/features/data/binance-data/)页面所示。`vbt.CCXTData` 以相同参数连接 CCXT
支持的任意交易所，还能查找交易所仍提供数据的最早日期，因为许多交易所在请求起点早于其历史时不会返回数据。

## 股票、期货和外汇 \[#stocks-futures-and-fx]

Yahoo Finance 是获取日频股票数据最快捷的起点。其价格默认对拆股和股息进行调整，适合计算收益；`auto_adjust=False` 可禁用自动调整，并将调整后收盘价保留为独立特征。VBT
不自行调整价格，因此跨拆股回测时请使用复权数据，或事先调整。对于日内历史、深度数据或期货，表中商业提供商提供更多选择，下方各节分别展示。

您也可以拉取市场价格以外的输入。Alpha Vantage 可返回指标，例如下方[随机 RSI 示例](#alpha-vantage)。Nasdaq Data Link
同时支持时间序列数据集和数据表，通过 `data_format="datatable"`
选择后者，表筛选条件会传给提供商。这让您可以将经济和基本面数据集与价格一起研究。[数据流水线](/zh/features/data/financial-data-pipelines/)介绍如何为策略准备和对齐数据。

## TradingView \[#tradingview]

`vbt.TVData` 无需账户，即可按 `NASDAQ:AAPL`、`BINANCE:BTCUSDT` 等 TradingView 表示法下载股票、期货、加密货币、外汇和指数 K
线。[TradingView 数据](/zh/features/data/tradingview-data/)页面介绍周期、交易时段、标的搜索和历史限制。

## 查找交易标的 \[#finding-symbols]

大多数提供商通过 `list_symbols` 列出标的，并用 glob 通配符或正则表达式筛选；TradingView 还可列出指数成分股：

```python title="List Binance symbols that match a pattern"
>>> vbt.BinanceData.list_symbols("BTC*USDT")
['BTCDOWNUSDT', 'BTCSTUSDT', 'BTCUPUSDT', 'BTCUSDT']
```

标的可标注行业或资产类型等类别，并成为分组的列层级，如下方[标的类别](#symbol-classes)功能介绍所示。

## 自定义提供商 \[#custom-providers]

数据不必来自内置提供商。可以直接将 Pandas 价格用于指标和回测，也可用 `vbt.Data.from_data` 转换为 `Data` 对象。这里是使用虚构收盘价的小示例，每个资产一列：

```python title="Use prices already in Pandas"
>>> 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: float64
```

相同方法也适用于其他 Python 数据处理库或您自己的加载器返回的 DataFrame。保留现有数据源，让 VBT 负责之后的研究。

任意 API 都能成为提供商。继承 `vbt.RemoteData`，实现单个标的的获取方式，即可继承多标的拉取、更新、保存和本页所有其他能力。URL
后方或云存储桶中的文件，可使用[数据存储与数据库](/zh/features/data/data-storage-and-databases/)页面的文件类读取。

## FinDataPy \[#findatapy]

新增于 v2024.8.20

✅ 介绍用于 [findatapy](https://github.com/cuemacro/findatapy) 的新类，可从 Bloomberg、Eikon、Quandl、Dukascopy
等来源拉取数据。

```python title="Discover tickers on Dukascopy and pull one day of tick data"
>>> 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(  # (1)
...     "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(  # (2)
...     "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]
```

1.  字符串格式。
2.  关键词格式。

## Databento \[#databento]

新增于 v2023.12.23

✅ 介绍专门从 [Databento](https://databento.com/) 拉取数据的新类。

```python title="Get best bid and offer (BBO) 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-05

>>> data = 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
```

## 标的搜索 \[#symbol-search]

新增于 1.7.0

✅ 大多数数据类可以获取交易所全部可用标的列表，并可选使用
[glob 通配符](https://en.wikipedia.org/wiki/Glob_\(programming\))或[正则表达式](https://en.wikipedia.org/wiki/Regular_expression)模式筛选。这也适用于本地数据类。

```python title="Get all XRP pairs listed on Binance"
>>> 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']
```

## 标的类别 \[#symbol-classes]

新增于 1.7.0

✅ 由于 VBT 使用 Pandas 多级索引，您可将每个标的关联到一个或多个类别，例如行业。这让您能够按类别分析交易策略表现。

```python title="Compare equal-weighted portfolios for three sectors"
>>> 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}),  # (1)
...     size_type="targetpercent",
...     group_by="sector",
...     cash_sharing=True
... )
>>> pf.value.vbt.plot().show()
```

1.  每组有三个资产，在第一根 K 线上各分配 33.3%。

等权重科技、金融和零售投资组合价值随时间变化. [Figure data (JSON)](/assets/figures/features/data/classes.dc2278f36b04.json)

## Polygon.io \[#polygonio]

新增于 1.1.1

✅ 欢迎使用专门从 [Polygon.io](https://polygon.io/) 拉取数据的新类！

```python title="Get one month of 30-minute AAPL 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",  # (1)
...     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]
```

1.  使用通过 `tz` 提供的时区。

## Alpha Vantage \[#alpha-vantage]

新增于 1.1.1

✅ 欢迎使用专门从 [Alpha Vantage](https://www.alphavantage.co/) 拉取数据的新类！

```python title="Get Stochastic RSI of IBM 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]
```

## Nasdaq Data Link \[#nasdaq-data-link]

新增于 1.1.1

✅ 欢迎使用专门从 [Nasdaq Data Link](https://data.nasdaq.com/) 拉取数据的新类！

```python title="Get Index of Consumer Sentiment 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]
```

## Alpaca \[#alpaca]

新增于 1.0.2

✅ 欢迎使用专门从 [Alpaca](https://alpaca.markets/) 拉取数据的新类！

```python title="Get one week of adjusted 1-minute AAPL 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",  # (1)
...     end="15 minutes ago",  # (2)
...     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]
```

1.  使用通过 `tz` 提供的时区。
2.  如果拥有付费方案，请移除。
