AlphaFeed Blog

如何用 Python 计算 ASI 振动升降指标?不用 TA-Lib 还原通达信 ASI/ASIT

分析与指标 · 代码验证于 2026-10-09

如何用 Python 计算 ASI 振动升降指标(不用 TA-Lib)?

一句话回答: ASI(Accumulation Swing Index,振动升降指标)是 Welles Wilder 提出、通达信常用的趋势指标——先用当日与昨日的开高低收算出单日摆动值 SI,再把 SI 累加成 ASI 曲线,用 ASI 与其均线 ASIT 的金叉死叉过滤假突破。用 AlphaFeed 取前复权日线的 OHLC,几行 pandas 就能按通达信口径还原,不需要 TA-Lib。

为什么会有这个问题 / 传统做法的痛点

单看收盘价突破常被「假突破」骗——价格冲一下又缩回去。ASI 的设计初衷就是:把开、高、低、收四个价格的真实摆动强度综合成一个数,再累加成一条平滑趋势线。Wilder 认为 ASI 创新高/新低比收盘价创新高/新低更「可信」,因此常用它来确认趋势、过滤噪声。问题是 TA-Lib 没有现成 ASI 函数,网上公式版本还五花八门(Wilder 原版带「limit move」项,不适合 A 股),于是很多人卡在「到底按哪套算」。本文直接对齐通达信 ASI 口径,和软件显示一致。

分步骤解决(每步配可运行代码)

第 1 步:取前复权日线 OHLC

from alphafeed import AlphaFeed
import pandas as pd
import numpy as np

af = AlphaFeed(api_key="your-api-key")  # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()

df = af.klines.get("600519.SH", period="1d", count=250,
                   adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)

ASI 要用到昨日开盘、昨日收盘、昨日最低,所以前复权与按日期升序排列是前提。

第 2 步:按通达信口径算 SI → 累加成 ASI → 取 ASIT 均线

def asi(df, m=6):
    o, h, l, c = df["open"], df["high"], df["low"], df["close"]
    lc, lo, ll = c.shift(1), o.shift(1), l.shift(1)   # 昨收、昨开、昨低
    aa = (h - lc).abs()
    bb = (l - lc).abs()
    cc = (h - ll).abs()
    dd = (lc - lo).abs()
    # R:取 aa/bb/cc 中最大者对应的分母公式
    r = np.where((aa > bb) & (aa > cc), aa + bb/2 + dd/4,
         np.where((bb > cc) & (bb > aa), bb + aa/2 + dd/4, cc + dd/4))
    r = pd.Series(r, index=df.index).replace(0, np.nan)
    x = (c - lc) + (c - o)/2 + (lc - lo)
    si = (16 * x / r * np.maximum(aa, bb)).fillna(0)
    asi_ = si.cumsum()                 # ASI = SI 累加
    asit = asi_.rolling(m).mean()      # ASIT = ASI 的 M 日均线(默认 6)
    return asi_, asit

df["asi"], df["asit"] = asi(df, 6)
print(df[["trade_date", "asi", "asit"]].tail())

实测(tools/verify_new_2026-10-09.py,SDK 0.1.4):贵州茅台近 250 日 ASI 尾值 ≈ −8059.8、ASIT ≈ −8325.2,区间内 ASI 上穿 ASIT 的「金叉」共 23 次,尾部无 NaN。

第 3 步:检测 ASI 金叉/死叉信号

golden = (df["asi"].shift(1) <= df["asit"].shift(1)) & (df["asi"] > df["asit"])
dead   = (df["asi"].shift(1) >= df["asit"].shift(1)) & (df["asi"] < df["asit"])
print("最近一次金叉:", df.loc[golden, "trade_date"].tail(1).tolist())

ASI 上穿 ASIT 视为偏多信号,下穿为偏空;实盘常再叠加「ASI 创新高确认价格突破」。

参数与字段说明

参数/概念含义备注
adjust="forward"前复权必须,除权缺口会污染 OHLC 摆动
aa/bb/cc/dd高-昨收/低-昨收/高-昨低/昨收-昨开 的绝对值通达信中间变量
R分母,取 aa/bb/cc 最大者对应公式防止除零需 replace(0, nan)
16通达信固定系数Wilder 原版用 50 并除以 limit move
SI单日摆动值累加前的原始值
ASISI.cumsum()从样本首日起累加,是相对值
ASITMA(ASI, M),默认 M=6信号线

关键坑与注意事项

常见问题(FAQ)

Q:ASI 和 OBV、MACD 有什么不同? A:OBV 累加的是「成交量」,ASI 累加的是「价格摆动强度」(只用 OHLC,不含量);MACD 是均线差,不累加。三者都看趋势,但输入信息不同。

Q:为什么我的 ASI 和同花顺数值不一样? A:多半是复权方式或系数口径不同(16 vs 50、是否除 T、M 取值)。先统一为同一复权、同一公式再比。

Q:需要付费吗? A:单只股票日线在免费额度内即可;若要对全市场批量算 ASI 找「ASI 刚金叉」的票,需要 klines.batch + universes(Starter 及以上),详见官网定价页。

小结

ASI 把每天开高低收的真实摆动累加成一条趋势线,比单看收盘价更能过滤假突破。用 AlphaFeed 的前复权 OHLC,按通达信口径(系数 16、不除 limit move)几行就能还原 ASI 与 ASIT,并检测金叉——记住它是累加相对值,只看方向别比绝对大小。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。