关于 trading212-api
trading212-api 是供 Agent 使用 Trading 212 API 的技能,涵盖身份验证、账户选择、环境和 API 请求。它区分 DEMO 与 LIVE 交易,说明账户及订单操作,并注明 API 仍处于测试阶段。
主要功能
- 01HTTP Basic 身份验证指引
- 02DEMO 与 LIVE 环境选择
- 03Invest 和 Stocks ISA 账户处理
- 04账户摘要与订单 API 指引
- 05代码查询与请求规范
适用场景
- 01查看 Trading 212 账户详情
- 02选择正确的账户和环境
- 03为交易操作发送 API 请求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trading212-labs/ agent-skills --skill trading212-api安装后在 Claude Code 中输入/trading212-api确认已加载。
详细介绍
Trading 212 API
注意: Trading 212 API 目前处于 Beta 阶段,仍在积极开发中。部分端点或行为可能会发生变化。
快速参考
环境
| 环境 | 基础 URL | 用途 |
|---|---|---|
| Demo | https://demo.trading212.com/api/v0 | 模拟交易——无需真实资金即可测试 |
| Live | https://live.trading212.com/api/v0 | 真实资金交易 |
订单数量约定
- 正数 = 买入(例如,
10表示买入 10 股) - 负数 = 卖出(例如,
-10表示卖出 10 股)
账户类型
仅支持 Invest 和 Stocks ISA 账户。
工具标识符
Trading 212 使用自定义代码作为工具的唯一标识符。 提交工具请求前,请务必先搜索 Trading 212 代码。
身份验证
使用 API Key(用户名)和 API Secret(密码)进行 HTTP Basic Auth 身份验证。
先检查现有配置
在引导用户设置身份验证之前,先检查凭据是否已配置:
语义规则: 至少存在 一组完整凭据 时,即视为已配置凭据:一组完整凭据是同一账户的 key + secret(例如,T212_API_KEY + T212_API_SECRET、T212_API_KEY_INVEST + T212_API_SECRET_INVEST,或 T212_API_KEY_STOCKS_ISA + T212_API_SECRET_STOCKS_ISA)。无需配置所有四个账户专属变量;仅有 Invest 配对或仅有 Stocks ISA 配对也足够。检查是否存在任何可组成至少一组可用 key + secret 配对的组合。
# Example: configured if any complete credential set exists
if [ -n "$T212_AUTH_HEADER" ] && [ -n "$T212_BASE_URL" ]; then
echo "Configured (derived vars)"
elif [ -n "$T212_API_KEY" ] && [ -n "$T212_API_SECRET" ]; then
echo "Configured (single account)"
elif [ -n "$T212_API_KEY_INVEST" ] && [ -n "$T212_API_SECRET_INVEST" ]; then
echo "Configured (Invest); Stocks ISA also if T212_API_KEY_STOCKS_ISA and T212_API_SECRET_STOCKS_ISA are set"
elif [ -n "$T212_API_KEY_STOCKS_ISA" ] && [ -n "$T212_API_SECRET_STOCKS_ISA" ]; then
echo "Configured (Stocks ISA); Invest also if T212_API_KEY_INVEST and T212_API_SECRET_INVEST are set"
else
echo "No complete credential set found"
fi
如果存在任何一组完整凭据,请跳过完整设置流程并继续进行 API 调用;发起请求时,使用下文“发起请求”中的解析顺序(存在多组凭据时,选择与用户账户上下文匹配的一组)。不要要求用户运行派生单行命令,也不要让用户将 key 合并到标头中。仅当不存在完整凭据组时,才引导用户完成下方的完整设置流程。
重要: 发起任何 API 调用前,务必先询问用户要使用哪个环境:LIVE(真实资金)还是 DEMO(模拟交易)。不要自行假定环境。
API Key 与环境绑定
API Key 与特定环境绑定,不能跨环境使用。
| 创建 API Key 的环境 | 可配合使用的环境 | 不可配合使用的环境 |
|---|---|---|
| LIVE 账户 | live.trading212.com | demo.trading212.com |
| DEMO 账户 | demo.trading212.com | live.trading212.com |
如果收到 401 错误,请确认:
- 你使用的 API Key 适用于目标环境
- API Key 是在你尝试访问的同一环境(LIVE 或 DEMO)中生成的
获取凭据
- 决定要使用哪个环境——LIVE(真实资金)或 DEMO(模拟交易)
- 打开 Trading 212 应用(移动端或网页)
- 切换到正确的账户——确保当前处于与目标环境匹配的 LIVE 或 DEMO 模式
- 前往 设置 > API
- 生成一组新的 API Key——你将获得:
- API Key(ID)(例如,
35839398ZFVKUxpHzPiVsxKdOtZdaDJSrvyPF) - API Secret(例如,
7MOzYJlVJgxoPjdZJCEH3fO9ee7A0NzLylFFD4-3tlo)
- API Key(ID)(例如,
- 如果同时使用两个环境,请为每个环境分别保存凭据
构建身份验证标头
将 API Key(ID)和 Secret 用冒号连接,进行 Base64 编码,并在前面加上 Basic ,作为 Authorization 标头。
可选: 要预先计算标头,可设置:
export T212_AUTH_HEADER="Basic $(echo -n "$T212_API_KEY:$T212_API_SECRET" | base64 -w 0)"
否则,Agent 会在发起请求时根据 T212_API_KEY 和 T212_API_SECRET 构建标头。
手动方式(占位符):
# Format: T212_AUTH_HEADER = "Basic " + base64(API_KEY_ID:API_SECRET)
export T212_AUTH_HEADER="Basic $(echo -n "<YOUR_API_KEY_ID>:<YOUR_API_SECRET>" | base64 -w 0)"
# Example with sample credentials:
export T212_AUTH_HEADER="Basic $(echo -n "35839398ZFVKUxpHzPiVsxKdOtZdaDJSrvyPF:7MOzYJlVJgxoPjdZJCEH3fO9ee7A0NzLylFFD4-3tlo" | base64 -w 0)"
发起请求
发起 API 调用时,请使用第一个适用的选项(语义上:选择与用户账户匹配的凭据组,或唯一存在的凭据组):
- 如果已设置
T212_AUTH_HEADER和T212_BASE_URL: 在请求中使用它们。 - 否则,如果已设置
T212_API_KEY和T212_API_SECRET: 使用这对凭据(单个账户)。将请求头构建为Basic $(echo -n "$T212_API_KEY:$T212_API_SECRET" | base64 -w 0),将基础 URL 构建为https://${T212_ENV:-live}.trading212.com。不要引导用户推导或合并;由你来完成。 - 否则,如果两组账户专属凭据都已设置(
T212_API_KEY_INVEST/T212_API_SECRET_INVEST和T212_API_KEY_STOCKS_ISA/T212_API_SECRET_STOCKS_ISA):用户必须明确指定要使用哪个账户(Invest 或 Stocks ISA),除非他们要求获取所有账户的信息。用户提到 Invest 时,使用 Invest 凭据;提到 ISA/Stocks ISA 时,使用 Stocks ISA 凭据。如果用户需要所有账户的信息,请针对每个账户分别发起 API 调用(Invest 和 Stocks ISA),并呈现或汇总两个账户的结果。如果根据上下文无法确定要使用哪个账户(且用户没有要求获取所有账户的信息),请在发起 API 调用前询问用户确认(例如:“我应该使用哪个账户——Invest 还是 Stocks ISA?”)。不要自行假定。使用所选密钥/密钥密文构建请求头,并将基础 URL 构建为https://${T212_ENV:-live}.trading212.com。 - 否则,如果只设置了 Invest 凭据(
T212_API_KEY_INVEST和T212_API_SECRET_INVEST):使用这对凭据发起请求;如果用户询问 Stocks ISA,则说明当前仅配置了 Invest 账户。 - 否则,如果只设置了 Stocks ISA 凭据(
T212_API_KEY_STOCKS_ISA和T212_API_SECRET_STOCKS_ISA):使用这对凭据发起请求;如果用户询问 Invest,则说明当前仅配置了 Stocks ISA 账户。
如果已设置 T212_AUTH_HEADER,请在 Authorization 请求头中使用其值:
# When T212_AUTH_HEADER and T212_BASE_URL are set:
curl -H "Authorization: $T212_AUTH_HEADER" \
"${T212_BASE_URL}/api/v0/equity/account/summary"
仅设置主要变量时,请在 curl 命令中使用内联形式:
# When only T212_API_KEY, T212_API_SECRET, T212_ENV are set:
curl -H "Authorization: Basic $(echo -n "$T212_API_KEY:$T212_API_SECRET" | base64 -w 0)" \
"https://${T212_ENV:-live}.trading212.com/api/v0/equity/account/summary"
警告:
T212_AUTH_HEADER必须是完整的请求头值,包括Basic前缀。# 错误 - 不带 "Basic " 前缀的原始 base64 curl -H "Authorization: <base64-only>" ... # 这行命令无法运行! # 正确 - 使用 T212_AUTH_HEADER(包含 "Basic <base64>") curl -H "Authorization: $T212_AUTH_HEADER" ... # 这行命令可以运行
环境变量
单个账户与所有账户: API 密钥对应单个账户。一组密钥/密钥密文(T212_API_KEY + T212_API_SECRET)= 一个账户(Invest 或 Stocks ISA)。要使用所有账户(Invest 和 Stocks ISA),用户必须设置两组密钥/密钥密文:T212_API_KEY_INVEST / T212_API_SECRET_INVEST 和 T212_API_KEY_STOCKS_ISA / T212_API_SECRET_STOCKS_ISA。设置了两组凭据后,用户必须明确指定要使用哪个账户;如果根据上下文无法确定,请在发起 API 调用前询问用户确认(Invest 还是 Stocks ISA)。
主要变量(单个账户): 设置这些变量,以便与插件 README 保持一致:
export T212_API_KEY="your-api-key" # API Key (ID) from Trading 212
export T212_API_SECRET="your-api-secret"
export T212_ENV="demo" # or "live" (defaults to "live" if unset)
账户专属变量(Invest 和/或 Stocks ISA): 仅设置要使用的凭据组。同一账户的一组完整凭据(密钥 + 密钥密文)即可。例如,仅使用 Invest:
export T212_API_KEY_INVEST="your-invest-api-key"
export T212_API_SECRET_INVEST="your-invest-api-secret"
export T212_ENV="demo" # or "live"
如需使用两个账户,请同时设置两组凭据:
export T212_API_KEY_INVEST="your-invest-api-key"
export T212_API_SECRET_INVEST="your-invest-api-secret"
export T212_API_KEY_STOCKS_ISA="your-stocks-isa-api-key"
export T212_API_SECRET_STOCKS_ISA="your-stocks-isa-api-secret"
export T212_ENV="demo" # or "live" (applies to both)
可选 – 预先计算(适用于脚本或有此偏好的用户): 用户可以根据主要变量设置身份验证请求头和基础 URL,但并非必须;发起 API 调用时,如果未设置这些值,你(Agent)必须根据主要变量构建请求头和基础 URL。
# Build auth header and base URL from T212_API_KEY, T212_API_SECRET, T212_ENV
export T212_AUTH_HEADER="Basic $(echo -n "$T212_API_KEY:$T212_API_SECRET" | base64 -w 0)"
export T212_BASE_URL="https://${T212_ENV:-live}.trading212.com"
替代方案(手动设置): 如果你不想将密钥/密钥密文存储在环境变量中,可以直接设置派生变量。请注意,API 密钥只能与对应的环境搭配使用。
# For DEMO (paper trading)
export T212_AUTH_HEADER="Basic $(echo -n "<DEMO_API_KEY_ID>:<DEMO_API_SECRET>" | base64 -w 0)"
export T212_BASE_URL="https://demo.trading212.com"
# For LIVE (real money) - generate separate credentials in LIVE account
# export T212_AUTH_HEADER="Basic $(echo -n "<LIVE_API_KEY_ID>:<LIVE_API_SECRET>" | base64 -w 0)"
# export T212_BASE_URL="https://live.trading212.com"
提示: 如果你同时使用两个环境,请使用不同的变量名:
# Demo credentials
export T212_DEMO_AUTH_HEADER="Basic $(echo -n "<DEMO_KEY_ID>:<DEMO_SECRET>" | base64 -w 0)"
# Live credentials
export T212_LIVE_AUTH_HEADER="Basic $(echo -n "<LIVE_KEY_ID>:<LIVE_SECRET>" | base64 -w 0)"
常见身份验证错误
| 代码 | 原因 | 解决方案 |
|---|---|---|
| 401 | 凭据无效 | 检查 API 密钥/密钥,确保没有多余空格 |
| 401 | 环境不匹配 | LIVE API 密钥不能用于 DEMO,反之亦然 - 确认密钥与目标环境匹配 |
| 403 | 缺少权限 | 在 Trading 212 设置中检查 API 权限 |
| 408 | 请求超时 | 重试请求 |
| 429 | 超出速率限制 | 等待 x-ratelimit-reset 时间戳 |
账户
获取账户摘要
GET /api/v0/equity/account/summary (1 req/5s)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/account/summary"
响应结构:
{
"id": 12345678,
"currency": "GBP",
"totalValue": 15250.75,
"cash": {
"availableToTrade": 2500.5,
"reservedForOrders": 150.0,
"inPies": 500.0
},
"investments": {
"currentValue": 12100.25,
"totalCost": 10500.0,
"realizedProfitLoss": 850.5,
"unrealizedProfitLoss": 1600.25
}
}
账户字段
| 字段 | 类型 | 描述 |
|---|---|---|
id | integer | 主交易账户编号 |
currency | string | 主账户货币(ISO 4217) |
totalValue | number | 以主货币计价的账户总价值 |
cash.availableToTrade | number | 可用于投资的资金 |
cash.reservedForOrders | number | 为待处理订单预留的现金 |
cash.inPies | number | Pie 中未投资的现金 |
investments.currentValue | number | 所有投资的当前价值 |
investments.totalCost | number | 当前投资的成本基础 |
investments.realizedProfitLoss | number | 累计已实现盈亏 |
investments.unrealizedProfitLoss | number | 如果现在卖出,可能产生的盈亏 |
订单
订单类型
| 类型 | 端点 | 可用性 | 描述 |
|---|---|---|---|
| 市价单 | /api/v0/equity/orders/market | Demo + Live | 以最优价格立即执行 |
| 限价单 | /api/v0/equity/orders/limit | Demo + Live | 以限价或更优价格执行 |
| 止损单 | /api/v0/equity/orders/stop | Demo + Live | 达到止损价时执行市价单 |
| 止损限价单 | /api/v0/equity/orders/stop_limit | Demo + Live | 达到止损价时执行限价单 |
订单状态
| 状态 | 描述 |
|---|---|
LOCAL | 订单已在本地创建,尚未发送 |
UNCONFIRMED | 已发送至交易所,等待确认 |
CONFIRMED | 已获交易所确认 |
NEW | 已激活,等待执行 |
CANCELLING | 正在处理取消请求 |
CANCELLED | 已成功取消 |
PARTIALLY_FILLED | 部分股份已成交 |
FILLED | 已全部成交 |
REJECTED | 已被交易所拒绝 |
REPLACING | 正在处理修改请求 |
REPLACED | 已成功修改 |
有效时间
| 值 | 描述 |
|---|---|
DAY | 在交易所时区的午夜到期 |
GOOD_TILL_CANCEL | 持续有效,直到成交或取消(默认) |
订单策略
| Value | Description |
|---|---|
QUANTITY | 按股票数量下单(API 支持) |
VALUE | 按货币金额下单(API 不支持) |
发起来源
| Value | Description |
|---|---|
API | 通过此 API 下单 |
IOS | iOS 应用 |
ANDROID | Android 应用 |
WEB | Web 平台 |
SYSTEM | 系统生成 |
AUTOINVEST | 自动投资功能 |
下达市价单
POST /api/v0/equity/orders/market (50 req/min)
# Buy 5 shares
curl -X POST -H "Authorization: $T212_AUTH_HEADER" \
-H "Content-Type: application/json" \
"$T212_BASE_URL/api/v0/equity/orders/market" \
-d '{"ticker": "AAPL_US_EQ", "quantity": 5}'
# Sell 3 shares (negative quantity)
curl -X POST -H "Authorization: $T212_AUTH_HEADER" \
-H "Content-Type: application/json" \
"$T212_BASE_URL/api/v0/equity/orders/market" \
-d '{"ticker": "AAPL_US_EQ", "quantity": -3}'
# Buy with extended hours enabled
curl -X POST -H "Authorization: $T212_AUTH_HEADER" \
-H "Content-Type: application/json" \
"$T212_BASE_URL/api/v0/equity/orders/market" \
-d '{"ticker": "AAPL_US_EQ", "quantity": 5, "extendedHours": true}'
请求字段:
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | 是 | 证券代码(例如,AAPL_US_EQ) |
quantity | number | 是 | 正数表示买入,负数表示卖出 |
extendedHours | boolean | 否 | 设置为 true,允许在盘前(4:00-9:30 ET)和盘后(16:00-20:00 ET)时段执行。默认值:false |
响应:
{
"id": 123456789,
"type": "MARKET",
"ticker": "AAPL_US_EQ",
"instrument": {
"ticker": "AAPL_US_EQ",
"name": "Apple Inc",
"isin": "US0378331005",
"currency": "USD"
},
"quantity": 5,
"filledQuantity": 0,
"status": "NEW",
"side": "BUY",
"strategy": "QUANTITY",
"initiatedFrom": "API",
"extendedHours": false,
"createdAt": "2024-01-15T10:30:00Z"
}
下达限价单
POST /api/v0/equity/orders/limit (1 req/2s)
curl -X POST -H "Authorization: $T212_AUTH_HEADER" \
-H "Content-Type: application/json" \
"$T212_BASE_URL/api/v0/equity/orders/limit" \
-d '{"ticker": "AAPL_US_EQ", "quantity": 5, "limitPrice": 150.00, "timeValidity": "DAY"}'
请求字段:
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | 是 | 证券代码 |
quantity | number | 是 | 正数表示买入,负数表示卖出 |
limitPrice | number | 是 | 买入的最高价格,卖出的最低价格 |
timeValidity | string | 否 | DAY(默认值)或 GOOD_TILL_CANCEL |
下达止损单
POST /api/v0/equity/orders/stop (1 req/2s)
curl -X POST -H "Authorization: $T212_AUTH_HEADER" \
-H "Content-Type: application/json" \
"$T212_BASE_URL/api/v0/equity/orders/stop" \
-d '{"ticker": "AAPL_US_EQ", "quantity": -5, "stopPrice": 140.00, "timeValidity": "GOOD_TILL_CANCEL"}'
请求字段:
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | 是 | 证券代码 |
quantity | number | 是 | 正数表示买入,负数表示卖出 |
stopPrice | number | 是 | 触发价格(基于最新成交价) |
timeValidity | string | 否 | DAY(默认值)或 GOOD_TILL_CANCEL |
下达止损限价单
POST /api/v0/equity/orders/stop_limit (1 req/2s)
curl -X POST -H "Authorization: $T212_AUTH_HEADER" \
-H "Content-Type: application/json" \
"$T212_BASE_URL/api/v0/equity/orders/stop_limit" \
-d '{"ticker": "AAPL_US_EQ", "quantity": -5, "stopPrice": 145.00, "limitPrice": 140.00, "timeValidity": "DAY"}'
请求字段:
| Field | Type | Required | Description |
|---|---|---|---|
ticker | string | 是 | 证券代码 |
quantity | number | 是 | 正数表示买入,负数表示卖出 |
stopPrice | number | 是 | 激活限价单的触发价格 |
limitPrice | number | 是 | 后续订单的限价 |
timeValidity | string | 否 | DAY(默认值)或 GOOD_TILL_CANCEL |
获取待处理订单
GET /api/v0/equity/orders (1 req/5s)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/orders"
返回状态为 NEW、PARTIALLY_FILLED 等的订单对象数组。
按 ID 获取订单
GET /api/v0/equity/orders/{id} (1 req/1s)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/orders/123456789"
取消订单
DELETE /api/v0/equity/orders/{id} (50 req/min)
curl -X DELETE -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/orders/123456789"
如果取消请求已受理,则返回 200 OK。订单可能已经成交。
常见订单错误
| 错误 | 原因 | 解决方案 |
|---|---|---|
InsufficientFreeForStocksBuy | 现金不足 | 检查 cash.availableToTrade |
SellingEquityNotOwned | 卖出的数量超过持有数量 | 检查 quantityAvailableForTrading |
MarketClosed | 不在交易时段内 | 查看交易所时间表 |
持仓
获取所有持仓
GET /api/v0/equity/positions (1 req/1s)
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ticker | string | 否 | 按特定代码筛选(例如,AAPL_US_EQ) |
# All positions
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/positions"
# Filter by ticker
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/positions?ticker=AAPL_US_EQ"
响应架构:
[
{
"instrument": {
"ticker": "AAPL_US_EQ",
"name": "Apple Inc",
"isin": "US0378331005",
"currency": "USD"
},
"quantity": 15.5,
"quantityAvailableForTrading": 12.5,
"quantityInPies": 3,
"currentPrice": 185.5,
"averagePricePaid": 170.25,
"createdAt": "2024-01-10T09:15:00Z",
"walletImpact": {
"currency": "GBP",
"totalCost": 2089.45,
"currentValue": 2275.1,
"unrealizedProfitLoss": 185.65,
"fxImpact": 12.3
}
}
]
持仓字段
| 字段 | 类型 | 说明 |
|---|---|---|
quantity | number | 持有的总股数 |
quantityAvailableForTrading | number | 可卖出的股数 |
quantityInPies | number | 分配到组合中的股数 |
currentPrice | number | 当前价格(工具币种) |
averagePricePaid | number | 每股平均成本 |
createdAt | datetime | 持仓开仓日期 |
walletImpact.currency | string | 账户币种 |
walletImpact.totalCost | number | 账户币种的总成本 |
walletImpact.currentValue | number | 账户币种的当前价值 |
walletImpact.unrealizedProfitLoss | number | 账户币种的盈亏 |
walletImpact.fxImpact | number | 汇率对价值的影响 |
持仓数量情形
| 情形 | quantity | quantityAvailableForTrading | quantityInPies |
|---|---|---|---|
| 全部为直接持仓 | 10 | 10 | 0 |
| 部分在组合中 | 10 | 7 | 3 |
| 全部在组合中 | 10 | 0 | 10 |
重要: 下达卖单前,务必检查 quantityAvailableForTrading。
工具
代码查询工作流
当用户使用常见名称提及工具(例如,“SAP”“Apple”“AAPL”)时,必须先查找准确的 Trading 212 代码,再查询任何订单、持仓或历史数据。切勿手动构造代码格式。
优先使用缓存: 调用 API 前,务必检查
/tmp/t212_instruments.json。工具端点的速率限制为 50 秒,返回内容约为 5MB。仅当缓存不存在或已超过 1 小时时才调用 API。
通用搜索: 在三个有意义的字段中匹配用户的搜索词:代码、名称或简称。使用一个变量(例如 SEARCH_TERM),并在每个字段上使用 test($q; "i"),以便高效匹配“TSLA”“Tesla”“TL0”等内容。按地区筛选(例如“美国股票”“欧洲 SAP”)时,使用 ISIN 前缀(前 2 个字符)作为国家代码,或在 grep 后使用 currencyCode。
重要: 切勿自动选择工具。如果存在多个选项,必须询问用户的偏好。
# SEARCH_TERM = user query (e.g. TSLA, Tesla, AAPL, SAP)
SEARCH_TERM="TSLA"
CACHE_FILE="/tmp/t212_instruments.json"
if [ -f "$CACHE_FILE" ] && [ $(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || stat -c %Y "$CACHE_FILE"))) -lt 3600 ]; then
# Search ticker, name, or shortName fields
jq --arg q "$SEARCH_TERM" '[.[] | select((.ticker // "" | test($q; "i")) or (.name // "" | test($q; "i")) or (.shortName // "" | test($q; "i")))]' "$CACHE_FILE"
else
curl -s -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/metadata/instruments" > "$CACHE_FILE"
fi
获取所有工具
GET /api/v0/equity/metadata/instruments (1 req/50s)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/metadata/instruments"
响应架构:
[
{
"ticker": "AAPL_US_EQ",
"name": "Apple Inc",
"shortName": "AAPL",
"isin": "US0378331005",
"currencyCode": "USD",
"type": "STOCK",
"maxOpenQuantity": 10000,
"extendedHours": true,
"workingScheduleId": 123,
"addedOn": "2020-01-15T00:00:00Z"
}
]
工具字段
| 字段 | 类型 | 描述 |
|---|---|---|
ticker | string | 唯一的工具标识符 |
name | string | 工具全名 |
shortName | string | 简短代码(例如,AAPL) |
isin | string | 国际证券识别码 |
currencyCode | string | 交易货币(ISO 4217) |
type | string | 工具类型(见下文) |
maxOpenQuantity | number | 允许的最大持仓规模 |
extendedHours | boolean | 是否支持延长时段交易 |
workingScheduleId | integer | 交易所日程的引用 |
addedOn | datetime | 添加到平台的时间 |
工具类型
| 类型 | 描述 |
|---|---|
STOCK | 普通股 |
ETF | 交易所交易基金 |
CRYPTOCURRENCY | 加密货币 |
CRYPTO | 加密资产 |
FOREX | 外汇 |
FUTURES | 期货合约 |
INDEX | 指数 |
WARRANT | 认股权证 |
CVR | 或有价值权 |
CORPACT | 公司行动 |
Ticker 格式
{SYMBOL}_{EXCHANGE}_{TYPE} - 示例:
AAPL_US_EQ- 在美国交易所交易的 AppleVUSA_LSE_EQ- 在伦敦交易的 Vanguard S&P 500BTC_CRYPTO- Bitcoin
获取交易所元数据
GET /api/v0/equity/metadata/exchanges(1 req/30s)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/metadata/exchanges"
响应架构:
[
{
"id": 123,
"name": "NASDAQ",
"workingSchedules": [
{
"id": 456,
"timeEvents": [
{ "type": "PRE_MARKET_OPEN", "date": "2024-01-15T09:00:00Z" },
{ "type": "OPEN", "date": "2024-01-15T14:30:00Z" },
{ "type": "CLOSE", "date": "2024-01-15T21:00:00Z" },
{ "type": "AFTER_HOURS_CLOSE", "date": "2024-01-15T01:00:00Z" }
]
}
]
}
]
时间事件类型
| 类型 | 描述 |
|---|---|
PRE_MARKET_OPEN | 盘前时段开始 |
OPEN | 常规交易开始 |
BREAK_START | 交易休市开始 |
BREAK_END | 交易休市结束 |
CLOSE | 常规交易结束 |
AFTER_HOURS_OPEN | 盘后时段开始 |
AFTER_HOURS_CLOSE | 盘后时段结束 |
OVERNIGHT_OPEN | 夜间时段开始 |
历史数据
所有历史接口点都使用基于游标的分页,并提供 nextPagePath。
分页参数
| 参数 | 类型 | 默认值 | 最大值 | 描述 |
|---|---|---|---|---|
limit | integer | 20 | 50 | 每页项目数 |
cursor | string/number | - | - | 分页游标(在 nextPagePath 中使用) |
ticker | string | - | - | 按 ticker 筛选(订单、股息) |
time | datetime | - | - | 分页时间(用于交易记录的 nextPagePath) |
分页示例
#!/bin/bash
# Fetch all historical orders with pagination
NEXT_PATH="/api/v0/equity/history/orders?limit=50"
while [ -n "$NEXT_PATH" ]; do
echo "Fetching: $NEXT_PATH"
RESPONSE=$(curl -s -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL$NEXT_PATH")
# Process items (e.g., save to file)
echo "$RESPONSE" | jq '.items[]' >> orders.json
# Get next page path (null if no more pages)
NEXT_PATH=$(echo "$RESPONSE" | jq -r '.nextPagePath // empty')
# Wait 1 second between requests (50 req/min limit)
if [ -n "$NEXT_PATH" ]; then
sleep 1
fi
done
echo "Done fetching all orders"
历史订单
GET /api/v0/equity/history/orders(50 req/min)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/history/orders?limit=50"
# Filter by ticker
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/history/orders?ticker=AAPL_US_EQ&limit=50"
响应架构:
{
"items": [
{
"order": {
"id": 123456789,
"type": "MARKET",
"ticker": "AAPL_US_EQ",
"instrument": {
"ticker": "AAPL_US_EQ",
"name": "Apple Inc",
"isin": "US0378331005",
"currency": "USD"
},
"quantity": 5,
"filledQuantity": 5,
"status": "FILLED",
"side": "BUY",
"createdAt": "2024-01-15T10:30:00Z"
},
"fill": {
"id": 987654321,
"type": "TRADE",
"quantity": 5,
"price": 185.5,
"filledAt": "2024-01-15T10:30:05Z",
"tradingMethod": "TOTV",
"walletImpact": {
"currency": "GBP",
"fxRate": 0.79,
"netValue": 732.72,
"realisedProfitLoss": 0,
"taxes": [
{ "name": "STAMP_DUTY", "quantity": 3.66, "currency": "GBP" }
]
}
}
}
],
"nextPagePath": "/api/v0/equity/history/orders?limit=50&cursor=1705326600000"
}
成交类型
| 类型 | 描述 |
|---|---|
TRADE | 常规交易执行 |
STOCK_SPLIT | 拆股调整 |
STOCK_DISTRIBUTION | 股票分配 |
FOP | 无款交割转移 |
FOP_CORRECTION | FOP 更正 |
CUSTOM_STOCK_DISTRIBUTION | 自定义股票分配 |
EQUITY_RIGHTS | 配股 |
交易方式
| 方式 | 描述 |
|---|---|
TOTV | 在交易场所交易 |
OTC | 场外交易 |
税费类型(walletImpact.taxes)
| 类型 | 描述 |
|---|---|
COMMISSION_TURNOVER | 交易额佣金 |
CURRENCY_CONVERSION_FEE | 外汇兑换费 |
FINRA_FEE | FINRA 交易活动费 |
FRENCH_TRANSACTION_TAX | 法国金融交易税 |
PTM_LEVY | 收购与合并小组征费 |
STAMP_DUTY | 英国印花税 |
STAMP_DUTY_RESERVE_TAX | 英国印花税储备税 |
TRANSACTION_FEE | 一般交易费 |
历史股息
GET /api/v0/equity/history/dividends (50 req/min)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/history/dividends?limit=50"
# Filter by ticker
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/history/dividends?ticker=AAPL_US_EQ&limit=50"
响应架构:
{
"items": [
{
"ticker": "AAPL_US_EQ",
"instrument": {
"ticker": "AAPL_US_EQ",
"name": "Apple Inc",
"isin": "US0378331005",
"currency": "USD"
},
"type": "ORDINARY",
"amount": 12.5,
"amountInEuro": 14.7,
"currency": "GBP",
"tickerCurrency": "USD",
"grossAmountPerShare": 0.24,
"quantity": 65.5,
"paidOn": "2024-02-15T00:00:00Z",
"reference": "DIV-123456"
}
],
"nextPagePath": null
}
股息类型(常见)
| 类型 | 描述 |
|---|---|
ORDINARY | 普通股息 |
BONUS | 红利股息 |
INTEREST | 利息支付 |
DIVIDEND | 通用股息 |
CAPITAL_GAINS | 资本利得分配 |
RETURN_OF_CAPITAL | 资本返还 |
PROPERTY_INCOME | 房地产收入(REIT) |
DEMERGER | 分拆分配 |
QUALIFIED_INVESTMENT_ENTITY | QIE 分配 |
TRUST_DISTRIBUTION | 信托分配 |
注意:还有许多其他美国税务专用类型,用于 1042-S 报告。
账户交易
GET /api/v0/equity/history/transactions (50 req/min)
分页:
- 首次请求: 只能使用
limit参数(不能使用游标或时间戳) - 后续请求: 使用上一个响应中的
nextPagePath,其中会自动包含游标和时间戳 - 时间筛选: 交易无法按时间筛选;只能通过分页浏览历史数据
# First request - use only limit
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/history/transactions?limit=50"
响应架构:
{
"items": [
{
"type": "DEPOSIT",
"amount": 1000.0,
"currency": "GBP",
"dateTime": "2024-01-10T14:30:00Z",
"reference": "TXN-123456"
}
],
"nextPagePath": null
}
交易类型
| 类型 | 描述 |
|---|---|
DEPOSIT | 存入账户的资金 |
WITHDRAW | 从账户提取的资金 |
FEE | 收取的费用 |
TRANSFER | 内部转账 |
CSV 报告
请求报告: POST /api/v0/equity/history/exports (1 req/30s)
curl -X POST -H "Authorization: $T212_AUTH_HEADER" \
-H "Content-Type: application/json" \
"$T212_BASE_URL/api/v0/equity/history/exports" \
-d '{
"dataIncluded": {
"includeDividends": true,
"includeInterest": true,
"includeOrders": true,
"includeTransactions": true
},
"timeFrom": "2024-01-01T00:00:00Z",
"timeTo": "2024-12-31T23:59:59Z"
}'
响应:
{
"reportId": 12345
}
轮询完成状态: GET /api/v0/equity/history/exports (1 req/min)
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/history/exports"
响应:
[
{
"reportId": 12345,
"status": "Finished",
"dataIncluded": {
"includeDividends": true,
"includeInterest": true,
"includeOrders": true,
"includeTransactions": true
},
"timeFrom": "2024-01-01T00:00:00Z",
"timeTo": "2024-12-31T23:59:59Z",
"downloadLink": "https://trading212-reports.s3.amazonaws.com/..."
}
]
下载报告:
# Get the download link from the response
DOWNLOAD_URL=$(curl -s -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/history/exports" | jq -r '.[0].downloadLink')
# Download the CSV file
curl -o trading212_report.csv "$DOWNLOAD_URL"
报告状态值
| 状态 | 描述 |
|---|---|
Queued | 已收到报告请求 |
Processing | 已开始生成报告 |
Running | 正在生成报告 |
Finished | 已完成——downloadLink 可用 |
Canceled | 报告已取消 |
Failed | 生成失败 |
下单前验证
买入前——检查可用资金
#!/bin/bash
# Validate funds before placing a buy order
TICKER="AAPL_US_EQ"
QUANTITY=10
ESTIMATED_PRICE=185.00
ESTIMATED_COST=$(echo "$QUANTITY * $ESTIMATED_PRICE" | bc)
# Get available funds
AVAILABLE=$(curl -s -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/account/summary" | jq '.cash.availableToTrade')
echo "Estimated cost: $ESTIMATED_COST"
echo "Available funds: $AVAILABLE"
if (( $(echo "$ESTIMATED_COST > $AVAILABLE" | bc -l) )); then
echo "ERROR: Insufficient funds"
exit 1
fi
echo "OK: Funds available, proceeding with order"
卖出前——检查可用股份
#!/bin/bash
# Validate position before placing a sell order
TICKER="AAPL_US_EQ"
SELL_QUANTITY=5
# Get position for the ticker
POSITION=$(curl -s -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/positions?ticker=$TICKER")
AVAILABLE_QTY=$(echo "$POSITION" | jq '.[0].quantityAvailableForTrading // 0')
echo "Sell quantity: $SELL_QUANTITY"
echo "Available to sell: $AVAILABLE_QTY"
if (( $(echo "$SELL_QUANTITY > $AVAILABLE_QTY" | bc -l) )); then
echo "ERROR: Insufficient shares (some may be in pies)"
exit 1
fi
echo "OK: Shares available, proceeding with order"
速率限制处理
了解速率限制
速率限制按账户计算,而不是按 API 密钥或 IP 地址计算。如果多个应用使用同一个 Trading 212 账户,它们会共享同一速率限制池。
响应标头
每个 API 响应都包含速率限制标头:
| 标头 | 描述 |
|---|---|
x-ratelimit-limit | 周期内允许的请求总数 |
x-ratelimit-period | 周期时长,以秒为单位 |
x-ratelimit-remaining | 剩余请求数 |
x-ratelimit-reset | 限制重置时的 Unix 时间戳 |
x-ratelimit-used | 已发出的请求数 |
避免突发请求,以免触发速率限制
不要突发发送请求。 即使某个端点每分钟允许 50 个请求,一次性全部发送也可能触发速率限制并降低性能。 应均匀安排请求,例如每 1.2 秒调用一次,确保始终不超过限制。
错误做法(突发发送):
# DON'T DO THIS - sends all requests at once
for ticker in AAPL_US_EQ MSFT_US_EQ GOOGL_US_EQ; do
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/positions?ticker=$ticker" &
done
wait
正确做法(均匀发送):
# DO THIS - space requests evenly
for ticker in AAPL_US_EQ MSFT_US_EQ GOOGL_US_EQ; do
curl -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/positions?ticker=$ticker"
sleep 1.2 # 1.2 second between requests for 50 req/m limit
done
缓存策略
对于不常变化的数据,应在本地缓存以减少 API 调用:
#!/bin/bash
# Cache instruments list (changes rarely)
CACHE_FILE="/tmp/t212_instruments.json"
CACHE_MAX_AGE=3600 # 1 hour
if [ -f "$CACHE_FILE" ]; then
CACHE_AGE=$(($(date +%s) - $(stat -f %m "$CACHE_FILE")))
if [ "$CACHE_AGE" -lt "$CACHE_MAX_AGE" ]; then
cat "$CACHE_FILE"
exit 0
fi
fi
# Cache expired or doesn't exist - fetch fresh data
curl -s -H "Authorization: $T212_AUTH_HEADER" \
"$T212_BASE_URL/api/v0/equity/metadata/instruments" > "$CACHE_FILE"
cat "$CACHE_FILE"
安全指南
- 先在演示环境中测试 - 实盘交易前务必验证工作流
- 下单前先验证 - 买入前检查资金(
cash.availableToTrade),卖出前检查持仓(quantityAvailableForTrading) - 确认破坏性操作 - 下单和取消订单均不可撤销
- API 不具备幂等性 - 重复请求可能创建重复订单
- 切勿记录凭据 - 使用环境变量
- 遵守速率限制 - 均匀间隔发送请求,切勿突发发送
- 最多 50 个待处理订单 - 每个代码、每个账户
- 缓存元数据 - 证券和交易所很少变化