教程

用 /v1/quote 查实时行情与日 K 收盘价

查一只股票"现在多少钱"只需一次 GET —— `/v1/quote` 免 Key、免注册,返回最近 30 个交易日的 OHLC(开/高/低/收)+ 成交量额 + 换手率,`data[0]` 就是最新一天。适合做行情展示、复盘取数、批量取收盘价的底座。

一、先看最常用的 5 行代码

`/v1/quote` 是免费端点(无需 Key、无需注册)。核心参数只有 `code`,返回统一信封 `{ ok, endpoint, tier, elapsed_ms, source, data }`,`data` 是从新到旧的日数组(默认 30 条),`data[0]` = 最近交易日。

Python:取一只股票的最新价
import requests

r = requests.get(
    "https://api.ashareapi.com/v1/quote",
    params={"code": "sh600667"},   # 必须带市场前缀
    timeout=10,
)
body = r.json()
if not body.get("ok"):
    raise RuntimeError(body)        # 失败时返回 ok=false + error

bar = body["data"][0]               # 最近一个交易日
print(bar["date"], bar["last"], bar["turnover"])
  • `code` 必须带市场前缀:`sh600667`(沪)/ `sz000001`(深)/ `bj920002`(北交所)/ `hk00700`(港股)/ `usAAPL`(美股)—— 纯 6 位会返回空
  • `data` 是数组(默认 30 条,`data[0]` 最新),不是单个对象

二、字段含义与单位(最关键,别搞错)

date
交易日
YYYY-MM-DD,是数据日期不是查询日期
open / high / low
开 / 最高 / 最低
字符串形式的数字
last
收盘价(上一交易日)
不是盘中实时价 —— 见第三节
volume
成交量
手(×100 = 股)
amount
成交额
元(不是万、不是亿)
turnover
换手率
百分数(4.92 = 4.92%)

口径提醒:`volume` 是手、`amount` 是元、`turnover` 是百分数 —— 这三个单位是新手最常踩的坑(把 4.92 当成 4.92 元、把 volume 当成股)。同一字段在 `/v1/kline` 也是同名同值(口径一致,可放心混用)。

三、"实时价"还是"收盘价"?—— 数据日期语义

`/v1/quote` 的 `last` 是该交易日的收盘价,`date` 告诉你这是哪一天。盘中调用时 `data[0].date` 就是当天,`last` 是截至请求时刻的最新价(可视为当前价);盘后调用时则是当天收盘价。所以判断"是不是实时"看 `date` 是否等于今天即可。

这是设计使然:同一个端点既可当"实时行情"也可当"历史收盘价"用,靠 `date` 区分。想做纯展示(页面显示"现价"),先检查 `date` 是否是今天,避免把昨日收盘价当现价展示(这是最常见的误导)。

  • 盘中:`date` = 今天 → `last` 是当前最新价
  • 盘后 / 休市:`date` = 最近交易日 → `last` 是收盘价
  • 判断方法:`bar["date"] == 今天`(或按交易日历判断)

四、批量取多只股票(并发 + 限流)

`/v1/quote` 每次只接收一个 `code`(不是逗号分隔)。要取多只,用线程池并发,并注意匿名限流:5 次/分钟。

Python:并发取多只(含限流说明)
from concurrent.futures import ThreadPoolExecutor
import requests

def q(code):
    r = requests.get("https://api.ashareapi.com/v1/quote",
                     params={"code": code}, timeout=10)
    j = r.json()
    if not j.get("ok"):        # 429 限流 / 401 也会走这里
        return code, j.get("error")
    return code, j["data"][0]["last"]

codes = ["sh600667", "sz000001", "sh600519"]
with ThreadPoolExecutor(max_workers=3) as ex:
    for code, price in ex.map(q, codes):
        print(code, price)
  • 匿名 5 次/分钟:超过会返回 429;需要更高频率 → 解一次 PoW 挑战提到 60 次/分钟(见第五节),或申请 Key
  • 并发不要太高:3~5 个线程足够,太高只会更快撞限流

五、撞到 429 怎么办(免费提速)

匿名调用每秒/每分钟有配额,超了返回 `429 Too Many Requests`。`/v1/challenge` 是免费提速通道:取一个挑战(PoW),解出后用 `X-PoW` 头带回来,匿名配额从 5 次/分钟 → 60 次/分钟。

Python:取挑战 → 解 → 提速调用
import requests

# 1) 取挑战(difficulty 只能调高不能调低)
ch = requests.get("https://api.ashareapi.com/v1/challenge", timeout=10).json()
# ch = {"challenge": ..., "difficulty": 18, ...}

# 2) 解 PoW:找一个 nonce 使 sha256(challenge+nonce) 前 difficulty 位为 0
#    (细节见 /docs/errors;大多数场景直接申请 Key 更省事)

# 3) 带着 X-PoW 调用,配额提升
# r = requests.get("https://api.ashareapi.com/v1/quote",
#                  params={"code": "sh600667"},
#                  headers={"X-PoW": solved}, timeout=10)
  • 日常够用:单机展示/复盘 5 次/分钟通常够;批量任务建议直接申请 Key(见 /pricing)
  • 429 不要死循环重试:退避几秒再试,或降低频率

六、quote 和 kline 有什么区别?

用途
行情快照 + 最近 30 日
历史 K 线(可指定周期/条数)
参数
code
code / period / count
默认返回
最近 30 个交易日
最近 30 根(count 最大 1212)
复权
不复权语义(原始价)
前复权(除权日不跳空)
字段
date/open/high/low/last/volume/amount/turnover
同名同值

一句话:要"现在/最近几天的价"用 `quote`;要"完整历史走势、算指标、回测"用 `kline`(前复权)。两者字段口径一致,互相接得上。

常见问题

为什么返回的是收盘价,不是实时价?

看 `data[0].date`:等于今天时 `last` 就是盘中最新价(可当现价用);等于历史日期时就是那天收盘价。这个端点设计上同时服务"实时快照"和"收盘价取数"两种用途,用 date 区分,避免把昨日收盘价当现价。

volume 是股还是手?amount 是元还是万元?

volume 单位是手(1 手 = 100 股),amount 单位是元,turnover 是百分数(4.92 表示 4.92%)。这三个是最容易搞错的单位,建议在代码里统一注释。

可以一次查多只股票吗?

不能 —— `/v1/quote` 每次一个 code。批量请用线程池并发,并注意匿名限流(5 次/分钟);高频需求建议申请 Key 或用 /v1/challenge 解 PoW 提额到 60 次/分钟。

code 要带前缀吗?可以只传 600667 吗?

必须带市场前缀(sh600667 / sz000001 / bj920002 / hk00700 / usAAPL)。只传 6 位数字会返回空结果(不是报错),这是最常见的新手问题。

这个端点收费吗?

免费 —— 无需注册、无需 Key,匿名即可调用(限流 5 次/分钟)。更高额度见 /pricing。

最后更新: 2026-10-01

数据来自 ashareapi /v1/quote 线上实测(2026-10-01:600667 返回 30 条,data[0] date=2026-09-30 last=17.29 high=18.28 volume=1029096 amount=1804480000 turnover=4.92);字段与单位经线上响应核对。