Python 批量获取 A 股全市场 K 线数据并计算技术指标(附完整代码)
做量化研究,第一步就是拿到数据。这篇文章手把手教你用 Python 批量获取 A 股全市场 5000+ 只股票的历史 K 线,并计算常用技术指标(均线、MACD、RSI、布林带等),代码可以直接跑。
一、为什么需要批量获取全市场 K 线?
做量化分析,只看一两只股票是远远不够的。常见场景包括:
- 全市场选股:计算所有股票的技术指标,筛选符合条件的标的
- 因子计算:基于全市场数据构建因子库
- 行业对比:批量拉取行业内所有股票做横截面分析
- 策略回测:对全市场跑策略,评估收益分布
这就要求数据源必须满足两个条件:
- 支持批量获取,一次拉取多只股票
- 速度要快,5000+ 只股票不能跑半小时
二、环境准备
安装依赖
bash
pip install "tickflow[all]" --upgrade
tickflow[all] 包含 pandas 和进度条支持,适合做数据分析。
TickFlow 官方文档:docs.tickflow.org
三、获取单只股票 K 线
先从最简单的开始。
免费获取日 K 线(无需注册)
python
from tickflow import TickFlow
tf = TickFlow.free()
df = tf.klines.get("600000.SH", period="1d", count=10000, as_dataframe=True)
print(f"获取到 {len(df)} 根 K 线")
print(df.tail())
输出示例:
text
获取到 6400 根 K 线
symbol name timestamp trade_date open high low close volume amount
6395 600000.SH 浦发银行 1775145600000 2026-04-03 10.25 10.25 10.08 10.12 411518 417211984.0
6396 600000.SH 浦发银行 1775491200000 2026-04-07 10.12 10.17 9.95 9.98 378826 380103392.0
...
TickFlow 的免费服务支持日 K(1d)、周 K(1w)、月 K(1M)、季 K(1Q)、年 K(1Y),单次最多获取 10000 根,无需注册和 API key。
获取分钟 K 线(需注册)
python
from tickflow import TickFlow
tf = TickFlow(api_key="your-api-key")
df = tf.klines.get("600000.SH", period="5m", count=100, as_dataframe=True)
print(df.tail())
分钟级 K 线支持 1m、5m、15m、30m、60m,需要在 tickflow.org 注册获取 API key。
四、批量获取全市场 K 线
方式一:指定标的列表
python
from tickflow import TickFlow
tf = TickFlow.free()
symbols = ["600000.SH", "000001.SZ", "600519.SH", "000858.SZ", "601318.SH"]
dfs = tf.klines.batch(symbols, period="1d", count=200, as_dataframe=True, show_progress=True)
print(f"成功获取 {len(dfs)} 只股票的数据")
for symbol, df in dfs.items():
print(f"{symbol}: {len(df)} 根 K 线, 最新收盘价 {df['close'].iloc[-1]}")
方式二:获取全市场标的再批量拉取
python
from tickflow import TickFlow
tf = TickFlow(api_key="your-api-key")
# 获取 A 股全部标的代码
universe = tf.universes.get("CN_Equity_A")
symbols = universe["symbols"]
print(f"A 股共 {len(symbols)} 只标的")
# 批量获取全市场日 K 线
dfs = tf.klines.batch(
symbols,
period="1d",
count=200,
as_dataframe=True,
show_progress=True,
max_workers=5
)
print(f"成功获取 {len(dfs)} 只股票的数据")
实测:全市场 5000+ 只股票的最近 200 根日 K 线,1-2 分钟即可下载完成。
五、计算常用技术指标
拿到 K 线数据后,可以直接用 pandas 计算各种技术指标。
1. 均线(MA)
python
df = tf.klines.get("600519.SH", period="1d", count=200, as_dataframe=True)
df["ma5"] = df["close"].rolling(5).mean()
df["ma10"] = df["close"].rolling(10).mean()
df["ma20"] = df["close"].rolling(20).mean()
df["ma60"] = df["close"].rolling(60).mean()
print(df[["trade_date", "close", "ma5", "ma10", "ma20", "ma60"]].tail(10))
2. MACD
python
def calc_macd(df, fast=12, slow=26, signal=9):
exp_fast = df["close"].ewm(span=fast, adjust=False).mean()
exp_slow = df["close"].ewm(span=slow, adjust=False).mean()
df["dif"] = exp_fast - exp_slow
df["dea"] = df["dif"].ewm(span=signal, adjust=False).mean()
df["macd"] = (df["dif"] - df["dea"]) * 2
return df
df = calc_macd(df)
print(df[["trade_date", "close", "dif", "dea", "macd"]].tail(10))
3. RSI(相对强弱指标)
python
def calc_rsi(df, period=14):
delta = df["close"].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(period).mean()
avg_loss = loss.rolling(period).mean()
rs = avg_gain / avg_loss
df[f"rsi_{period}"] = 100 - (100 / (1 + rs))
return df
df = calc_rsi(df, 6)
df = calc_rsi(df, 14)
print(df[["trade_date", "close", "rsi_6", "rsi_14"]].tail(10))
4. 布林带(Bollinger Bands)
python
def calc_bollinger(df, period=20, std_dev=2):
df["boll_mid"] = df["close"].rolling(period).mean()
df["boll_std"] = df["close"].rolling(period).std()
df["boll_upper"] = df["boll_mid"] + std_dev * df["boll_std"]
df["boll_lower"] = df["boll_mid"] - std_dev * df["boll_std"]
return df
df = calc_bollinger(df)
print(df[["trade_date", "close", "boll_upper", "boll_mid", "boll_lower"]].tail(10))
5. VWAP(成交量加权平均价)
python
tf_paid = TickFlow(api_key="your-api-key")
df_5m = tf_paid.klines.intraday("600000.SH", period="5m", as_dataframe=True)
df_5m["vwap"] = (df_5m["amount"] / df_5m["volume"]).round(2)
print(df_5m[["trade_time", "close", "vwap"]].tail())
六、全市场批量计算技术指标
将数据获取和指标计算串起来,对全市场做分析:
python
import pandas as pd
from tickflow import TickFlow
tf = TickFlow.free()
# 选取部分标的演示(实际可用全市场)
symbols = ["600000.SH", "000001.SZ", "600519.SH", "000858.SZ", "601318.SH"]
dfs = tf.klines.batch(symbols, period="1d", count=200, as_dataframe=True, show_progress=True)
results = []
for symbol, df in dfs.items():
if len(df) < 60:
continue
df["ma5"] = df["close"].rolling(5).mean()
df["ma20"] = df["close"].rolling(20).mean()
# MACD
exp12 = df["close"].ewm(span=12, adjust=False).mean()
exp26 = df["close"].ewm(span=26, adjust=False).mean()
df["dif"] = exp12 - exp26
df["dea"] = df["dif"].ewm(span=9, adjust=False).mean()
# RSI
delta = df["close"].diff()
gain = delta.where(delta > 0, 0).rolling(14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(14).mean()
df["rsi_14"] = 100 - (100 / (1 + gain / loss))
latest = df.iloc[-1]
results.append({
"symbol": symbol,
"close": latest["close"],
"ma5": round(latest["ma5"], 2),
"ma20": round(latest["ma20"], 2),
"ma5_above_ma20": latest["ma5"] > latest["ma20"],
"dif": round(latest["dif"], 4),
"dea": round(latest["dea"], 4),
"macd_golden": latest["dif"] > latest["dea"],
"rsi_14": round(latest["rsi_14"], 2),
})
result_df = pd.DataFrame(results)
print(result_df.to_string(index=False))
输出类似:
text
symbol close ma5 ma20 ma5_above_ma20 dif dea macd_golden rsi_14
600000.SH 9.89 9.93 9.85 True 0.0312 0.0280 True 52.31
000001.SZ 10.91 10.88 10.75 True 0.0521 0.0410 True 55.20
600519.SH 1580.0 1575.2 1560.8 True 8.1200 6.3400 True 58.90
...
七、筛选信号股票
基于计算结果,筛选出满足特定条件的股票:
python
# 均线多头 + MACD 金叉 + RSI 未超买
strong = result_df[
(result_df["ma5_above_ma20"] == True) &
(result_df["macd_golden"] == True) &
(result_df["rsi_14"] < 70)
]
print(f"符合条件的股票: {len(strong)} 只")
print(strong[["symbol", "close", "rsi_14"]].to_string(index=False))
八、复权方式选择
做技术指标计算时,复权方式很重要。TickFlow 支持多种复权:
python
# 比例前复权(默认,适合量化回测和收益率计算)
df_forward = tf.klines.get("600000.SH", adjust="forward", as_dataframe=True)
# 差值前复权(与东方财富、同花顺等软件价格一致)
df_additive = tf.klines.get("600000.SH", adjust="forward_additive", as_dataframe=True)
# 不复权(原始价格)
df_none = tf.klines.get("600000.SH", adjust="none", as_dataframe=True)
# 后复权(长期收益对比)
df_backward = tf.klines.get("600000.SH", adjust="backward", as_dataframe=True)
| 复权方式 | 参数值 | 适用场景 |
|---|---|---|
| 比例前复权 | forward |
收益率计算、量化回测 |
| 差值前复权 | forward_additive |
与东方财富/同花顺价格对齐 |
| 不复权 | none |
原始价格 |
| 比例后复权 | backward |
长期收益对比 |
九、按时间范围获取数据
python
import datetime
from tickflow import TickFlow
tf = TickFlow(api_key="your-api-key")
start = int(datetime.datetime(2024, 1, 1).timestamp() * 1000)
end = int(datetime.datetime(2024, 12, 31).timestamp() * 1000)
df = tf.klines.get(
"600000.SH",
period="1d",
start_time=start,
end_time=end,
count=10000,
as_dataframe=True,
)
print(f"2024 年共 {len(df)} 个交易日")
print(df.tail())
十、异步方式提升性能
如果需要更高性能,可以使用异步客户端:
python
import asyncio
from tickflow import AsyncTickFlow
async def main():
async with AsyncTickFlow(api_key="your-api-key") as tf:
symbols = ["600000.SH", "000001.SZ", "600519.SH"]
dfs = await tf.klines.batch(
symbols,
period="1d",
count=200,
as_dataframe=True,
show_progress=True,
max_concurrency=10,
)
for symbol, df in dfs.items():
df["ma20"] = df["close"].rolling(20).mean()
latest = df.iloc[-1]
status = "站上" if latest["close"] > latest["ma20"] else "跌破"
print(f"{symbol}: {latest['close']:.2f} ({status} MA20: {latest['ma20']:.2f})")
asyncio.run(main())
十一、总结
本文介绍了用 Python 批量获取 A 股全市场 K 线数据并计算技术指标的完整流程:
- 安装 TickFlow SDK(
pip install "tickflow[all]") - 获取单只或批量股票的日 K、分钟 K 数据
- 计算均线、MACD、RSI、布林带等技术指标
- 全市场扫描并筛选信号股票
TickFlow 的核心优势在于:
- 免费层即可获取全量历史日 K,无需注册
- 批量获取 5000+ 只股票仅需 1-2 分钟
- 支持多种复权方式,与主流行情软件对齐
- API 设计统一,代码简洁
相关链接
- 官网:tickflow.org
- 文档:docs.tickflow.org
- Github:github.com/tickflow-or...
数据到手,技术指标就是几行代码的事。真正的量化,从拿到稳定数据开始。