外汇数据查询:返回字段与数据结构全解(forexList / 日K / 分钟K / 海外列表)
约 9 分钟 入门外汇数据查询返回字段数据结构OHLC
# 外汇数据查询:返回字段与数据结构全解(forexList / 日K / 分钟K / 海外列表)
> 接口级 · 免费 · 返回 JSON · 适用:所有接入点使用者 · 阅读时间:8 分钟
## TL;DR
- 所有接入点的业务数据都在 `showapi_res_body` 内,外层 `showapi_res_code` 只表示系统级成败。
- 四个接入点的返回结构各不相同:列表型(forexList)、日 K 型(OHLC)、分钟 K 型、海外 FXCM 型。
- 成功标志统一为 `showapi_res_body.ret_code == 0`,**没有**细分业务错误码枚举。
## Why:为什么值得先读懂字段
四个接入点返回长得不一样:有的给 `forexList` 数组,有的给 `list` 里带 `open/high/low/close`,海外列表又多出一串 `classify/pip/exchange`。动手写解析前先把结构对齐,能少踩一半坑——尤其是「时间戳单位」「哪些是字符串型数字」这类细节。
## What:公共结构与各接入点字段
| 项 | 说明 |
|----|------|
| 外层字段 | `showapi_res_code`(系统级,0=成功) / `showapi_res_error` / `showapi_res_id` / `showapi_fee_num` |
| 业务容器 | `showapi_res_body`(所有业务字段都在这) |
| 成功标志 | `showapi_res_body.ret_code == "0"`(部分接入点为 Number,判断时建议宽松比较) |
### 接入点 1:热门外汇列表(1683-1)
`forexList: Object[]`,元素:`code`(String, 编码如 `USDCNY`)、`forexName`(String, 中文名如 `美元兑人民币`)。
### 接入点 2:日线历史查询(1683-2)
`ret_code` / `remark`(如 "查询成功!") / `size`(String, 数据条数) / `list: Object[]`,元素:
`date`(String, `2018-09-04`)、`open`、`high`、`low`、`close`(均为 String 数值)、`code`、`forexName`、`time`(String, 毫秒时间戳)。
### 接入点 3:历史分钟K线查询(1683-3)
结构与日线类似,但 `list` 元素用 `datetime`(String, `2025-02-06 10:08:00`) 替代 `date`,其余 `open/high/low/close/code/forexName/time` 一致。
### 接入点 4:海外外汇列表(1683-4)
`ret_code`(Number) / `list: Object[]`,元素:`trading_time`、`classify`(FX/INDEX/COMMODITY/METAL/BUND/CRYPTO/FX_BASKET)、`forex_name`、`max_unit`、`pip`、`target_diff`、`closed_time`、`code`(如 `AUDCAD.FXCM`)、`min_stop_distance`、`min_unit`、`exchange`(FXCM)、`pip_cost`。
## How:统一解析骨架(Python)
```python
import requests
def call_1683(point: str, payload: dict, appkey: str) -> dict:
url = f"https://route.showapi.com/1683-{point}"
payload = {**payload, "appKey": appkey}
r = requests.post(url, data=payload, timeout=10)
data = r.json()
if data.get("showapi_res_code") != 0:
raise RuntimeError(data.get("showapi_res_error"))
body = data["showapi_res_body"]
if str(body.get("ret_code")) != "0":
raise RuntimeError(f"ret_code={body.get('ret_code')}")
return body
# 示例:日线
body = call_1683("2", {"code": "USDCNY", "begin": "20250120", "end": "20250201"}, "YOUR_APPKEY")
for row in body["list"]:
print(row["date"], row["open"], row["close"], row["time"])
```
## 返回示例(日线,节选)
```json
{
"showapi_res_body": {
"ret_code": 0,
"remark": "查询成功!",
"size": "10",
"list": [
{ "date": "2025-01-31", "open": "7.2507", "high": "7.2507",
"low": "7.2424", "close": "7.2507", "code": "USDCNY",
"forexName": "美元兑人民币", "time": 1738252800000 }
]
}
}
```
## 进阶 / 边界
- **时间是毫秒时间戳**:`time` 字段是 13 位毫秒,转 Python `datetime` 需 `/1000`;分钟 K 额外提供 `datetime` 字符串可直接用。
- **价格是字符串**:`open/high/low/close` 均为字符串(部分带多位小数如 `5.0822000000`),比较/计算前先 `float()`。
- **ret_code 类型不一致**:1683-1/2/3 文档标 String,1683-4 标 Number,判断统一用 `str(...)` 转换最稳。
## FAQ
**Q1:showapi_res_code 和 ret_code 都要判断吗?**
A:建议都判断。前者是系统/鉴权级,后者是业务级;任一非 0 都代表这次没拿到有效数据。
**Q2:为什么 high 和 low 有时相等?**
A:分钟 K 在某些分钟无波动时,开盘=最高=最低=收盘属正常;日线同理。
**Q3:size 是字符串还是数字?**
A:文档标注为 String,用前 `int(size)` 转换即可。
**Q4:有没有错误码对照表?**
A:没有细分业务错误码,成功统一为 `ret_code==0`,失败看 `showapi_res_error` 文案即可。
## 下一步阅读
- [外汇数据查询:日线历史查询接入点实战](https://www.showapi.com/guides/forex-daily-history-1683)
- [外汇数据查询:历史分钟K线查询接入点实战](https://www.showapi.com/guides/forex-minute-kline-1683)
- [外汇数据查询:热门外汇列表接入点详解](https://www.showapi.com/guides/forex-hotlist-guide-1683)
- **本系列共 13 篇**:查看[外汇数据查询指南总目录](https://www.showapi.com/guides/forex-guides-1683)




