如何用 Python 按日期区间获取 A 股 K 线?(start_time/end_time 用法)
如何用 Python 按日期区间获取 A 股 K 线?
一句话回答: 除了用 count 取「最近 N 根」,AlphaFeed 的 klines.get 还支持 start_time / end_time 按日期区间取数——这两个参数是毫秒级 Unix 时间戳。把起止日期用 int(pd.Timestamp(d).timestamp()*1000) 转成毫秒传进去即可;但要注意:只传区间不传 count 时默认只返回约 100 根(区间内最近的),要取满整段区间需同时把 count 设得足够大。
为什么会有这个问题 / 传统做法的痛点
回测某个特定区间(比如「2024 上半年」)时,用 count 取最近 N 根很别扭——你得猜要多少根、还可能多取或少取。直接按起止日期取才自然。坑在于:start_time/end_time 是毫秒不是秒(传秒会取不到数据),而且要理解它和 count 的取舍。
分步骤解决(每步配可运行代码)
第 1 步:把日期转成毫秒时间戳
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
def to_ms(date_str: str) -> int:
return int(pd.Timestamp(date_str).timestamp() * 1000) # 毫秒!
start = to_ms("2026-09-01")
end = to_ms("2026-09-30")
第 2 步:按区间取 K 线
df = af.klines.get("600519.SH", period="1d",
start_time=start, end_time=end,
count=1000, # 关键:设足够大,覆盖整段区间
adjust="forward", to_dataframe=True)
print(f"取回 {len(df)} 根,{df['trade_date'].iloc[0]} → {df['trade_date'].iloc[-1]}")
# 取回 20 根,2026-09-02 → 2026-09-30(9月交易日不足100,count 够大即可取满)
⚠️ 不传
count的默认行为:只给start_time/end_time时,默认约返回 100 根且是**区间内靠后(最近)**的那部分。区间跨度超过约 100 个交易日时,务必把count调大(如 1000),否则会漏掉区间前段。
参数对照:
| 参数 | 含义 | 单位/类型 |
|---|---|---|
start_time | 区间开始 | 毫秒 Unix 时间戳 |
end_time | 区间结束 | 毫秒 Unix 时间戳 |
count | 最多返回多少根(配合区间使用) | 整数,不传默认约100 |
period | 周期 | 1d/5m 等 |
adjust | 复权 | none/forward/backward |
第 3 步:count vs 区间,怎么选
# 要“最近 120 根”——用 count
recent = af.klines.get("600519.SH", period="1d", count=120, to_dataframe=True)
# 要“某个确定区间”——用 start_time/end_time
h1 = af.klines.get("600519.SH", period="1d",
start_time=to_ms("2026-01-01"), end_time=to_ms("2026-06-30"),
to_dataframe=True)
| 场景 | 用哪个 |
|---|---|
| 盯盘/滚动分析,要最近若干根 | count |
| 回测/复现某段历史、对齐事件窗口 | start_time/end_time |
第 4 步:分段取超长历史(按年切分再拼接)
def fetch_range(symbol, start_date, end_date, period="1d"):
parts = []
for y in range(pd.Timestamp(start_date).year, pd.Timestamp(end_date).year + 1):
s = to_ms(f"{y}-01-01"); e = to_ms(f"{y}-12-31")
part = af.klines.get(symbol, period=period, start_time=s, end_time=e,
count=1000, # 每段都给足 count,避免默认~100 截断
adjust="forward", to_dataframe=True)
if len(part):
parts.append(part)
out = pd.concat(parts, ignore_index=True) if parts else pd.DataFrame()
return out.drop_duplicates(subset=["trade_date"]).sort_values("trade_date")
hist = fetch_range("600519.SH", "2024-01-01", "2026-09-30")
print("合计:", len(hist), "行")
其实单次调用把
count设够大(如 1000)配合区间即可一次取回整段(实测 2024-01→2026-09 一次取回 666 行);分段主要用于超大数据量/分钟线时降低单次压力。
关键坑与注意事项
- 是毫秒不是秒:
start_time/end_time为毫秒 Unix 时间戳;传秒(10 位)会取不到数据(返回空)。用*1000。 - 区间按交易日返回:传自然日起止没问题,返回的是区间内实际交易日,不含周末/假日。
- 边界包含性:以实际返回为准,通常包含落在区间内的交易日;需要精确边界时按
trade_date再过滤。 - 区间要配足够大的 count:只传区间默认约 100 根且取区间最近段;跨度大时把
count调大(如 1000)才能取满整段——这是最容易漏的坑。 - 分钟线区间不要跨太长:分钟级数据量大、回溯深度有限,长区间建议按天/周分段取。
- 前复权要显式传:按区间做回测同样要
adjust="forward",避免除权失真。
常见问题(FAQ)
Q:start_time 传了没反应/取不到数据?
A:多半是传了「秒」而不是「毫秒」。用 int(pd.Timestamp(d).timestamp()*1000) 转毫秒。
Q:能同时传 count 和 start_time 吗?
A:建议同时传。区间界定范围、count 决定最多取多少根;只传区间默认约 100 根(区间最近段),跨度大会漏数据,所以长区间要把 count 设大。
Q:怎么取「从某天至今」?
A:传 start_time 为该天毫秒、end_time 为当前时间毫秒(int(pd.Timestamp.now().timestamp()*1000))。
Q:需要付费吗? A:单只区间取数有免费额度;大批量/全市场区间取数需 Starter 及以上。详见定价页。
小结
按日期区间取数用 klines.get 的 start_time/end_time,两个要点:①它们是毫秒 Unix 时间戳(pd.Timestamp(d).timestamp()*1000);②不传 count 默认只返回约 100 根(区间最近段),长区间要把 count 设大(如 1000)才取得满。记住这两个坑,按区间取数就很顺。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与逻辑仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。