Agent-ready A-share market and research data SDK with Tushare, iFinD, MinIO, REST and MCP.
Project description
n-ashare-market
面向程序与 Agent 的 A 股市场数据 SDK。当前版本提供:
- Tushare 历史日线:
none / qfq / hfq; - iFinD
THS_RQ实时行情快照; - Insight 历史 tick 与
1/5/15/30/60minK 线; - Insight 实时 tick/1min 单会话订阅与 SSE;
- 完整覆盖旧
ashare-history-system的 41 个数据集与 8 个引用表; - 在旧范围之上额外提供财务报表、Insight 1min/tick 和实时能力;
- MinIO raw/curated Parquet、覆盖清单、实时归档和带鉴权的外部下载;
- MinIO 实时小对象安全 compact;
- 本地/远程 Python SDK;
- FastAPI REST/OpenAPI;
- MCP tools/resources;
- JSON 友好的来源、新鲜度、覆盖度和 artifact 元数据。
Insight 使用独立 subprocess bridge,可继续运行在供应商要求的 Python 3.7 环境,主 SDK 保持 Python 3.11+。
1. 架构
Tushare history ─┐
iFinD snapshot ──┼─ MarketDataService ─ normalization ─ MinIO curated/catalog
Insight bridge ──┘ └────────── MinIO realtime/artifacts
│
├─ Python SDK
├─ REST / OpenAPI
├─ CLI
└─ MCP Server
MinIO 是持久化缓存和分发层,不承担实时消息总线职责。实时请求先由 iFinD 返回给调用方,再将快照微批归档到 MinIO。
详细设计见 docs/architecture.md,数据目录和全量重建见 docs/research.md,旧系统逐项覆盖见 docs/legacy-coverage.md。
2. 安装
Python 需要 3.11 或更高版本。
cd ashare-market-sdk
python -m venv .venv
. .venv/bin/activate
pip install -e .
cp .env.example .env
从 PyPI 安装发布版本:
pip install n-ashare-market
从 Git 仓库安装 Python SDK
仓库发布后,客户端不需要复制源码。推荐打 tag 后固定版本安装:
pip install "n-ashare-market @ git+https://gitlab.thoughtyard.com.cn/aion/ashare-market-sdk.git@v0.5.0"
私有仓库建议使用已经配置好的 SSH key,避免把访问 token 写入命令或日志:
pip install "n-ashare-market @ git+ssh://git@gitlab.thoughtyard.com.cn/aion/ashare-market-sdk.git@v0.5.0"
如果以后把它放在一个 monorepo 的 ashare-market-sdk/ 子目录,则使用:
pip install "n-ashare-market @ git+https://gitlab.example.com/YOUR_ORG/YOUR_REPO.git@v0.5.0#subdirectory=ashare-market-sdk"
安装后验证命令是否在 PATH(这一步由部署人员执行):
ashare-market --help
iFinD 的 iFinDPy 使用官方 SDK 安装包,不包含在 PyPI 依赖中。运行 REST/MCP 的 Python 环境必须能够执行:
import iFinDPy
默认使用主服务当前 Python 运行 Insight bridge,不需要配置解释器路径。如果供应商 SDK 只能安装在 独立 Python 环境,该环境至少需要 Insight SDK、pandas 和可写 Parquet 的 pyarrow,再覆盖:
ASHARE_MARKET_INSIGHT_USERNAME=...
ASHARE_MARKET_INSIGHT_PASSWORD=...
ASHARE_MARKET_INSIGHT_PYTHON=/absolute/path/to/separate/.venv/bin/python
桥接部署细节见 docs/insight.md。
然后在 .env 中配置:
ASHARE_MARKET_TUSHARE_TOKEN=...
ASHARE_MARKET_IFIND_USERNAME=...
ASHARE_MARKET_IFIND_PASSWORD=...
不要把真实 token、用户名或密码提交到仓库。
3. 启动 MinIO
docker compose -f deploy/docker-compose.minio.yml up -d
ashare-market ensure-buckets
默认地址:
- S3 API:
http://127.0.0.1:9000 - Console:
http://127.0.0.1:9001
ensure-buckets 会创建并启用版本控制:
ashare-curatedashare-rawashare-realtimeashare-artifactsashare-catalog
一键启动完整服务
配置好 .env 后,一条命令启动 MinIO、REST API、Streamable HTTP MCP、历史同步和实时监督器:
./deploy/start.sh
停止服务:
./deploy/stop.sh
不使用 Docker 时可先启动 MinIO,然后直接运行:
ashare-market serve --host 0.0.0.0 --port 8020
启动完成后,REST 地址为 http://<服务器>:8020,MCP 地址为
http://<服务器>:8020/mcp。MCP 作为 ASGI 子应用挂载到 REST 服务,共用同一个 MarketDataService、
MinIO client、查询缓存、Provider 限流器和运行时监督器。
默认自动同步 stock_basic,trade_cal,daily,daily_basic,adj_factor,stk_limit。首次运行会按照 coverage 断点回补历史,之后在配置的数据就绪时间后增量刷新。实时订阅只有在
ASHARE_MARKET_RUNTIME_REALTIME_SYMBOLS 明确配置股票列表时才启用。运行状态可通过
GET /v1/runtime 查看;容器同步日志可通过
docker compose --project-directory . -f deploy/docker-compose.yml logs -f ashare-market 跟踪。
4. Python SDK
本地模式
本地模式在当前 Python 进程中直接调用 Tushare、iFinD 和 MinIO。
from ashare_market import AshareMarketClient
with AshareMarketClient() as client:
bars = client.history.daily(
["000001.SZ", "600000.SH"],
"2025-01-01",
"2025-03-31",
adjustment="qfq",
cache_policy="cache_first",
)
print(bars.dataframe)
print(bars.meta)
# 标准化前的 Tushare pro_bar 原始字段。
raw_bars = client.history.raw_daily(
"000001.SZ",
"2025-01-01",
"2025-01-31",
)
quotes = client.realtime.quotes(["000001.SZ", "600000.SH"])
print(quotes.dataframe)
artifact = client.history.export_daily(
"000001.SZ",
"2020-01-01",
"2025-01-01",
file_format="parquet",
)
print(artifact["download_url"])
client.download_artifact(artifact, "daily.parquet")
minute = client.history.minutes(
"000001.SZ",
"2026-07-16 09:30:00+08:00",
"2026-07-16 15:00:00+08:00",
frequency="5min",
adjustment="qfq",
)
ticks = client.history.ticks(
"000001.SZ",
"2026-07-16 09:30:00+08:00",
"2026-07-16 10:00:00+08:00",
)
indicators = client.research.query(
"fina_indicator",
symbols="000001.SZ",
start_date="2024-01-01",
end_date="2026-07-17",
)
# reference 数据集不需要日期,使用 TTL 缓存。
stocks = client.research.query("stock_basic")
远程模式
from ashare_market import AshareMarketClient
with AshareMarketClient(
base_url="http://127.0.0.1:8020",
api_key="your-api-key",
) as client:
bars = client.history.daily("000001.SZ", "2025-01-01", "2025-01-31")
index_bars = client.research.query(
"index_daily",
symbols="000300.SH",
start_date="2025-01-01",
end_date="2025-01-31",
)
# 一次生成回测窗口需要的三张完整 Parquet;不再把全市场拆成上千次 JSON 请求。
bundle = client.backtests.export(
["000001.SZ", "600000.SH"],
"2026-07-01",
"2026-07-17",
lookback_bars=120,
)
for dataset, artifact in bundle["datasets"].items():
client.download_artifact(artifact, f"{dataset}.parquet")
SDK 主服务应该在哪里运行
生产环境推荐在一台常驻 Linux 数据服务器上运行单实例 REST 服务和 MCP 服务。Tushare、iFinD、
Insight 与 MinIO 凭证只放在服务器;研究终端、策略程序和 Agent 只安装 Python 包并使用上面的
base_url 远程模式。这样缓存、额度控制、Insight 会话和审计口径只有一份。
- REST 主服务使用单 Uvicorn worker;当前 Insight session 状态在进程内,多 worker 会产生多个互不共享的会话。
- MCP stdio 可运行在 Agent 所在机器并通过远程 Python SDK/REST 访问主服务;受信任环境也可直接在数据服务器运行 MCP。
- MinIO 开发时可以同机,生产建议独立磁盘或独立节点,并备份 catalog bucket。
- 只有单机研究或开发场景才建议本地模式;它会让每个客户端分别持有 Provider 登录和频次。
systemd 示例见 deploy/ashare-market.service.example,完整运维说明见 docs/operations.md。
缓存策略
| 策略 | 行为 |
|---|---|
cache_only |
只读 MinIO,不调用 Provider;允许返回部分覆盖 |
cache_first |
coverage commit 完整时读 MinIO,否则从 Tushare 刷新并写 MinIO |
refresh |
强制从 Tushare 获取,并发布新的不可变对象和 commit |
direct |
直接从 Tushare 获取,不读写 MinIO |
5. REST / OpenAPI
ashare-market api --host 127.0.0.1 --port 8020
- OpenAPI:
http://127.0.0.1:8020/docs GET /health:只显示配置能力,不登录 Provider;GET /ready:连接 MinIO 并确保 bucket 存在;GET /v1/datasets;GET /v1/datasets/{name}/schema;GET /v1/compatibility/ashare-history-system;GET /v1/runtime:同步、紧凑化和实时状态;GET /v1/artifacts/{object_name}:经 REST 同源鉴权下载真实对象;POST /v1/history/daily;POST /v1/history/daily-raw;POST /v1/backtests/export:一次导出daily/daily_basic/stk_limit完整 Parquet;POST /v1/realtime/quotes;POST /v1/coverage/daily。POST /v1/coverage/daily-raw;POST /v1/history/intraday;POST /v1/coverage/intraday;POST /v1/realtime/sessions;GET /v1/realtime/sessions/{id}/events;GET /v1/realtime/sessions/{id}/stream;POST /v1/realtime/compact。GET /v1/research/datasets;POST /v1/research/query;POST /v1/research/coverage;POST /v1/research/sync。POST /v1/datasets/sync(通用别名)。
日线示例:
curl -X POST http://127.0.0.1:8020/v1/history/daily \
-H 'Content-Type: application/json' \
-H 'X-API-Key: your-api-key' \
-d '{
"symbols":["000001.SZ"],
"start_date":"2025-01-01",
"end_date":"2025-01-31",
"adjustment":"qfq",
"cache_policy":"cache_first"
}'
当结果超过 ASHARE_MARKET_API_MAX_ROWS,接口会创建完整 Parquet artifact。Python 客户端看到
truncated=true 后会自动通过带 X-API-Key 的同源代理下载完整 Parquet,不再静默返回前 2,000 行。
ASHARE_MARKET_PUBLIC_BASE_URL 配置后,meta.artifact.download_url 是外部可达的 REST URL;未配置时返回
/v1/artifacts/... 相对路径,不再暴露容器内的 minio:9000。
为什么数据目录里只有 xl.meta
deploy/data 是 MinIO 的私有 XL 后端目录,不是普通文件导出目录。一个逻辑上的 .parquet S3 对象在磁盘上会表现为
同名目录和 xl.meta,小对象还可能直接内联在元数据中;因此不能对该目录直接运行 parquet-tools。应从 MinIO Console、
S3/mc 或上述 REST artifact 接口下载对象后再检查,例如:
parquet-tools inspect daily.parquet
新写 EOD 数据按“请求批次 + 交易日”合并成 symbol_bucket=all;后台还会从最近月份向历史月份逐月生成活跃紧凑快照。
旧 hash 小对象暂不物理删除,读取会在紧凑快照更新后自动跳过它们,便于回滚和后续按生命周期安全清理。
6. MCP / Agent
stdio 模式:
ashare-market mcp --transport stdio
Streamable HTTP 随 REST 服务一起启动:
ashare-market serve --host 0.0.0.0 --port 8020
客户端连接 http://<服务器>:8020/mcp。配置 ASHARE_MARKET_API_KEY 后,REST 与 MCP 都要求相同的
X-API-Key;对外暴露时仍应通过反向代理配置 TLS。
可用工具:
market_list_datasetsmarket_get_schemamarket_get_legacy_coveragemarket_get_realtime_quotesmarket_get_daily_barsmarket_get_raw_daily_barsmarket_get_raw_daily_coveragemarket_get_daily_coveragemarket_create_daily_exportmarket_create_backtest_exportmarket_get_minute_barsmarket_get_tick_historymarket_get_intraday_coveragemarket_create_intraday_exportmarket_start_insight_sessionmarket_get_insight_sessionmarket_get_insight_eventsmarket_stop_insight_sessionmarket_compact_realtimemarket_list_research_datasetsmarket_query_researchmarket_get_research_coveragemarket_create_research_exportmarket_sync_research_datasetmarket_sync_dataset
可用 resources:
ashare://datasets/catalogashare://datasets/{dataset}/schemaashare://research/catalogashare://compatibility/ashare-history-system
通用 stdio MCP 配置示例:
{
"mcpServers": {
"ashare-market": {
"command": "/absolute/path/to/ashare-market-sdk/.venv/bin/ashare-market-mcp",
"env": {
"ASHARE_MARKET_MINIO_ENDPOINT": "127.0.0.1:9000"
}
}
}
}
凭证应配置在服务器的 .env 或密钥系统中,不要复制到 Agent prompt 或 MCP tool 参数里。
7. CLI
ashare-market datasets
ashare-market legacy-coverage
ashare-market daily --symbols 000001.SZ --start 2025-01-01 --end 2025-01-31
ashare-market quotes --symbols 000001.SZ,600000.SH
ashare-market coverage --symbols 000001.SZ --start 2025-01-01 --end 2025-01-31
ashare-market daily --symbols 000001.SZ --start 2020-01-01 --end 2025-01-01 --export parquet
ashare-market intraday --symbols 000001.SZ \
--start '2026-07-16 09:30:00+08:00' --end '2026-07-16 15:00:00+08:00' \
--kind 5min --adjustment qfq
# 实时 session 由常驻 API 服务持有;CLI 通过 REST 操作它。
ashare-market --base-url http://127.0.0.1:8020 stream-start \
--symbols 000001.SZ,600000.SH --tick --kline
ashare-market --base-url http://127.0.0.1:8020 stream-sessions
ashare-market --base-url http://127.0.0.1:8020 stream-events SESSION_ID --after 0
ashare-market --base-url http://127.0.0.1:8020 stream-stop SESSION_ID
ashare-market compact-realtime --dataset tick --trade-date 2026-07-17
ashare-market research-list
ashare-market research fina_indicator --symbols 000001.SZ \
--start 2024-01-01 --end 2026-07-17
# 默认按 coverage 断点续跑;不传日期时使用数据集默认全量起点。
ashare-market research-sync daily_basic
ashare-market research-sync income --start 2010-01-01 --end 2026-07-17
# `sync` 是面向全部注册数据集的等价短命令。
ashare-market sync daily
ashare-market sync weekly
ashare-market sync etf_daily --symbols 510300.SH,159915.SZ
ashare-market sync index_daily --symbols 000300.SH
ashare-market sync kline_5min --symbols 000001.SZ --start 2026-01-01 --end 2026-07-17
8. 当前边界
- 股票、ETF、指数和概念/行业代码型行情要求明确代码列表;全市场日频与事件表支持按日期分块同步。
- MinIO catalog 采用不可变 JSON commit,并有 TTL 索引缓存和有界并发读取;更大规模部署仍可引入数据库或 Iceberg catalog。
- iFinD 实时快照为请求式
THS_RQ;推送式 tick/1min 由 Insight 提供。 - 当前实时 manager 状态保存在 API 进程内,API 重启后需重新创建 session;已归档数据不受影响。
- EOD 旧小对象由后台按月紧凑,无需从 Provider 重抓;物理清理旧版本仍由运维生命周期策略控制。
- 已覆盖旧系统全部 41+8 数据;基金范围目前仅包含旧系统已有的场内 ETF 日线,不扩展债券、期货、宏观和海外市场。
- MinIO 内数据的共享范围必须符合 Tushare、iFinD 和 Insight 的账户授权与再分发条款。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters