Python SDK
为量化研究员量身打造的高性能 Python 数据客户端
pip install quantdb-sdk
SDK 设计理念 Design Principles
quantdb-sdk 封装了 QuantDB 的全量 RESTful 与对象存储直连接口,提供同步(QuantDBClient)和异步(AsyncQuantDBClient)两种调用方式。所有查询与下载接口直接产出经过清洗和类型转换的标准 pandas DataFrame,无缝对接 NumPy、Polars、Backtrader、Qlib 与 LightGBM 等研究框架。
安装与依赖 Installation
pip install quantdb-sdk
开发或贡献源码时,可从本地仓库执行可编辑安装:
# 安装核心依赖与开发测试组件
pip install -e ".[dev]"
concurrent.futures.ThreadPoolExecutor(max_workers=8) 或 asyncio.Semaphore(8))。实测 8 线程可跑满千兆带宽,同时维持极低的本地内存与连接开销。服务端接口不限频,连续拉取数千文件不会触发 429 限制。
初始化客户端 Authentication
方式一:API Key 鉴权(强烈推荐)
通过环境变量读取 API Key,杜绝密钥泄露风险:
import os from quantdb_sdk import QuantDBClient # 从环境变量 QUANTDB_API_KEY 获取凭据 client = QuantDBClient(api_key=os.environ["QUANTDB_API_KEY"])
方式二:账户密码登录(获取 24h JWT Bearer Token)
client = QuantDBClient(
username="trader01",
password="your_secure_password"
)
核心方法一览 Method Matrix
client.data
统一入口
只凭数据集名跨 6 大分类取数(在线 + 本地零流量)
get_me()
账户
获取当前登录用户的基本信息与角色
get_usage()
用量
查询当前周期流量消耗与订阅限额明细
list_api_keys()
鉴权
列出账户下已激活的 API Key 列表
create_api_key()
鉴权
生成新的量化访问密钥 API Key
query_kline()
行情
极速查询日线 / 分钟线,直出 DataFrame
query_tick()
高频
下载指定交易日 Tick 逐笔与五档盘口明细
query_etf_kline()
ETF
查询 ETF 日 K 线(510300.SH 等),直出 DataFrame
query_stock_list()
基础
全市场股票代码、简称与板块元数据搜索
query_calendar()
基础
获取交易日历与休市安排(零流量)
preview_as_df()
免流
Parquet 尾部免流量字段与格式预览
download_file()
存储
高速并发流式下载原始 Parquet 切片至本地
load_as_df()
内存
远端 Parquet 直读内存 DataFrame,不落盘
sync_dataset()
增量
基于 Release Cursor 的全自动本地增量同步
DuckDBWarehouse
DuckDB
挂载本地多表 Parquet,零流量执行 SQL JOIN
query_local()
DuckDB
基于本地单切片执行极速 DuckDB SQL 查询
create_order()
订单
创建专业版订阅订单并获取支付宝支付链接
AsyncQuantDBClient
异步
原生 asyncio 异步并发客户端
账户与用量查询 Account & Usage
# 查询已用流量与当前订阅状态(套餐额度与流量包额度分开返回) usage = client.get_usage() print(f"套餐: 已用 {usage['plan_used_gb']:.2f} / {usage['plan_total_gb']:.2f} GB,剩余 {usage['plan_remaining_gb']:.2f} GB") print(f"流量包: 已用 {usage['package_used_gb']:.2f} / {usage['package_total_gb']:.2f} GB,剩余 {usage['package_remaining_gb']:.2f} GB") print(f"合计: 已用 {usage['used_gb']:.2f} / {usage['total_gb']:.2f} GB,剩余 {usage['remaining_gb']:.2f} GB") print(f"订阅状态: {usage['subscription'].get('status')}")
API Key 管理 Key Management
专业版用户支持 1 个有效 API Key。API Key 永久有效,可随时重新生成:
# 列出已有 Key keys = client.list_api_keys() # 创建新 Key new_key = client.create_api_key(description="Quant Server 01") print(new_key["key"])
订阅与在线支付 Subscription & Orders
SDK 原生支持列出套餐、创建订单并拉起支付宝网页支付:
# 1. 列出可购买套餐 plans = client.list_plans() for p in plans: print(p["id"], p["name"], p["amount_yuan"]) # 2. 创建专业版月付订单(¥99 / 月) order = client.create_order(plan_id="pro-monthly") print("支付链接:", order["pay_url"]) # 3. 校验订单状态 status = client.get_order(order_id=order["order_id"]) print(status["status"])
V1 / V2 物理数据布局 Storage Architecture
QuantDB 针对不同数据特征采用最优物理存储策略:
- V2 按日全市场分区 (
dt=YYYYMMDD/data.parquet):高频时序与因子数据集,每个交易日新增一个分区,单次范围请求仅下载所需日期切片。 - V1 逐股票全历史文件 (
{Symbol}.parquet):财务、股本等低频季报数据,按标的单独存储。
纯 V2 按日分区数据集列表
| 数据集 | sub_category | 日期范围 | 更新状态 |
|---|---|---|---|
| 日线不复权 | daily_unadjusted | 2016-01-04 ~ 至今 | 每日更新 |
| 日线前复权 | daily_forward | 2016-01-04 ~ 至今 | 每日更新 |
| 日线后复权 | daily_backward | 2016-01-04 ~ 至今 | 每日更新 |
| 指数日线 | index_daily | 2016-01-04 ~ 至今 | 每日更新 |
| 1 分钟 K 线 | min1_kline | 2016-01-04 ~ 至今 | 每日更新 |
| 5 分钟 K 线 | min5_kline | 2016-01-04 ~ 至今 | 每日更新 |
| Tick 逐笔 | tick_data | 2026-09-03 起(按日) | 每日更新 |
| ETF 日 K 线 | etf_kline | 2006-04-24 ~ 至今 | 每日更新 |
| 估值指标 | valuation | 2016-01-04 ~ 至今 | 每日更新 |
| 技术指标 | technical_indicators | 2016-01-04 ~ 至今 | 每日更新 |
| 盘口情绪 | market_sentiment | 2016-01-04 ~ 至今 | 每日更新 |
| 日频特征 | features_daily | 2016-01-04 ~ 至今 | 每日更新 |
| L1 日频因子 | l1_factors | 2016-01-04 ~ 至今 | 每日更新 |
| 融资融券 | margin_trading | 2016-01-04 ~ 至今 | 每日更新 |
| L2 高频因子 | l2_factors | 2023-01-01 ~ 至今 | 每日更新 |
| 训练宽表(300+ 维) | l1_l2_factors | 2023-01-01 ~ 至今 | 每日更新 |
client.data — 统一数据入口 0.4.0
client.data 是跨分类的统一取数入口:只凭 dataset 名即可访问全部 6 大分类目录,无需再手填 category_id + sub_category。SDK 侧自动解析分类并路由,同时覆盖在线查询与本地零流量读取。异步客户端对应 client.data(方法统一 a_ 前缀,如 a_read_local())。
发现与元数据(零流量)
# 列出全部数据集(可按分类 / 访问级别 / 关键词过滤) print(client.data.datasets().head()) print(client.data.datasets(category="6")) # ML 数据集分类 print(client.data.datasets(keyword="复权")) # 数据集详情 + 云端元数据(覆盖区间 / 文件数 / 文件大小) print(client.data.info("l1_factors"))
在线查询与本地零流量读取
# 在线查询:按数据集名自动路由(日线 / ETF / Tick / V2 / V1) df = client.data.query( "daily_forward", symbol="600519.SH", start_date="2026-09-01", end_date="2026-09-05" ) tick = client.data.query("tick_data", symbol="600519.SH", trade_date="20260924") # 本地零流量读取(root 缺省读 QUANTDB_DATA_DIR,可显式指定) local = client.data.read_local("daily_forward", start_date="2026-09-01") paths = client.data.local_files("balance", symbol="600519.SH") # 本地优先,缺失时才显式回退在线(会消耗流量) df2 = client.data.read("valuation", symbol="600519.SH", prefer="local") # 其余映射:preview / load / download / sync / mount client.data.preview("balance", symbol="600519.SH", limit=5)
datasets() / info() / local_files() / local_path() / read_local() 全程不发起下载;read() 默认本地优先,仅在本地缺失时才回退在线,避免静默消耗流量。
query_kline — K 线数据查询 Data Query
# 查询贵州茅台前复权日线(返回 DataFrame) df = client.query_kline( symbol="600519.SH", adj_type="forward", start_date="2026-01-01", end_date="2026-07-22" ) print(df.head()) # 仅查询收盘价与成交量字段 df_mini = client.query_kline("000001.SZ", fields="close,volume", limit=20)
query_etf_kline — ETF 日 K 线查询 ETF Kline
查询分类 4 的 etf_kline(V2 按日分区,symbol 形如 510300.SH)。auto 优先 V2 日切片,日期范围覆盖不完整时回退 V1 逐股票文件。
# 查询沪深 300 ETF 日 K 线 df_etf = client.query_etf_kline( symbol="510300.SH", start_date="2026-09-01", end_date="2026-09-03" ) print(df_etf.head())
query_partition_size — 各子分类分区大小 0.3.5
查询各数据子分类的分区大小,用于估算下载流量与数据占用。返回分区数 file_count、总字节 file_size 与换算列 file_size_gb;缺省返回全部子分类,可传 sub_category 单查。异步版为 a_query_partition_size()。
# 查询全部子分类的分区大小 df_sizes = client.query_partition_size() print(df_sizes[["dimension", "file_count", "file_size_gb"]].to_string(index=False)) # 只查 daily_forward 一个子分类的字节数(用于评估该数据集下载流量) df_one = client.query_partition_size(sub_category="daily_forward") print(df_one)
query_tick — Tick 分笔高频数据 High Frequency
# 下载平安银行指定交易日五档 Tick 数据 df_tick = client.query_tick( symbol="000001.SZ", trade_date="20260720", start_ts="09:30:00", end_ts="11:30:00" ) print(df_tick.head())
sync_dataset — 本地增量同步 Incremental Sync
通过服务端的 Release Cursor 实现微秒级差异比对。支持断点续传、临时文件原子替换与本地 MD5 对账跳过:
# 首次同步自动初始化本地 quantdb_sync.sqlite 元数据库 result = client.sync_dataset("daily_forward", save_dir="D:/quantdb-data") print(f"已下载: {len(result['downloaded'])} 个, 对账跳过: {len(result['matched'])} 个") # 财务表增量同步(支持断点重试) financial = client.sync_dataset("balance", save_dir="D:/quantdb-data") # ETF 日线增量同步(0.3.5 起支持) etf = client.sync_dataset("etf_kline", save_dir="D:/quantdb-data")
DuckDBWarehouse — 本地极速 SQL 引擎 Local DuckDB Engine
将本地已同步的多个 Parquet 数据集注册为内存 DuckDB 视图,零流量毫秒级执行复杂多表关联(SQL JOIN):
from quantdb_sdk import QuantDBClient, DuckDBWarehouse client = QuantDBClient(api_key=os.environ["QUANTDB_API_KEY"]) wh = client.get_local_warehouse() # 挂载日线行情与财务利润表为本地 View wh.mount_dataset("1", "daily_unadjusted", symbol="600519.SH", view_name="kline") wh.mount_dataset("3", "income", symbol="600519.SH", view_name="income") # 零流量本地 SQL JOIN 查询 df_join = wh.query(""" SELECT k.trade_date, k.close, i.net_profit_excl_min_int_inc FROM kline k LEFT JOIN income i ON k.trade_date = i.m_anntime ORDER BY k.trade_date DESC LIMIT 20 """) print(df_join)
300+ 维 ML 特征宽表装载 AI / ML Training
# 一键将 300+ 维预计算模型训练宽表装入内存 df_factors = client.load_as_df(category_id="6", sub_category="l1_l2_factors", symbol="train_factors_2026q1") print(df_factors.shape) # (175217 行, 367 列) # 直接喂入 LightGBM 训练 import lightgbm as lgb feature_cols = [c for c in df_factors.columns if c not in ["wind_code", "date", "target_5d"]] train_data = lgb.Dataset(df_factors[feature_cols], label=df_factors["target_5d"]) model = lgb.train({}, train_data, num_boost_round=100)
AsyncQuantDBClient — 异步高并发 AsyncIO
import asyncio from quantdb_sdk import AsyncQuantDBClient async def main(): client = AsyncQuantDBClient(api_key=os.environ["QUANTDB_API_KEY"]) # 异步并发请求多只股票日线 tasks = [ client.a_query_kline("600519.SH", adj_type="forward"), client.a_query_kline("000858.SZ", adj_type="forward"), client.a_query_stock_list(keyword="芯片"), ] results = await asyncio.gather(*tasks) for df in results: print(df.shape) asyncio.run(main())
典型策略场景实战 Strategy Recipes
场景:双均线金叉策略回测
import pandas as pd df = client.query_kline("600519.SH", adj_type="forward", start_date="2025-01-01") df["ma5"] = df["close"].rolling(5).mean() df["ma20"] = df["close"].rolling(20).mean() # 信号生成:MA5 上穿 MA20 买入,下穿卖出 df["signal"] = 0 df.loc[df["ma5"] > df["ma20"], "signal"] = 1 df.loc[df["ma5"] < df["ma20"], "signal"] = -1 df["strat_ret"] = df["signal"].shift(1) * df["close"].pct_change() print(f"累计收益: {(1 + df['strat_ret']).cumprod().iloc[-1]:.2%}")