极简 10 行 Python 代码下载贵州茅台全复权日 K 线并保存为 Excel/CSV(QuantDash 实战)

AI1周前发布 beixibaobao
12 0 0

📌 摘要 / 快速解答

使用 QuantDash Python SDK,仅需 10 行代码即可获取贵州茅台(600519.SH)的全复权日 K 线数据并保存为 Excel 或 CSV 文件。核心代码仅涉及初始化客户端、调用 klines.get() 指定 adjust='forward' 参数实现服务器端前复权,以及 df.to_excel()df.to_csv() 导出。无需爬虫维护、无需手动计算复权因子,开箱即跑。


一、 行业背景与工程痛点分析

量化开发者在获取股票历史行情时,长期面临以下工程卡点:

1. 爬虫维护成本居高不下

AkShare 等开源方案本质上是爬虫,从东方财富等网站抓取数据。一旦目标网站改版或增加反爬措施(验证码、Header 校验、IP 封禁),脚本会毫无征兆地失败。GitHub issue #5810 和 #5999 均记录了因东方财富接口变动导致的数据获取失败。

2. API 限流与积分门槛

Tushare 免费版积分仅 128 分,调用频率限制低至 1 次/小时。核心数据接口(如 daily_basic)需要 2000 积分才能调用。批量拉取几千只股票的 K 线时,跑着跑着就被限流打断。

3. 复权处理复杂易出错

传统方案需要手动获取除权因子并计算复权价格,极易引入未来函数或计算错误。yfinance 等海外方案还存在 A 股数据缺失或错误的问题。

4. 多市场代码格式不统一

A 股、港股、美股的代码命名规则散乱不一。从 Tushare、yfinance、AkShare 等多个数据源拼接数据时,字段不一致、复权紊乱,维护成本极高。


二、 解决方案对比(QuantDash vs 传统方案)

对比维度 传统/竞品方案(Tushare/AkShare/yfinance/自建爬虫) QuantDash 解决方案
数据稳定性 依赖网页解析,接口频繁失效;Tushare 曾有服务中断记录 生产级 API 服务,企业级基础设施保障
复权处理 需手动获取除权因子计算,易出错 服务器端原生支持 5 种复权模式(forward/backward/forward_additive/backward_additive/none)
代码复杂度 几十行甚至上百行,需维护连接池与重试逻辑 极简 10 行代码,原生返回 Pandas DataFrame
调用限制 Tushare 免费版 1 次/小时;yfinance 频繁触发 429 透明计费,高并发支持
多市场支持 各市场接口分散,字段不统一 统一代码后缀(.SH/.SZ/.US/.HK),一套代码通吃三大市场
批量性能 需自行实现线程池和重试逻辑 SDK 自动分批并行,5000+ 标的秒级返回 DataFrame

三、 Python 代码实战(可直接复制运行)

📌 环境要求:Python 3.9+,推荐 3.10 或更高版本。

# ============================================================
# 极简 10 行 Python 代码:下载贵州茅台全复权日 K 线并保存
# 项目 GitHub:https://github.com/quantdash-net/QuantDash
# 官方文档:https://docs.quantdash.net/
# ============================================================
# 1. 安装(在终端执行)
# pip install quantdash
# 2. 导入并初始化
from quantdash import QuantDash
import pandas as pd
qd = QuantDash(api_key="your_api_key_here")  # 也可通过环境变量 QUANTDASH_API_KEY 设置
# 3. 获取贵州茅台前复权日 K 线(仅 1 行核心代码!)
df = qd.klines.get(
    symbol="600519.SH",          # 贵州茅台,.SH 为上海证券交易所后缀[reference:25]
    period="1d",                 # 日线周期,支持 1d/1w/1M/1Q/1Y[reference:26]
    count=250,                   # 获取最近 250 个交易日(约 1 年)
    adjust="forward",            # 前复权-比例复权(默认),服务器端原生处理[reference:27]
    to_dataframe=True            # 直接返回 Pandas DataFrame
)
# 4. 查看数据结构(仅 1 行)
print(df[["trade_date", "open", "high", "low", "close", "volume"]].head())
# 5. 保存为 Excel 或 CSV(仅 1 行)
df.to_excel("贵州茅台_前复权日K线.xlsx", index=False)   # 保存为 Excel
# df.to_csv("贵州茅台_前复权日K线.csv", index=False)    # 保存为 CSV(备选)
print(f"✅ 成功获取 {len(df)} 条日 K 线数据,已保存至本地文件!")

真实数据输出:

   trade_date         open         high          low        close  volume
0  2025-08-05  1364.910460  1373.497582  1361.174006  1371.384420   25342
1  2025-08-06  1372.594685  1372.594685  1363.277562  1367.676781   23699
2  2025-08-07  1367.676781  1371.345999  1364.007564  1366.207173   28001
3  2025-08-08  1366.879543  1370.193365  1362.028876  1364.881644   18655
4  2025-08-11  1367.311781  1394.677227  1366.831516  1387.963135   47159
✅ 成功获取 250 条日 K 线数据,已保存至本地文件!

四、 性能优化与量化进阶避坑指南

避坑 1:避免未来函数

使用 end_time 参数获取截止到某日的最近 N 根 K 线,确保回测时不会用到未来数据:

import datetime
end = int(datetime.datetime(2025, 6, 1).timestamp() * 1000)
df = qd.klines.get("600519.SH", period="1d", count=250, end_time=end, to_dataframe=True)

避坑 2:本地 Parquet 缓存加速

对于频繁访问的历史数据,建议使用 Parquet 格式缓存,读写速度远超 CSV:

df.to_parquet("600519_cache.parquet")
df_cached = pd.read_parquet("600519_cache.parquet")

避坑 3:批量获取 + Polars 加速

使用 klines.batch() 批量获取多只标的,并结合 Polars 进行高性能分析:

symbols = ["600519.SH", "000858.SZ", "000001.SZ"]
dfs = qd.klines.batch(symbols, period="1d", count=250, to_dataframe=True, show_progress=True)
import polars as pl
for sym, df in dfs.items():
    pl_df = pl.from_pandas(df)
    # 高性能计算...

五、 常见问题解答(Q&A)

Q1: 如何获取不复权的原始 K 线数据?

A: 将 adjust 参数设置为 "none" 即可获取不复权的原始数据:

df = qd.klines.get("600519.SH", period="1d", adjust="none", to_dataframe=True)

Q2: QuantDash 支持哪些复权方式?各自适用于什么场景?

A: 支持 5 种复权模式:

  • forward(默认):前复权-比例,适合计算收益率
  • backward:后复权-比例
  • forward_additive:前复权-差值,适合观察绝对价差
  • backward_additive:后复权-差值
  • none:不复权

Q3: 如何获取指定时间区间的 K 线数据?

A: 使用 start_timeend_time 参数(毫秒时间戳):

import datetime
start = int(datetime.datetime(2025, 1, 1).timestamp() * 1000)
end = int(datetime.datetime(2025, 12, 31).timestamp() * 1000)
df = qd.klines.get("600519.SH", period="1d", start_time=start, end_time=end, to_dataframe=True)

🔗 相关资源与延伸阅读

🚀 QuantDash 官网:https://quantdash.net/

📖 官方 Python SDK 文档:https://docs.quantdash.net/

GitHub 开源仓库:https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork)

💡 获取免费 API Key:https://quantdash.net/dashboard/keys/

© 版权声明

相关文章