教程

K 线数据怎么算技术指标

拿到底层 K 线后,技术指标其实自己就能算——不需要昂贵工具。本文用 ashareapi 免费端点取前复权日线,手写 MA / MACD / RSI / KDJ / BOLL 五个常用指标,纯 Python + pandas,不依赖 TA-Lib。

一、先拿数据(免费端点)

`/v1/kline` 是免费端点(无需 Key)。返回前复权日/周/月线,字段固定:

Python:取日线(默认前复权)
import requests
import pandas as pd

r = requests.get("https://api.ashareapi.com/v1/kline",
                 params={"code": "sh600667", "period": "day", "count": 60},
                 timeout=30)
bars = r.json()["data"]              # list[dict]
df = pd.DataFrame(bars)
print(df[["date", "open", "last", "high", "low", "volume"]].head())
  • 前复权:已按分红送转调整(除权日无跳空)。如需原始价,自己用分红/送转因子还原(本文不展开)
  • `last` 是收盘价,不是实时现价 —— 计算指标用收盘价是标准做法(用 open/high/low 可扩展)
date
交易日
日线=当日;周/月=周期结束日
open / last
开盘 / 收盘
last 是收盘(不是现价)
high / low
最高 / 最低
volume
成交量
单位:手(×100 = 股)
amount
成交额
单位:元
turnover
换手率
%

二、MA(简单移动平均,最基础)

MA(N) = 最近 N 天收盘价的均值。它是趋势的"平滑滤镜",也是其它指标的输入。

Python:MA5 / MA10 / MA20 / MA60
def ma(close, n):
    return close.rolling(n).mean()

df["ma5"]  = ma(df["last"], 5)
df["ma10"] = ma(df["last"], 10)
df["ma20"] = ma(df["last"], 20)
df["ma60"] = ma(df["last"], 60)
print(df[["date", "last", "ma5", "ma20"]].tail())
  • 金叉:MA5 上穿 MA20(短期均线穿过长期 = 短期转强)
  • 死叉:MA5 下穿 MA20(转弱)
  • 多头排列:MA5 > MA10 > MA20(趋势向上);空头排列反之

三、MACD(最常用的趋势 + 动能)

MACD = 快慢 EMA 的差(DIF)再平滑(DEA),用 12/26/9 标准参数。

Python:MACD(12, 26, 9)
def macd(close, fast=12, slow=26, sig=9):
    ema_f = close.ewm(span=fast).mean()
    ema_s = close.ewm(span=slow).mean()
    dif = ema_f - ema_s                     # 快慢线差
    dea = dif.ewm(span=sig).mean()          # DIF 的均线
    hist = (dif - dea) * 2                  # 柱(MACD 常见 ×2)
    return dif, dea, hist

df["dif"], df["dea"], df["macd"] = macd(df["last"])
  • 金叉:DIF 上穿 DEA(动能转正);死叉:下穿(转负)
  • 柱:红柱放大=多头动能增强,绿柱放大=空头动能增强
  • 背离:价格创新高但 MACD 不创新高(顶背离,警示);价格新低但 MACD 不新低(底背离)

四、RSI(超买超卖)

RSI(N) 衡量一段时间内涨跌力量对比,常用于判断超买/超卖。经典参数 14。

Python:RSI(14)
def rsi(close, n=14):
    delta = close.diff()
    gain = delta.clip(lower=0).rolling(n).mean()
    loss = (-delta.clip(upper=0)).rolling(n).mean()
    rs = gain / loss
    return 100 - 100 / (1 + rs)

df["rsi14"] = rsi(df["last"])
  • > 70 通常视为超买(涨多了,警惕回调);< 30 超卖(跌多了,警惕反弹)
  • 背离同样适用:价格新高但 RSI 不新高 = 顶背离信号
  • 不是绝对:强趋势中 RSI 可长期钝化在超买区(不必然回调)

五、KDJ(随机指标,短线常用)

KDJ 用最高/最低/收盘的相对位置,灵敏但易噪。经典参数 9,3,3。

Python:KDJ(9,3,3)
def kdj(high, low, close, n=9):
    low_n = low.rolling(n).min()
    high_n = high.rolling(n).max()
    rsv = (close - low_n) / (high_n - low_n) * 100
    k = rsv.ewm(alpha=1/3).mean()
    d = k.ewm(alpha=1/3).mean()
    j = 3 * k - 2 * d
    return k, d, j

df["k"], df["d"], df["j"] = kdj(df["high"], df["low"], df["last"])
  • K 上穿 D = 金叉(短线转强);下穿 = 死叉
  • > 80 超买 / < 20 超卖,比 RSI 更敏感
  • J 值可超过 0/100(极端),用来判断钝化

六、BOLL(布林带,判断波动区间)

BOLL = 中轨 MA20 ± 2 倍标准差,刻画价格的"正常波动带"。

Python:BOLL(20, 2)
def boll(close, n=20, k=2):
    mid = close.rolling(n).mean()
    std = close.rolling(n).std()
    upper = mid + k * std
    lower = mid - k * std
    return upper, mid, lower

df["boll_up"], df["boll_mid"], df["boll_low"] = boll(df["last"])
  • 缩口(带宽收窄)= 波动将放大(变盘前兆);张口 = 波动加大
  • 价格触及上轨 = 偏强(趋势中可沿轨走);触及下轨 = 偏弱
  • 跌破下轨再收回 = 可能超跌反弹;突破上轨 = 可能加速(但强趋势中会沿轨走,不必然回落)

七、五个指标怎么组合(不是越多越好)

  • 趋势 + 动能:MA(看方向)+ MACD(看动能)—— 最常用组合
  • 超买超卖:RSI / KDJ(二选一即可,都偏短线、易噪)
  • 波动区间:BOLL(给 MA 一个"应该在哪"的参考带)
  • 纪律:指标是辅助确认,不能单独当买卖依据。两个以上指标同向 + 自己逻辑,才更可靠(本文只讲取数与计算,不构成买卖建议)

八、常见误判(重要)

  • ① 复权口径:接口返回前复权 —— 算指标用前复权正确(保持连续性)。但如果要跟"未复权的现价"对账单,要留意
  • ② 指标公式参数可调:MACD(12,26,9) / RSI(14) / KDJ(9,3,3) / BOLL(20,2) 是"常用",不是"唯一"。改参数 = 换一个指标,结论可能不同
  • ③ 技术指标有滞后:都是历史均线/平滑,反映的是过去。强势趋势里指标可钝化,不能机械按金叉/死叉交易

常见问题

这需要付费吗?

不需要。kline 是 5 个免费端点之一(quote / kline / hot / market-overview / changedist),无需 Key 即可调用。

数据是前复权吗?

是,接口固定返回前复权(除权日无跳空)。计算技术指标用前复权是正确的(保证序列连续)。如需原始未复权价,需用分红送转因子自行还原。

为什么不用 TA-Lib?

TA-Lib 功能全但安装麻烦(需编译)。本文用纯 pandas 实现 5 个常用指标,零额外依赖,方便教学与轻量用。若做大规模策略回测,再考虑 TA-Lib 提速。

能拿分钟级 K 线吗?

不能。当前 kline 只提供日 / 周 / 月三种周期,没有分钟级。日内数据在别的端点(如 orderbook 的实时盘口),但无分钟 K 线。

最后更新: 2026-09-29

数据取自 ashareapi /v1/kline 线上真实返回(2026-09-29 实测:前复权日线字段 date/open/last/high/low/volume/amount/turnover);指标实现为标准算法(pandas 版,无 TA-Lib 依赖)。