Skip to main content

市场数据常见问题

机器翻译译自英文(docs.alpaca.markets)本页 80 段已全部译完

通用

为什么我收到 HTTP 403(禁止)?

如果以下任一条件为真,市场数据端点将返回 HTTP 403:

  • 请求未通过身份验证
  • 提供的凭证不正确
  • 通过身份验证的用户权限不足

要解决这些问题,有两个检查清单,一个用于普通用户,一个用于经纪合作伙伴。如果你不确定哪个适用于你,请查看此 FAQ。如果你仍然不确定,请检查你的访问密钥。如果它以字母 C 开头,那么你是经纪合作伙伴,否则你是普通用户。如果你还没有访问密钥,请在 Alpaca 仪表板 的右侧生成它。

普通用户检查清单

  • 确保你在以下 HTTP 标头中提供你的凭证:
    • APCA-API-KEY-ID
    • APCA-API-SECRET-KEY
  • 确保你的凭证有效:
    • 在 Web UI 上检查密钥
    • 当你重置模拟账户时,需要重新生成凭证
  • 确保主机为 data.alpaca.markets 用于历史数据 或 stream.data.alpaca.markets 用于实时数据
  • 如果你在 HTTP 响应正文中收到类似 subscription does not permit querying recent SIP data 的消息,请确保你有适当的 订阅
    • 例如,要查询最近 15 分钟内的任何 SIP 交易或报价,你需要 Algo Trader Plus 订阅

经纪合作伙伴检查清单

  • 确保你在 HTTP 基本身份验证 中提供你的凭证
  • 确保你的凭证有效
  • 确保你根据环境使用正确的主机:
  • 如果你在 HTTP 响应正文中收到类似 subscription does not permit querying recent SIP data 的消息,请确保你有适当的 订阅
    • 例如,要查询最近 15 分钟内的任何 SIP 交易或报价,你需要特殊订阅

如何订阅 AlgoTrader Plus?

你可以在 Alpaca UI 上订阅 AlgoTrader Plus:在主页面的左侧边栏中点击“Plans & Features”,然后在该页面的 Market Data 框中点击“Upgrade to AlgoTrader Plus”。

股票

IEX 和 SIP 数据有什么区别?

SIP 是 证券信息处理器 的缩写。所有美国交易所都被监管机构要求向合并磁带报告其活动(交易和报价)。这就是我们所说的 SIP 数据。

IEX(投资者交易所)是一家单一的证券交易所。

WebSocket 流

我们的免费市场数据产品仅包括来自 IEX 交易所的实时数据:

wss://stream.data.alpaca.markets/v2/iex

另一方面,Algo Trader Plus 订阅提供 SIP 数据:

wss://stream.data.alpaca.markets/v2/sip

历史数据

在历史端点上,使用 feed 参数在两个数据源之间切换:

$ curl -s -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" \
  "https://data.alpaca.markets/v2/stocks/AAPL/bars?feed=sip&timeframe=1Day&start=2023-09-29&limit=1" | jq .
{
  "bars": [
    {
      "t": "2023-09-29T04:00:00Z",
      "o": 172.02,
      "h": 173.07,
      "l": 170.341,
      "c": 171.21,
      "v": 51861083,
      "n": 535134,
      "vw": 171.599691
    }
  ],
  "symbol": "AAPL",
  "next_page_token": "QUFQTHxEfDIwMjMtMDktMjlUMDQ6MDA6MDAuMDAwMDAwMDAwWg=="
}
$ curl -s -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" \
  "https://data.alpaca.markets/v2/stocks/AAPL/bars?feed=iex&timeframe=1Day&start=2023-09-29&limit=1" | jq .
{
  "bars": [
    {
      "t": "2023-09-29T04:00:00Z",
      "o": 172.015,
      "h": 173.06,
      "l": 170.36,
      "c": 171.29,
      "v": 923134,
      "n": 12630,
      "vw": 171.716432
    }
  ],
  "symbol": "AAPL",
  "next_page_token": null
}

在此示例中(2023-09-29 Apple 日 K 线),你可以清楚地看到两个数据源之间的差异:当天 IEX 交易所有 12 630 笔符合条件的交易,而所有交易所总计超过 535 136 笔交易(自然包括 IEX)。它们的成交量之间也可以看到类似的差异。

所有最新端点(包括 snapshot 端点)都需要订阅才能与 SIP 源一起使用。对于历史查询,end 参数必须至少为 15 分钟前,才能在没有订阅的情况下查询 SIP 数据。feed 的默认值始终是基于用户订阅的“最佳”可用数据源。

$  curl -s -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" \
  "https://data.alpaca.markets/v2/stocks/AAPL/trades/latest" | jq .
{
  "symbol": "AAPL",
  "trade": {
    "t": "2023-09-29T19:59:59.246196362Z",
    "x": "V",  // << IEX exchange code
    "p": 171.29,
    "s": 172,
    "c": [
      "@"
    ],
    "i": 12727,
    "z": "C"
  }
}
$ curl -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" \
  "https://data.alpaca.markets/v2/stocks/AAPL/trades/latest?feed=sip"
{"code":42210000,"message":"subscription does not permit querying recent SIP data"}

在此示例中,我们在没有订阅的情况下查询最新的 AAPL 交易。在这种情况下,默认的 feed 是 iex。如果我们尝试查询 SIP 源,将会收到错误。要修复该错误,我们需要订阅 Algo Trader Plus。

为什么我找不到某个特定股票代码(例如 CGRNQ)的市场数据?

OTC

使用 assets 端点 确保该股票代码不在 OTC 交易。https://api.alpaca.markets/v2/assets/CGRNQ 返回

{
  "id": "dc2d8be9-33b5-4a32-8f57-5b7d209d2c82",
  "class": "us_equity",
  "exchange": "OTC", // << This symbol is traded in OTC
  "symbol": "CGRNQ",
  "name": "CAPSTONE GREEN ENERGY CORP COM PAR $.001",
  "status": "active",
  "tradable": false,
  "marginable": false,
  "maintenance_margin_requirement": 100,
  "shortable": true,
  "easy_to_borrow": true,
  "fractionable": true,
  "attributes": []
}

目前,OTC 股票代码的市场数据只能通过特殊订阅查询,该订阅仅面向经纪合作伙伴。如果你有该订阅,可以使用 feed=otc 查询数据。

不活跃

确保资产处于活跃状态。检查 同一端点 的 status 字段。

暂停

确保在你查询时该股票代码当前或曾经没有被暂停交易。你可以在 Nasdaq 网站上查看 当前暂停 或 历史暂停。例如,股票代码 SVA 自 2019-02-22 起已暂停。

公司股票代码变更时会发生什么?

也许最著名的例子是 Facebook 决定 将自己更名为 Meta,并将其股票代码从 FB 更改为 META。此转变发生在 2022-06-09。

最新端点

在最新端点(最新交易、最新报价、最新 K 线 和 快照)上,数据绝不会以任何方式被操纵。这些端点始终返回当时接收到的数据(这也是 最新 K 线 上没有 adjustment 参数的原因)。因此,在这种情况下,最新 FB 交易返回公司仍叫 FB 时的最后一笔交易:

$ curl -s -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" "${APCA_API_DATA_URL}/v2/stocks/trades/latest?symbols=FB" | jq .
{
  "trades": {
    "FB": {
      "c": [
        "@",
        "T"
      ],
      "i": 31118,
      "p": 196.29,
      "s": 121,
      "t": "2022-06-08T23:59:55.103033856Z",
      "x": "P",
      "z": "C"
    }
  }
}

请注意,响应中的时间戳是 2022-06-08,即名称变更的前一晚。

流端点

股票代码始终反映公司在 流端点 传输时使用的代码。在实践中,这意味着流客户端必须在名称变更后重新订阅新股票代码以继续接收数据。重新订阅无需重新连接,在 Facebook 示例中,你只需向 META 发送 订阅消息。

历史端点

在历史端点上,我们引入了 asof 参数,以将更名前后的数据链接在一起。默认情况下,此参数是“启用”的,因此即使你不指定它,在更名后查询新股票代码时,你也会获得新旧股票代码的数据。

对于 FB - META 更名的例子,我们可以简单地查询 META 整周的日 K 线(更名发生在周四),然而我们也会看到周一、周二和周三的 K 线,即使在那几天公司仍叫 FB。

$ curl -s -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" \
  "${APCA_API_DATA_URL}/v2/stocks/bars?timeframe=1Day&symbols=META&start=2022-06-06&end=2022-06-11" | \
  jq -r '.bars.META[] | [.t, .o, .h, .l, .c] | @tsv'
2022-06-06T04:00:00Z    193.99  196.92  188.4   194.25
2022-06-07T04:00:00Z    191.93  196.53  191.49  195.65
2022-06-08T04:00:00Z    194.67  202.03  194.41  196.64
2022-06-09T04:00:00Z    194.28  199.45  183.68  184
2022-06-10T04:00:00Z    183.04  183.1   175.02  175.57

如果你禁用 asof 参数,你将不会获得 FB K 线:

$ curl -s -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" \
  "${APCA_API_DATA_URL}/v2/stocks/bars?timeframe=1Day&symbols=META&start=2022-06-06&end=2022-06-11&asof=-" | \
  jq -r '.bars.META[] | [.t, .o, .h, .l, .c] | @tsv'
2022-06-09T04:00:00Z    194.28  199.45  183.68  184
2022-06-10T04:00:00Z    183.04  183.1   175.02  175.57

如果将 asof 设置为更名前的日期,则可以使用旧股票代码进行查询:

$ curl -s -H "APCA-API-KEY-ID: ${APCA_API_KEY_ID}" -H "APCA-API-SECRET-KEY: ${APCA_API_SECRET_KEY}" \
  "${APCA_API_DATA_URL}/v2/stocks/bars?timeframe=1Day&symbols=FB&start=2022-06-06&end=2022-06-11&asof=2022-06-06" | \
  jq -r '.bars.FB[] | [.t, .o, .h, .l, .c] | @tsv'
2022-06-06T04:00:00Z    193.99  196.92  188.4   194.25
2022-06-07T04:00:00Z    191.93  196.53  191.49  195.65
2022-06-08T04:00:00Z    194.67  202.03  194.41  196.64
2022-06-09T04:00:00Z    194.28  199.45  183.68  184
2022-06-10T04:00:00Z    183.04  183.1   175.02  175.57

不幸的是,asof 映射仅在更名后的第二天在我们的历史端点上可用。在 FB-META 示例中,它自 2022-06-10 起可用,因此在更名当天(2022-06-09)运行相同的查询不会返回 FB K 线。这是由于我们的一个数据源的限制。我们正在积极改进这一点,并在市场开盘前使用新股票代码进行映射。

K 线如何聚合?

分钟和日 K 线由交易聚合而成。交易的 (SIP) 时间戳对于分钟 K 线截断到分钟,对于日 K 线截断到天(纽约时间)。例如,14:52:28 的交易属于 14:52:00 分钟 K 线,该 K 线包含 14:52:00(含)至 14:53:00(不含)之间的所有交易。K 线的时间戳是区间的左侧(本例中为 14:52:00)。

K 线有三个部分可能被交易更新:

  • 开盘价 / 收盘价
  • 最高价 / 最低价
  • 成交量

这些更新的规则取决于

  • 交易的磁带(A、B:NYSE,C:Nasdaq,O:OTC)
  • 交易的条件
  • K 线的类型(M:分钟,D:日)
    • 某些规则对于分钟和日 K 线不同。例如 P(先前参考价格)与在交易日的较早时间点进行交易的义务有关。这将更新日 K 线的最高/最低价格,但不会更新分钟 K 线的最高/最低价格,因为该价格可能发生在另一分钟。

规则基于 SIP 的指南:

下表包含所有更新规则:

条件
代码
条件描述磁带K 线
类型
更新
开盘 /
收盘
更新
最高 /
最低
更新
成交量
常规销售ABMD:green_circle::green_circle::green_circle:
@常规销售COMD:green_circle::green_circle::green_circle:
A收购CMD🟢🟢🟢
B平均价格交易ABMD:red_circle::red_circle::green_circle:
B捆绑交易CMD:green_circle::green_circle::green_circle:
C现金销售ABCOMD:red_circle::red_circle::green_circle:
D分配CMD🟢🟢🟢
E自动执行ABMD:green_circle::green_circle::green_circle:
F跨市场扫单ABCMD:green_circle::green_circle::green_circle:
G捆绑卖出交易CM:red_circle:🔴:green_circle:
G捆绑卖出交易CD:yellow_circle:🟢🟢
H价格变动交易ABCMD:red_circle::red_circle::green_circle:
I零股交易ABCOMD:red_circle::red_circle::green_circle:
K规则 127 或规则 155ABCMD:green_circle::green_circle::green_circle:
L最后卖出ABCMD:green_circle::green_circle::green_circle:
M市场中心官方收盘价ABCMD:red_circle::red_circle::red_circle:
N次日ABCOMD:red_circle::red_circle::green_circle:
O市场中心开盘交易ABCMD:green_circle::green_circle::green_circle:
P先前参考价格ABCOM:red_circle::red_circle::green_circle:
P先前参考价格ABCOD:yellow_circle::green_circle::green_circle:
Q市场中心官方开盘价ABCMD:red_circle::red_circle::red_circle:
R卖方ABCOMD:red_circle::red_circle::green_circle:
T盘前盘后交易ABCOM🟢🟢:green_circle:
T盘前盘后交易ABCOD:red_circle::red_circle:🟢
U延长交易时段ABCOMD:red_circle::red_circle::green_circle:
V或有交易ABCMD:red_circle::red_circle::green_circle:
W平均价格交易COMD🔴🔴🟢
X交叉交易ABCMD:green_circle::green_circle::green_circle:
Y黄旗常规交易CMD🟢🟢🟢
Z乱序卖出ABCM🔴🔴:green_circle:
Z乱序卖出ABCD:yellow_circle::green_circle::green_circle:
4衍生定价ABCM:red_circle::red_circle::green_circle:
4衍生定价ABCD:yellow_circle:🟢🟢
5市场中心重新开盘交易ABCMD:green_circle::green_circle::green_circle:
6市场中心收盘交易ABCMD:green_circle::green_circle::green_circle:
7合格或有交易ABCMD:red_circle::red_circle::green_circle:
9修正的合并收盘价ABCM:red_circle::red_circle::red_circle:
9修正的合并收盘价ABCD:green_circle::green_circle::red_circle:
  • :green_circle: 表示给定条件更新该值
  • :yellow_circle: 表示给定条件仅当交易是 K 线的第一笔交易时才更新开盘/收盘价格
  • :red_circle: 表示给定条件不更新该值

在原始的 CTS / UTP 规范中,有一些更复杂的更新规则(请参阅链接规范中的脚注),但我们不使用这些规则。在大多数情况下,我们简单地使用 :yellow_circle:(或 :green_circle:)代替。

一笔交易可以有多个条件。在这种情况下,应用最严格的规则。例如,如果 Nasdaq 交易具有以下条件:@、4、I,并且正在生成日 K 线,则 K 线的任何价格都不会被更新(开盘/收盘和最高/最低都是 :red_circle:,因为这是零股交易),只有成交量 :green_circle: 会被更新。如果该交易没有 I 条件(仅 @ 和 4),则开盘/收盘价格仅当这是 K 线的第一笔交易时才会更新 :yellow_circle:,并且最高/最低价格 :green_circle: 和成交量 :green_circle: 都会被更新。如果是常规交易(@),则其所有值都会被更新。

一旦计算出交易的组合更新规则,K 线的字段就会更新:

  • 如果开盘价尚未设置且更新开盘/收盘规则为 :green_circle: 或 :yellow_circle:,则设置开盘价
  • 如果最高价尚未设置,或者交易价格高于之前的最高价且更新最高/最低规则为 :green_circle:,则设置最高价
  • 如果最低价尚未设置,或者交易价格低于之前的最低价且更新最高/最低规则为 :green_circle:,则设置最低价
  • 如果更新开盘/收盘规则为 :green_circle:,或者为 :yellow_circle: 且收盘价尚未设置,则设置收盘价
  • 如果更新成交量规则为 :green_circle:,则成交量增加交易规模
  • 如果更新成交量规则为 :green_circle:,则交易笔数增加一
  • VWAP 是这两个内部变量的比率:
    • 如果更新最高/最低规则和更新成交量规则均为 :green_circle:,则成交量加权总价增加交易价格和成交量的乘积
    • 如果更新最高/最低规则和更新成交量规则均为 :green_circle:,则总成交量增加交易规模。这意味着如果 K 线中有更新成交量但不更新最高/最低价格的交易(例如条件 R),则该成交量可能不同于 K 线的“正常”成交量字段

最后,仅当 K 线的任何字段(开盘价、最高价、最低价、收盘价、成交量)都不为 0 时,才会发出 K 线。因此,如果 K 线区间内没有交易,或者只有一笔 I 交易(仅更新成交量,但不更新任何价格),则不会生成 K 线。

所有其他非分钟和非日 K 线由分钟和日 K 线聚合而成。例如,小时(1Hour)K 线由给定小时内的所有分钟 K 线聚合而成,周 K 线(1Week)由给定周内的所有日 K 线聚合而成。此聚合不再考虑给定区间内实际发生的交易,而是使用以下规则聚合 K 线:

  • 开盘价是第一根 K 线的开盘价
  • 最高价是所有 K 线最高价中的最大值
  • 最低价是所有 K 线最低价中的最小值
  • 收盘价是最后一根 K 线的收盘价
  • 成交量是所有 K 线成交量的总和
  • 交易笔数是所有 K 线交易笔数的总和
  • VWAP 是所有 K 线 VWAP 的成交量加权平均值

期权

为什么某些合约代码缺少 Greeks 和隐含波动率?

Greeks 和隐含波动率并非始终适用于所有合约。问题不在于数据计划,而在于 Alpaca 如何计算这些值。Alpaca 使用 Black-Scholes 模型来计算 Greeks,更具体地说,使用 gopriceoptions 包。为了使计算有结果,需要以下数据:

  • 合约代码最新报价的买入价和卖出价非零
  • 标的代码的最新 (SIP) 交易
  • 合约到期日在今天之后
  • 计算的隐含波动率有效

如果这些条件中的任何一个不满足,则无法计算 Greeks,因此无法呈现。特别需要注意的一点是,0DTE(即当天到期)的合约不会有 Greeks。为什么?Black-Scholes 模型包含一个因子,其分母中有“到期天数”。如果该值为 0,则结果为除以 0,是未定义的,因此无法计算 Greeks。请参阅下面计算的一部分。

没有 Greeks 的另一个主要原因是无法计算隐含波动率。计算使用期权价格对波动率的导数,称为期权的 Vega (ν),来迭代猜测将计算当前期权价格的波动率。

  • 对波动率进行初始猜测(σ₀,例如 20%)。
  • 在该猜测下计算理论价格和期权的 Vega。
  • 更新猜测值。
  • 重复该过程,直到猜测值之间的差异接近零。

Alpaca 计算最多迭代 100 次。如果计算出的价格在此时间内未与实际期权价格收敛,则不计算隐含波动率。

深度价外(OTM)期权对价格的微小变化高度敏感,使得期权价值的计算高度不稳定。随着到期日临近或期权变得深度价外,期权对波动率的敏感性(Vega)趋近于零。这会产生数学上的除以零或平坦导数场景,导致数值求解器无法收敛到答案。

期权 K 线如何聚合?

期权 K 线聚合的逻辑与 股票 K 线 相同——请先阅读该问题。唯一的区别是期权交易与股票交易具有不同的条件。

下表包含期权交易条件的更新规则,使用相同的颜色代码:

条件
代码
条件描述K 线
类型
更新
开盘 /
收盘
更新
最高 /
最低
更新成交量
A已取消MD:red_circle::red_circle::red_circle:
B延迟且乱序MD:red_circle::red_circle::red_circle:
C最后且已取消MD:red_circle::red_circle::red_circle:
D延迟MD:red_circle::red_circle::red_circle:
E开盘交易且已取消MD:red_circle::red_circle::red_circle:
F开盘交易、延迟且乱序MD:red_circle::red_circle::red_circle:
G仅交易且已取消MD:red_circle::red_circle::red_circle:
H开盘交易且延迟MD:green_circle::green_circle::green_circle:
I自动执行MD:green_circle::green_circle::green_circle:
J重新开盘交易MD:green_circle::green_circle::green_circle:
S跨市场扫单MD:green_circle::green_circle::green_circle:
a单边拍卖非 ISOMD:green_circle::green_circle::green_circle:
b单边拍卖 ISOMD:green_circle::green_circle::green_circle:
c单边交叉非 ISOMD:green_circle::green_circle::green_circle:
d单边交叉 ISOMD:green_circle::green_circle::green_circle:
e单边场内交易MD:green_circle::green_circle::green_circle:
f多边自动电子交易MD:green_circle::green_circle::green_circle:
g多边拍卖MD:green_circle::green_circle::green_circle:
h多边交叉MD:green_circle::green_circle::green_circle:
i多边场内交易MD:green_circle::green_circle::green_circle:
j多边自动电子交易对单边MD:green_circle::green_circle::green_circle:
k股票期权拍卖MD:green_circle::green_circle::green_circle:
l多边拍卖对单边MD🟢🟢:green_circle:
m多边场内交易对单边MD:green_circle::green_circle:🟢
n股票期权自动电子交易MD:green_circle::green_circle::green_circle:
o股票期权交叉MD:green_circle::green_circle::green_circle:
p股票期权场内交易MD:green_circle::green_circle:🟢
q股票期权自动电子交易对单边MD:green_circle::green_circle::green_circle:
r股票期权拍卖对单边MD🟢🟢🟢
s股票期权场内交易对单边MD:green_circle::green_circle::green_circle:
t自有产品多边场内交易MD:red_circle::red_circle::green_circle:
u自有产品多边压缩交易MD:red_circle::red_circle::green_circle:
v盘前盘后交易M:green_circle::green_circle:🟢
v盘前盘后交易D:red_circle::red_circle::green_circle:

加密货币

为什么会有成交量为 0 / 交易笔数为 0 的加密货币 K 线?

我们的加密货币市场数据反映了来自我们自己的 Alpaca 交易所的交易和报价。由于某些加密货币的波动性,包括在任何给定时间缺乏交易量,我们包含报价中间价以提供更好的数据体验。如果在 K 线内没有交易发生,成交量将为 0,但价格将由报价价格决定。