深圳融克迪特科技有限公司 Logo,金融科技,量化交易,软件开发

深圳融克迪特科技有限公司

RONG CREDIT TECHNOLOGY CO., LTD.

基础入门

【AkShare 系列 第2讲】获取单只股票日线

本讲围绕 AkShare 的个股历史行情接口,完成“给一只 A 股代码和一段日期区间,拿到可继续处理的日线 DataFrame”这一最小闭环。内容覆盖参数写法、核心列检查、日期与收盘列验证、自检练习和可复用函数封装,目标是把第 1 讲的安装成功,推进到真正能为后续 CSV 保存与 pandas 计算服务的行情输入。

2026-04-22 智铨研究 阅读时长 11 分钟

目录

  1. 本节目标
  2. 为什么第 2 讲先抓单只股票日线
  3. 沿用第 1 讲结果,不重新开题
  4. 四步拿到第一张个股日线表
  5. 先把目标参数写死
  6. 调用股票历史行情接口
  7. 先看前几行,再看列名和形状
  8. 抽出最关键的三列做一次最小检查
  9. 确认这次调用真的能进入后续课程
  10. 返回对象确实是 DataFrame
  11. 表格不是空的
  12. 至少有日期和收盘价相关字段
  13. 日期列能被正常解析
  14. 收盘列能转成数值
  15. 第一次抓个股日线时最容易卡的点
  16. 返回空表
  17. 字段名和示例不一致
  18. 想当然地把代码写成带交易所前缀
  19. 拿到表后直接开始算指标
  20. 把日线下载动作封装成一个小函数
  21. 哪些现象先不要误判成失败
  22. 把“会运行”升级成“会检查”
  23. 换一只股票再跑一次
  24. 把日期区间缩短到两周
  25. 只保留日期和收盘价
  26. 检查是否有重复日期
  27. 把本讲结果沉淀成一份可复用输入表
  28. 把这一讲过没过说清楚
  29. 本讲小结
  30. 系列衔接
  31. 风险揭示与免责声明

1. 本节目标

本讲只做一个最小闭环任务:用 AkShare 取回一只 A 股的日线数据,并确认这张表已经能进入后续清洗和计算流程。和第 1 讲“先取一份 A 股列表”相比,这一步开始真正接触行情表,但仍然控制在最小范围内,不去同时处理复权、分钟线、多股票批量下载这些会让新手分心的问题。

做完这一讲后,先把下面三件事确认清楚:

  1. 单只股票日线接口至少需要哪些核心参数。
  2. 返回的数据表里哪些列最值得先看。
  3. 拿到表后,怎样快速判断这次调用是真的成功,而不是“表能打印,但结构根本没法继续用”。

如果第 1 讲解决的是“AkShare 能不能导入”,那第 2 讲解决的就是“AkShare 能不能拿到真正可分析的行情表”。

2. 为什么第 2 讲先抓单只股票日线

很多新手在刚拿到股票列表后,会立刻跳去抓指数、板块、财务指标,结果很快被接口名、字段差异和参数写法绕住。单只股票日线是更好的第二步,原因有三个:

  1. 输入最简单,只要一个股票代码和一段日期区间。
  2. 输出最直观,通常就是按交易日展开的行情表,方便肉眼检查。
  3. 后面无论是保存 CSV、补缺失值,还是联动 pandas 算均线,几乎都以这类表格为起点。

所以本讲不追求“接口覆盖面”,而是追求“第一次真正拿到可继续处理的历史行情表”。

3. 沿用第 1 讲结果,不重新开题

开始前,默认你已经完成第 1 讲,并且当前环境里下面两件事成立:

import akshare as ak
import pandas as pd

如果导入还会报错,先回到第 1 讲把安装问题解决掉。本讲还需要一个来自第 1 讲 A 股列表里的股票代码。为了避免一上来就被停牌、上市时间过短或接口波动干扰,建议直接选最常见、最容易验证的一只,例如:

symbol = "000001"

这里先不用纠结它对应哪只股票,也不用一开始就做代码转换。只要确保是一个标准 6 位 A 股代码即可。

4. 四步拿到第一张个股日线表

下面按顺序拆开做,每一步只处理一个最小动作,先把流程走通,再看细节。

5. 先把目标参数写死

不要一开始就把日期写成“过去一年”或“最近三年”。短课场景里更适合先压缩成一小段时间,便于打印和验证:

symbol = "000001"
start_date = "20240101"
end_date = "20240215"

日期写成 YYYYMMDD 这种纯数字字符串,排错最直接。很多新手写成 2024-01-01 也许某些版本能过,但一旦本地版本或接口封装细节不同,就容易出现隐蔽兼容问题。

6. 调用股票历史行情接口

先用最小参数组合,不要同时加前复权、后复权、周线和月线:

daily_df = ak.stock_zh_a_hist(
    symbol=symbol,
    period="daily",
    start_date=start_date,
    end_date=end_date,
    adjust=""
)

这一版写法的重点是“尽可能少的变量”。

如果你一开始就把这些参数写得很复杂,出了问题时根本不知道是代码错、参数错,还是数据源口径没对上。

7. 先看前几行,再看列名和形状

拿到表之后,不要只停在 print(daily_df),而是按固定顺序检查:

print(daily_df.head())
print(daily_df.shape)
print(daily_df.columns.tolist())

你最先要确认的是它是不是“按日期展开的多列表格”。通常你会看到日期、开盘、收盘、最高、最低、成交量、成交额之类的列。不同版本或不同数据源口径下,列名可能有细微差别,但它至少应该满足两个特征:

  1. 每一行代表一个交易日。
  2. 价格和成交相关列能被后续 pandas 直接读取和计算。

8. 抽出最关键的三列做一次最小检查

本讲不要求你理解所有字段,但至少要先取出最常用的几列:

core_cols = ["日期", "收盘", "成交量"]
preview_df = daily_df[core_cols].copy()
print(preview_df.head())

这一步非常重要。因为后面第 5 讲“转成 DataFrame 并预览”、第 6 讲“保存行情到 CSV”、第 8 讲“联动 pandas 算 5 日均线”,真正反复用到的,往往就是这类核心列,而不是一次把整张表的所有字段都背下来。

如果你的本地返回列名不是这三个字面值,就先打印列名,再把 core_cols 换成你本地真实存在的对应列,不要硬抄教程里的字段名。

9. 确认这次调用真的能进入后续课程

本讲的成功标准建议按下面五条执行,不要只凭“看到一张表”就算过关。

10. 返回对象确实是 DataFrame

assert isinstance(daily_df, pd.DataFrame)

11. 表格不是空的

assert len(daily_df) > 0

日线表为空通常意味着代码、日期范围、数据源状态或网络环境里至少有一个环节不对。

12. 至少有日期和收盘价相关字段

columns = [str(col) for col in daily_df.columns]
assert any("日期" in col for col in columns)
assert any("收盘" in col for col in columns)

13. 日期列能被正常解析

date_col = next(col for col in daily_df.columns if "日期" in str(col))
parsed_date = pd.to_datetime(daily_df[date_col])
assert parsed_date.notna().all()

如果日期列都解析不好,后面算均线、筛选月份、按时间排序都会变得很痛苦。

14. 收盘列能转成数值

close_col = next(col for col in daily_df.columns if "收盘" in str(col))
close_series = pd.to_numeric(daily_df[close_col], errors="coerce")
assert close_series.notna().sum() > 0

这一步不是鸡毛蒜皮,它决定了你后面能不能把这张表真正用于计算。

15. 第一次抓个股日线时最容易卡的点

下面这些情况第一次上手时最常见,提前看一眼能少走很多弯路。

16. 返回空表

优先检查三个地方:

  1. symbol 是否真的是 6 位 A 股代码。
  2. start_dateend_date 是否写成了 YYYYMMDD
  3. 日期区间是否合理,不能开始日期晚于结束日期。

17. 字段名和示例不一致

这是很常见的情况。AkShare 的一些接口封装和上游数据源会变化,所以本讲不要求你死记字段名,而是要求你先学会用 columns.tolist() 看清本地真实结构,再做下一步。

18. 想当然地把代码写成带交易所前缀

在不同接口里,代码格式要求并不完全相同。第 2 讲先固定在一类最常见写法上,避免把问题复杂化。如果你换了别的接口,再回头查它的参数口径,而不是把所有接口都当成同一种写法。

19. 拿到表后直接开始算指标

这一步太急了。本讲只到“拿到并验证个股日线表”。先把最小输入表走通,再去做导出、缺失处理和均线计算,排障成本会低很多。

20. 把日线下载动作封装成一个小函数

这一步建议尽早沉淀,否则你后面每次练习都在重复拼参数:

import akshare as ak
import pandas as pd

def load_daily_history(symbol: str, start_date: str, end_date: str) -> pd.DataFrame:
    df = ak.stock_zh_a_hist(
        symbol=symbol,
        period="daily",
        start_date=start_date,
        end_date=end_date,
        adjust=""
    )
    if df.empty:
        raise ValueError(f"{symbol} 在指定区间没有取到日线数据")
    return df

daily_df = load_daily_history("000001", "20240101", "20240215")
print(daily_df.head())

后面不管你是要保存 CSV,还是要联动 pandas 算指标,都可以从这个函数继续接,而不是每次重新从零写调用逻辑。

21. 哪些现象先不要误判成失败

第 2 讲最容易出现的问题,不是代码真坏了,而是把一些正常现象误当成失败。下面几种情况建议先区分清楚:

  1. 返回行数比你预期少。如果你选的日期区间里本来就有节假日、周末或停牌日,行数少并不一定有问题。先看日期分布,再判断是否异常。
  2. 收盘列看起来不是整数。价格列出现很多小数是正常的,不需要为了“看起来整齐”先做四舍五入。入门阶段更重要的是保持原始口径。
  3. 列名里有你暂时用不到的字段。这不算问题。短课里真正要练的是“先抽核心列”,而不是把整张表一次性解释完。
  4. 第一行不是你熟悉的最近交易日。很多接口默认按时间升序返回,第一行可能是最早日期。只要排序逻辑一致,就不影响后续处理。

真正需要停下来排查的,还是那三类核心故障:空表、关键列缺失、日期或价格列无法转换。

22. 把“会运行”升级成“会检查”

如果你只做到能打印 head(),其实还没有真正掌握这一讲。建议把下面这组自检动作做完,它们比盲目换接口更能帮你建立稳定感:

23. 换一只股票再跑一次

symbol000001 换成另一只你熟悉的 6 位代码,保持其他参数不变,再执行一次。目的不是下载更多数据,而是确认你的代码不是“只对某一个例子碰巧有效”。

24. 把日期区间缩短到两周

把开始日期和结束日期压到更短的范围,例如只保留 10 到 15 个交易日,然后重新打印 shape 和头尾日期。你会更容易直观看出接口到底按什么方式返回结果。

25. 只保留日期和收盘价

preview_df 再缩成两列:

mini_df = daily_df[[date_col, close_col]].copy()
print(mini_df.head())

这一步的意义不是省列,而是帮你建立一个非常轻的后续输入表。后面算收益率、均线或导出 CSV 时,这种最小表格反而更好用。

26. 检查是否有重复日期

assert pd.to_datetime(daily_df[date_col]).duplicated().sum() == 0

很多新手到后面才发现日期重复,导致排序、合并和指标计算都出现异常。现在先检查一次,后面会省很多时间。

27. 把本讲结果沉淀成一份可复用输入表

为了让第 2 讲真正服务后续课程,建议你做一个 5 分钟内能完成的小作业,不需要追求漂亮,只追求可复用:

  1. 选定一只你后面愿意继续使用的股票代码。
  2. 下载一个月左右的日线数据。
  3. 只保留日期、收盘、成交量三列。
  4. 打印前 5 行和最后 5 行。
  5. 在注释里写一句话说明:这张表后面准备拿来做什么。

一个简单的完成版可以长这样:

study_df = daily_df[[date_col, close_col, '成交量']].copy()
print(study_df.head())
print(study_df.tail())
# 后续用于保存 CSV 和计算 5 日均线

做到这一步,你就不只是“调通一个接口”,而是已经准备好一份真正能供下一讲继续使用的练习数据。

28. 把这一讲过没过说清楚

如果你想用一句很实际的话判断自己有没有完成第 2 讲,可以直接用下面这条标准:

“我已经能稳定给出一只股票代码和一段日期区间,拿回一张日线 DataFrame,并确认日期列、收盘列和成交量列可以被后续处理。”

这条标准里,每个词都很重要:

  1. 稳定,意味着不是只在一个例子上偶然跑通。
  2. 日线 DataFrame,意味着你拿到的不是截图、不是字符串,而是一张真正能继续操作的表。
  3. 后续处理,意味着你已经开始为保存、预览和计算做准备,而不是停在“打印一下”。

只要你能做到这一步,第 2 讲就已经完成了它在整套短课里的任务。

29. 本讲小结

本讲的重点不是“把接口名背下来”,而是走通一条真正可复用的最小路径:给一只股票代码和一段日期区间,拿到一张可检查、可筛列、可做数值转换的日线表。只要这条路径跑通,后面你再处理指数数据、财经日历或均线计算,都会更像是在扩展同一种工作流,而不是重新摸索。

30. 系列衔接

本讲是《AkShare数据获取入门短课》的第 2/8 讲,当前主题是《获取单只股票日线》。

上一讲:第 1 讲《安装AkShare:先取一份A股列表》。

下一讲:第 3 讲《下载上证指数近一个月数据》。

后续安排:第 4 讲《抓取一份财经日历》;第 5 讲《转成DataFrame并预览》。

31. 风险揭示与免责声明

风险揭示与免责声明

本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。

本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。

市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。

读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。