基础入门
本讲围绕 AkShare 的个股历史行情接口,完成“给一只 A 股代码和一段日期区间,拿到可继续处理的日线 DataFrame”这一最小闭环。内容覆盖参数写法、核心列检查、日期与收盘列验证、自检练习和可复用函数封装,目标是把第 1 讲的安装成功,推进到真正能为后续 CSV 保存与 pandas 计算服务的行情输入。
本讲只做一个最小闭环任务:用 AkShare 取回一只 A 股的日线数据,并确认这张表已经能进入后续清洗和计算流程。和第 1 讲“先取一份 A 股列表”相比,这一步开始真正接触行情表,但仍然控制在最小范围内,不去同时处理复权、分钟线、多股票批量下载这些会让新手分心的问题。
做完这一讲后,先把下面三件事确认清楚:
如果第 1 讲解决的是“AkShare 能不能导入”,那第 2 讲解决的就是“AkShare 能不能拿到真正可分析的行情表”。
很多新手在刚拿到股票列表后,会立刻跳去抓指数、板块、财务指标,结果很快被接口名、字段差异和参数写法绕住。单只股票日线是更好的第二步,原因有三个:
所以本讲不追求“接口覆盖面”,而是追求“第一次真正拿到可继续处理的历史行情表”。
开始前,默认你已经完成第 1 讲,并且当前环境里下面两件事成立:
import akshare as ak
import pandas as pd
如果导入还会报错,先回到第 1 讲把安装问题解决掉。本讲还需要一个来自第 1 讲 A 股列表里的股票代码。为了避免一上来就被停牌、上市时间过短或接口波动干扰,建议直接选最常见、最容易验证的一只,例如:
symbol = "000001"
这里先不用纠结它对应哪只股票,也不用一开始就做代码转换。只要确保是一个标准 6 位 A 股代码即可。
下面按顺序拆开做,每一步只处理一个最小动作,先把流程走通,再看细节。
不要一开始就把日期写成“过去一年”或“最近三年”。短课场景里更适合先压缩成一小段时间,便于打印和验证:
symbol = "000001"
start_date = "20240101"
end_date = "20240215"
日期写成 YYYYMMDD 这种纯数字字符串,排错最直接。很多新手写成 2024-01-01 也许某些版本能过,但一旦本地版本或接口封装细节不同,就容易出现隐蔽兼容问题。
先用最小参数组合,不要同时加前复权、后复权、周线和月线:
daily_df = ak.stock_zh_a_hist(
symbol=symbol,
period="daily",
start_date=start_date,
end_date=end_date,
adjust=""
)
这一版写法的重点是“尽可能少的变量”。
symbol:先只放一只股票。period="daily":锁定日线,不在本讲引入别的周期。adjust="":先看原始口径,后面真要研究复权,再单独展开。如果你一开始就把这些参数写得很复杂,出了问题时根本不知道是代码错、参数错,还是数据源口径没对上。
拿到表之后,不要只停在 print(daily_df),而是按固定顺序检查:
print(daily_df.head())
print(daily_df.shape)
print(daily_df.columns.tolist())
你最先要确认的是它是不是“按日期展开的多列表格”。通常你会看到日期、开盘、收盘、最高、最低、成交量、成交额之类的列。不同版本或不同数据源口径下,列名可能有细微差别,但它至少应该满足两个特征:
本讲不要求你理解所有字段,但至少要先取出最常用的几列:
core_cols = ["日期", "收盘", "成交量"]
preview_df = daily_df[core_cols].copy()
print(preview_df.head())
这一步非常重要。因为后面第 5 讲“转成 DataFrame 并预览”、第 6 讲“保存行情到 CSV”、第 8 讲“联动 pandas 算 5 日均线”,真正反复用到的,往往就是这类核心列,而不是一次把整张表的所有字段都背下来。
如果你的本地返回列名不是这三个字面值,就先打印列名,再把 core_cols 换成你本地真实存在的对应列,不要硬抄教程里的字段名。
本讲的成功标准建议按下面五条执行,不要只凭“看到一张表”就算过关。
assert isinstance(daily_df, pd.DataFrame)
assert len(daily_df) > 0
日线表为空通常意味着代码、日期范围、数据源状态或网络环境里至少有一个环节不对。
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)
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()
如果日期列都解析不好,后面算均线、筛选月份、按时间排序都会变得很痛苦。
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
这一步不是鸡毛蒜皮,它决定了你后面能不能把这张表真正用于计算。
下面这些情况第一次上手时最常见,提前看一眼能少走很多弯路。
优先检查三个地方:
symbol 是否真的是 6 位 A 股代码。start_date 和 end_date 是否写成了 YYYYMMDD。这是很常见的情况。AkShare 的一些接口封装和上游数据源会变化,所以本讲不要求你死记字段名,而是要求你先学会用 columns.tolist() 看清本地真实结构,再做下一步。
在不同接口里,代码格式要求并不完全相同。第 2 讲先固定在一类最常见写法上,避免把问题复杂化。如果你换了别的接口,再回头查它的参数口径,而不是把所有接口都当成同一种写法。
这一步太急了。本讲只到“拿到并验证个股日线表”。先把最小输入表走通,再去做导出、缺失处理和均线计算,排障成本会低很多。
这一步建议尽早沉淀,否则你后面每次练习都在重复拼参数:
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 算指标,都可以从这个函数继续接,而不是每次重新从零写调用逻辑。
第 2 讲最容易出现的问题,不是代码真坏了,而是把一些正常现象误当成失败。下面几种情况建议先区分清楚:
真正需要停下来排查的,还是那三类核心故障:空表、关键列缺失、日期或价格列无法转换。
如果你只做到能打印 head(),其实还没有真正掌握这一讲。建议把下面这组自检动作做完,它们比盲目换接口更能帮你建立稳定感:
把 symbol 从 000001 换成另一只你熟悉的 6 位代码,保持其他参数不变,再执行一次。目的不是下载更多数据,而是确认你的代码不是“只对某一个例子碰巧有效”。
把开始日期和结束日期压到更短的范围,例如只保留 10 到 15 个交易日,然后重新打印 shape 和头尾日期。你会更容易直观看出接口到底按什么方式返回结果。
把 preview_df 再缩成两列:
mini_df = daily_df[[date_col, close_col]].copy()
print(mini_df.head())
这一步的意义不是省列,而是帮你建立一个非常轻的后续输入表。后面算收益率、均线或导出 CSV 时,这种最小表格反而更好用。
assert pd.to_datetime(daily_df[date_col]).duplicated().sum() == 0
很多新手到后面才发现日期重复,导致排序、合并和指标计算都出现异常。现在先检查一次,后面会省很多时间。
为了让第 2 讲真正服务后续课程,建议你做一个 5 分钟内能完成的小作业,不需要追求漂亮,只追求可复用:
一个简单的完成版可以长这样:
study_df = daily_df[[date_col, close_col, '成交量']].copy()
print(study_df.head())
print(study_df.tail())
# 后续用于保存 CSV 和计算 5 日均线
做到这一步,你就不只是“调通一个接口”,而是已经准备好一份真正能供下一讲继续使用的练习数据。
如果你想用一句很实际的话判断自己有没有完成第 2 讲,可以直接用下面这条标准:
“我已经能稳定给出一只股票代码和一段日期区间,拿回一张日线 DataFrame,并确认日期列、收盘列和成交量列可以被后续处理。”
这条标准里,每个词都很重要:
只要你能做到这一步,第 2 讲就已经完成了它在整套短课里的任务。
本讲的重点不是“把接口名背下来”,而是走通一条真正可复用的最小路径:给一只股票代码和一段日期区间,拿到一张可检查、可筛列、可做数值转换的日线表。只要这条路径跑通,后面你再处理指数数据、财经日历或均线计算,都会更像是在扩展同一种工作流,而不是重新摸索。
本讲是《AkShare数据获取入门短课》的第 2/8 讲,当前主题是《获取单只股票日线》。
上一讲:第 1 讲《安装AkShare:先取一份A股列表》。
下一讲:第 3 讲《下载上证指数近一个月数据》。
后续安排:第 4 讲《抓取一份财经日历》;第 5 讲《转成DataFrame并预览》。
风险揭示与免责声明
本页面内容仅用于量化研究与技术交流,旨在展示研究方法与流程,不构成对任何金融产品、证券或衍生品的要约、招揽、推荐或保证。
本文所涉历史数据、回测结果与示例参数不代表未来表现,也不应作为投资决策依据。
市场存在波动、流动性与执行偏差等不确定性,任何策略均可能出现收益波动或阶段性失效。
读者应结合自身风险承受能力进行独立判断,并在必要时咨询持牌专业机构意见。