股票数据 API
基础信息
- Base URL:
http://localhost:6789/api/v1/stocks - 响应格式: JSON(信封包裹
{ok, schema_version, query_time, results, ...})—— 本文所有 「响应」示例给出的都是信封内results的裸结构,客户端实际收到的是包裹后的信封 - 数据源: 日K/RTSI/资金流统一走 fox 引擎(
fox_engine.fox,本地 Parquet/MySQL 优先, 缺口才回源);详情/批量行情走RealDataSource(腾讯 + TDX + 东财 + 新浪多级降级, 腾讯为行情/估值主源) - 降级约定: 个股类端点数据级失败返回空结构 + HTTP 200(K线返回
[]、base-info返回null),只有系统级错误才透传 4xx/5xx,前端统一按「暂无数据」渲染
端点索引
/stocks 前缀下的全部在用端点;参数细节见下方分节,完整 schema 见 http://localhost:6789/docs。
| 方法 | 路径 | 参数(默认值) | 说明 |
|---|---|---|---|
| GET | /stocks/search | keyword、page=1、page_size=10 | 代码/名称/拼音模糊搜索(纯字母输入走拼音首字母与全拼;分页,不含实时行情) |
| GET | /stocks/index | — | 全量股票轻量索引(header 本地搜索数据源,行含拼音首字母/全拼两列) |
| GET | /stocks/cache-stats | — | 缓存命中率统计 |
| GET | /stocks/batch-quotes | codes | 批量行情快照(自选表格列用) |
| GET | /stocks/batch-kline | codes、days | 批量日K(自选迷你蜡烛图用),每股最近 N 条、旧→新 |
| GET | /stocks/{code} | — | 股票详情(实时行情 + 基本面) |
| GET | /stocks/{code}/base-info | — | 关键指标 + 基本信息(fox 融合层;缺失返回 null 而非 404) |
| GET | /stocks/{code}/kline | days=120(30~2000) | 日K线(统一走 fox 引擎) |
| GET | /stocks/{code}/finance | — | 财务数据(fox 融合层优先 → 新浪指标兜底 → 实时拉取) |
| GET | /stocks/{code}/finance-indicators | refresh=false | 新浪 gjzb 财务摘要 78 项指标 × 12 期 |
| GET | /stocks/{code}/finance-detail | — | 财报明细聚合:核心指标时序(含同比/单季环比)+ 变动解读 + 全量指标 |
| GET | /stocks/{code}/industry-compare | — | 行业横向对比 |
| GET | /stocks/{code}/ah-premium | — | AH 比价(仅 A+H 两地上市标的有数据) |
| GET | /stocks/{code}/vpa | — | 量价分析(健康度 + 偏多/中性/偏空观察,不给买卖指令) |
| GET | /stocks/{code}/rtsi | days(30~2000) | 趋势强度指数 RTSI(统一走 fox 引擎) |
| GET | /stocks/{code}/intraday | period=5m、days=1、use_cache=true | 分钟K线(TDX TCP 自实现 → 东财 → 新浪降级) |
| GET | /stocks/{code}/strategy-hits | days、limit | 该股本人在规则化策略执行历史中的命中记录(证据时间线) |
| GET | /stocks/{code}/tactic-hits | days、limit | 该股在「今日信号」形态战法快照中的命中记录 |
| GET | /stocks/{code}/strategy-audit | — | 单股「策略体检」:三大内置打分体系对它的当前结论聚合 |
接口列表
GET /stocks/{code}/intraday?period=5m&days=1
获取分钟 K 线(盘中高频查询,IntradayCache 30s 轮询缓存,前端 1m/5m 周期每 30s 轮询)。
参数:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| period | str | 5m | 周期:1m/5m/15m/30m/60m |
| days | int | 1 | 回看天数(1~30) |
| use_cache | bool | true | false 绕过 IntradayCache 直接回源 |
缓存语义:分钟线走独立 IntradayCache(market_data_service/intraday_cache.py)——盘中 1m/5m TTL=30s、15m=900s、30m=1800s、60m=3600s,盘后统一放宽 ≥3600s;响应带 Cache-Control: public, max-age=30(盘中)/ max-age=3600(盘后)与同值 X-Cache-TTL,source 为 cache(新鲜命中)/ cache_stale(过期复用旧数据并后台刷新)/ live(实时回源)。
响应:
{
"code": "600519",
"period": "5m",
"bars": [{"datetime": "2026-08-19 09:35:00", "open": 1295.0, "high": 1308.88, "low": 1280.34, "close": 1307.88, "volume": 38294}],
"source": "cache"
}
GET /stocks/search?keyword=茅台&page=1&page_size=10
模糊搜索股票(支持代码/名称/拼音,分页)。结果不含实时行情(price/changePercent=0), 前端通过 GET /stocks/{code} 单独获取。
拼音匹配:纯字母关键词(如 gzmt、maotai)在编码/名称 LIKE 无命中时,
走服务层拼音索引(stock_service.get_pinyin_index,pypinyin 构建,30 分钟缓存),
按 首字母前缀 > 全拼前缀 > 首字母包含 > 全拼包含 排序。该索引同时内联到
/stocks/index 下发(前端 header 搜索本地完成拼音匹配,零网络往返);
pypinyin 未安装 / DB 抖动时索引为空、拼音搜索自动跳过(编码/名称搜索不受影响)。
参数:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| keyword | str | 必填 | 股票编码或名称关键词 |
| page | int | 1 | 页码,从 1 开始 |
| page_size | int | 10 | 每页数量(1~100) |
响应(results = 命中列表,page_info 作为信封的顶层附加字段保留):
{
"ok": true,
"schema_version": 1,
"query_time": "2026-09-25T09:31:02.114322",
"results": [
{"code": "600519", "name": "贵州茅台", "industry": "白酒", "market": "SH", "price": 0, "changePercent": 0}
],
"page_info": {"cur_page": 1, "per_page": 10, "total": 1},
"data_availability": {"kline": false, "quote": false, "...": false},
"disclaimer": "…"
}
信封规则(app/core/envelope.py::_wrap):dict 载荷里 items / results / data
三个键之一会被提升为 results,其余键平铺到信封顶层(total/count 例外,它们进
stats.total)。所以前端读分页必须读 res.page_info,而不是 res.results.page_info。
GET /stocks/{code}
获取股票详情(实时行情 + 基本面)。
响应:
{
"code": "600519",
"name": "贵州茅台",
"price": 1800.0,
"changePercent": 1.25,
"peRatio": 28.5,
"pbRatio": 9.2,
"marketCap": 22600.0,
"turnoverRate": 0.35,
"totalShares": 12.56,
"floatShares": 12.56
}
GET /stocks/{code}/kline?days=120
获取日 K 线,统一走 fox 引擎(fox_engine.fox.get_daily_kline):
读路径为 SQLite 快路径 → Parquet 镜像 → MySQL fox_kline_daily,缺口才回源,
不再是早期的「腾讯 → TDX → 东财」逐次三级降级(那条链现在是 fox 融合层的写入侧)。
参数:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
| days | int | 120 | K线根数(30~2000) |
Cache-Control 由服务端按 is_trading_hours() 现算:盘中 30s、盘后 300s。
曾有缺陷是固定 300s —— 浏览器会把盘中 K 线缓存整整 5 分钟,与内部 30s 刷新脱节。
改 K 线读路径时不要把它写回常量。失败时返回 [](HTTP 200)而不是 500。
多周期(week/month/quarter/year)K 线走
/api/v1/datamgr/fox/stock/{code}/kline-bar。
响应(信封内 results 为数组,stats.total 为根数):
[
{"date": "2026-07-18", "open": 1780.0, "close": 1800.0, "high": 1810.0, "low": 1775.0, "volume": 25000, "amount": 4500000000}
]
GET /stocks/{code}/finance
获取财务数据(多级降级:fox_ 融合层优先 → sina_financial_indicator 兜底 → 实时拉取)。
fox_ 融合层为多源融合结果(sina_financial_indicator 主源 + TDX 快照兜底),命中且 ≥2 期时直接返回,不再触发网络拉取;仅数据不足时回退实时链路补充,避免趋势图退化。
响应:
[
{"year": 2025, "report_period": "2025-12-31", "revenue": 150000000000, "netProfit": 75000000000, "roe": 32.5}
]
GET /stocks/{code}/industry-compare
同行业标的横向对比列表。走实时数据源(东财行业对比接口,stock_service.get_industry_compare),
带 industry 前缀缓存;原 stock_base_info 本地路径已随该表于 2026-08-22 移除。
失败时降级为空数组(HTTP 200),前端按「暂无数据」处理。
数据源切换
通过环境变量 DATA_SOURCE 控制:
| 值 | 数据源 | 说明 |
|---|---|---|
real | RealDataSource | 推荐,多源降级 |
akshare | AkshareDataSource | 直连东财/新浪(等效akshare) |
mock | MockDataSource | 模拟数据(开发测试) |
tushare | TushareDataSource | 预留(需TUSHARE_TOKEN) |