GitPedia

Ta cn

中国版技术指标

From wukan1986·Updated June 17, 2026·View on GitHub·

1. 部分技术指标与国内不同。但大部分中国股民都是参考国内技术指标进行交易。需要实现中国版指标 2. `TA-Lib`只支持单支序列,要计算多支股票需循环,耗时久。 The project is written primarily in Python, distributed under the MIT License license, first published in 2022. Key topics include: alpha101, alpha191, bottleneck, kdj, macd.

ta_cn 中国版技术指标

!!! 注意:如要在polars中使用技术指标,请使用polars_ta

项目背景

初学量化,技术指标一般使用TA-Lib,但存在以下问题

  1. 部分技术指标与国内不同。但大部分中国股民都是参考国内技术指标进行交易。需要实现中国版指标
  2. TA-Lib只支持单支序列,要计算多支股票需循环,耗时久。

在实现遗传算法挖因子时,意识到如果能将常用的操作都转成算子,将大大简化策略的研究,
特别是将+-*/等中缀操作符转成ADD()SUB()MUL()DIV()前缀函数,可直接输到遗传算法工具中

所以开始参考Alpha101和各券商金融工程研报,试着实现一些算子,但后期实现中发现一些问题

  1. 每家金工的研报指标命名上都有区别,难以统一
  2. 指标太多,实现工作太大

直到看到了MyTT这个项目才意识到,指标命名参考股票软件的公式才是最方便直接的,可以直接到各股软中复制公式。遇到性能问题再针对性转换即可。

本人为何不直接用MyTT,而是重复造轮子呢?

  1. 大部分公式只支持单条数据,遇到几千支股票的DataFrame,循环太慢
  2. TA-Lib与国内指标不同,区别在哪,没有对比。错过了很好的教学机会
  3. 为了行数短牺牲了可读性
  4. 部分函数直接复制于股票软件,代码没有优化,有重复计算

再次大迭代,仿WorldQuant

  1. 2022年9月初,知道WorldQuant Websim重新开放为WorldQuant BRAIN后,开始研究国外的平台
  2. WQ公式更加科学。例如:
    1. WQ时序有ts_前缀
    2. WQ有横截面函数和分组函数,通达信没有
    3. 通达信将大量不相关的指标都归类为引用函数
    4. WQ公式为Alpha因子而设计,有大量的权重处理等函数

目标

  1. 优先实现WorldQuant公式,然后实现通达信公式
  2. 通过在通达信中导入WQ公式并别名,来实现通达信公式覆盖
  3. 支持二维矩阵计算
  4. 支持长表和宽表,支持NaN跳过
  5. 最终实现WQ的本地版

实现方案优先级

  1. bottleneck。支持二维数据,优先使用
  2. TA-Lib。封装了常用函数,次要选择
  3. numba。速度受影响,最后才用它

安装

  1. 只想使用二维矩阵TA-Lib,只需安装基础版即可
commandline
pip install ta_cn -i https://mirrors.aliyun.com/pypi/simple --upgrade
  1. 使用中国版指标加速
commandline
pip install ta_cn[cn] -i https://mirrors.aliyun.com/pypi/simple --upgrade
  1. 开发人员安装。开发迭代很快,只有版本稳定才会发布到PyPI,需要时效更高的安装方法
    1. 从github下载zip文件
    2. 解压zip, 进入解压后目录,输入以下命令
commandline
pip install .[cn] -i https://mirrors.aliyun.com/pypi/simple --upgrade
  1. 库维护者安装。可修改本地文件
commandline
pip install -e .

常见使用方法

  1. 转发原生talib,输入一维向量
    • 优点: 本库提供了跳过空值的功能
    • 缺点: 不要在大量循环中调用,因为跳过空值的功能每调用一次就要预分配内存
  2. 封装原生talib,输入二维矩阵,同时支持参数一维向量化
    • 优点:可为不同股票指定不同参数,可用于按天遍历计算指标。只分配一次内存
  3. 直接调用包中定义的指标,如KDJ等
    • 优点:符合中国习惯的技术指标
    • 缺点:指标数目前比较少。一般没有跳过空值功能
  4. 输入为长表,分组计算
    • 优点:使用简单,可进行指标嵌套
    • 缺点:速度会慢一些。准备工作偏复杂
  5. 输入为宽表
    • 优点:计算快
    • 缺点:计算前需要准备数据为指定格式,占大量内存

停牌处理,跳过空值

  1. TA-Lib遇到空值后面结果全为NaN
  2. 跳过NaN后,导致数据长度不够,部分函数可能报错
  3. 方案一:将所有数据进行移动,时序指标移动到最后,横截面指标移动到最右。
    • 优点:原指标不需要改动,只要提前处理数据。处理速度也快
    • 缺点:时序指标与横截面指标不能混合使用,得分别处理
  4. 方案二:预先初始化空白区,计算指标时屏蔽NaN,算完后回填
    • 优点:外部调用简单,不需要对数据提前处理
    • 缺点:由于有大量的是否跳过NaN的处理,所以速度慢

常见示例

python
import numpy as np # 新版talib,只要替换引用,并添加一句init即可 import ta_cn.talib as ta from ta_cn.utils_wide import pushna, pullna # 原版talib,不支持二维数据 # import talib as ta # 准备数据 h = np.random.rand(1000000).reshape(-1, 5000) + 10 l = np.random.rand(1000000).reshape(-1, 5000) c = np.random.rand(1000000).reshape(-1, 5000) # 指定模式,否则对talib封装的所有函数都不存在 ta.init(mode=2, skipna=False, to_globals=True) # 几个调用函数演示 r = ta.ATR(h, l, c, timeperiod=10) print(r) x, y, z = ta.BBANDS(c, timeperiod=10, nbdevup=2, nbdevdn=2) print(z) # 将少量值设置为空,用来模拟停牌 c[c < 0.4] = np.nan # 提前处理数据,跳过停牌进行计算,再还原的演示 # 嵌套指标时,全为时序指标使用down,或全为截面使用right。混合时此方法不要轻易使用 arr, row, col = pushna(c, direction='down') rr = ta.SMA(arr, timeperiod=10) r = pullna(rr, row, col) print(r)

使用ta_cn中定义的公式

python
import numpy as np from ta_cn.talib import init, set_compatibility_enable, set_compatibility from ta_cn.tdx.over_bought_over_sold import ATR_CN from ta_cn.tdx.trend import MACD # ta_cn.talib库底层是循环调用talib,部分计算效率不高 # 可导入ta_cn中的公式 # 准备数据 h = np.random.rand(10000000).reshape(-1, 50000) + 10 l = np.random.rand(10000000).reshape(-1, 50000) c = np.random.rand(10000000).reshape(-1, 50000) init(mode=2, skipna=False) r = ATR_CN(h, l, c, timeperiod=10) print(r) # 设置参数,让MACD中的EMA算法与国内算法相同 set_compatibility_enable(True) set_compatibility(1) set_compatibility_enable(False) x, y, z = MACD(c, fastperiod=12, slowperiod=26, signalperiod=9) print(z)

长宽表处理

二维矩阵计算,的确方便,Alpha101中的公式很快就可以实现,即支持时序又支持截面,但其中有一个难点,
就是NaN值的处理。pushnapullna可用于解决此问题,但在公式中嵌入就比较棘手。

所以,本项目还特别提供了长表与宽表的装饰器,按照一定的要求套用装饰器,就能让原本不可跳过空值的函数自动跳过空值。
如果明确数据内不会产生空值,可以不使用长宽表装饰器,效率会更快。

长表

处理慢一些,但结果更适合于机器学习。
底层主要通过series_groupby_apply(针对单列输入)和dataframe_groupby_apply(针对多列输入)装饰器来实现跳过空值。

python
import pandas as pd from ta_cn.imports.long_ta import ATR, SMA from ta_cn.imports.long_wq import group_neutralize, rank pd._testing._N = 500 pd._testing._K = 30 open_ = pd._testing.makeTimeDataFrame() + 5 high = pd._testing.makeTimeDataFrame() + 10 low = pd._testing.makeTimeDataFrame() + 5 close = pd._testing.makeTimeDataFrame() + 5 group = close.copy() * 100 // 1 % 5 df = { 'open_': open_.stack(), 'high': high.stack(), 'low': low.stack(), 'close': close.stack(), 'group': group.stack(), } df = pd.DataFrame(df) df.index.names = ['date', 'asset'] kwargs = df.to_dict(orient='series') # 单输入 r = SMA(df['close'], timeperiod=10) print(r.unstack()) # 多输入 r = ATR(df['high'], df['low'], df['close'], 10) print(r.unstack()) # 横截面 r = rank(df['close']) print(r.unstack()) r = group_neutralize(df['close'], df['group']) print(r.unstack())

宽表

处理速度通常比长表要快。核心是输入需要封装成WArr,输出要.raw()提取。
底层通过wide_wraps装饰器来实现空值跳过,通过long_wraps装饰器来实现长表函数转宽表函数

python
import pandas as pd from ta_cn.imports.wide_ta import ATR from ta_cn.utils import np_to_pd from ta_cn.utils_wide import WArr pd._testing._N = 250 pd._testing._K = 30 h = pd._testing.makeTimeDataFrame() + 10 l = pd._testing.makeTimeDataFrame() c = pd._testing.makeTimeDataFrame() # 数据需要封装成特殊对象,实现NaN的堆叠和还原 h_ = WArr.from_array(h, direction='down') l_ = WArr.from_array(l, direction='down') c_ = WArr.from_array(c, direction='down') r = ATR(h_, l_, c_, 10) # 返回的数据可能是np.ndarray print(r.raw()) # 可以再封装回pd.DataFrame d = np_to_pd(r.raw(), copy=False, index=c.index, columns=c.columns) print(d.iloc[-5:])

指标对比清单

参考 指标对比 未完工,待补充

Alpha101/Alpha191

本项目,试着用公式系统实现Alpha101Alpha191,请参考examples文件下的测试示例。它最大的特点是尽量保持原公式的形式,
少改动,防止乱中出错。然后再优化代码提高效率。

停牌处理,空值填充

  1. 板块指数,停牌了也要最近的行情进行计算,否则指数过小
  2. 停牌期的开高低收都是最近的收盘价,收盘价可以ffill

参考项目

  1. TA-Lib TA-Lib C语言版,非官方镜像
  2. ta-lib TA-Lib Python版封装
  3. MyTT My麦语言 T通达信 T同花顺
  4. funcat 公式移植
  5. pandas-ta 支持Pandas扩展的技术指标
  6. ta 通过类实现的技术指标
  7. WorldQuant算子
  8. WorldQuant算子详情

交流群

ta_cn技术指标交流群: 601477228

Contributors

Showing top 1 contributor by commit count.

View all contributors on GitHub →

This article is auto-generated from wukan1986/ta_cn via the GitHub API.Last fetched: 6/28/2026