{"id":21438101,"url":"https://github.com/wukan1986/ta_cn","last_synced_at":"2025-04-07T06:05:27.204Z","repository":{"id":39331614,"uuid":"503799511","full_name":"wukan1986/ta_cn","owner":"wukan1986","description":"中国版技术指标","archived":false,"fork":false,"pushed_at":"2023-12-27T04:52:38.000Z","size":429,"stargazers_count":165,"open_issues_count":6,"forks_count":53,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-03-31T05:04:04.264Z","etag":null,"topics":["alpha101","alpha191","bottleneck","kdj","macd","numba","pandas","talib"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wukan1986.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-15T14:26:14.000Z","updated_at":"2025-03-29T15:54:19.000Z","dependencies_parsed_at":"2023-12-27T05:42:24.114Z","dependency_job_id":null,"html_url":"https://github.com/wukan1986/ta_cn","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wukan1986%2Fta_cn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wukan1986%2Fta_cn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wukan1986%2Fta_cn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wukan1986%2Fta_cn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wukan1986","download_url":"https://codeload.github.com/wukan1986/ta_cn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247601447,"owners_count":20964864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpha101","alpha191","bottleneck","kdj","macd","numba","pandas","talib"],"created_at":"2024-11-23T00:32:53.659Z","updated_at":"2025-04-07T06:05:27.184Z","avatar_url":"https://github.com/wukan1986.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# ta_cn 中国版技术指标\n\n## !!! 注意：如要在`polars`中使用技术指标，请使用[polars_ta](https://github.com/wukan1986/polars_ta)\n\n## 项目背景\n\n初学量化，技术指标一般使用`TA-Lib`，但存在以下问题\n\n1. 部分技术指标与国内不同。但大部分中国股民都是参考国内技术指标进行交易。需要实现中国版指标\n2. `TA-Lib`只支持单支序列，要计算多支股票需循环，耗时久。\n\n在实现遗传算法挖因子时，意识到如果能将常用的操作都转成算子，将大大简化策略的研究，\n特别是将`+`、`-`、`*`、`/`等中缀操作符转成`ADD()`、`SUB()`、`MUL()`、`DIV()`前缀函数，可直接输到遗传算法工具中\n\n所以开始参考`Alpha101`和各券商金融工程研报，试着实现一些算子，但后期实现中发现一些问题\n\n1. 每家金工的研报指标命名上都有区别，难以统一\n2. 指标太多，实现工作太大\n\n直到看到了`MyTT`这个项目才意识到，指标命名参考股票软件的公式才是最方便直接的，可以直接到各股软中复制公式。遇到性能问题再针对性转换即可。\n\n## 本人为何不直接用`MyTT`，而是重复造轮子呢？\n\n1. 大部分公式只支持单条数据，遇到几千支股票的DataFrame，循环太慢\n2. `TA-Lib`与国内指标不同，区别在哪，没有对比。错过了很好的教学机会\n3. 为了行数短牺牲了可读性\n4. 部分函数直接复制于股票软件，代码没有优化，有重复计算\n\n## 再次大迭代，仿WorldQuant\n\n1. 2022年9月初，知道WorldQuant Websim重新开放为WorldQuant BRAIN后，开始研究国外的平台\n2. WQ公式更加科学。例如：\n    1. WQ时序有`ts_`前缀\n    2. WQ有横截面函数和分组函数，通达信没有\n    3. 通达信将大量不相关的指标都归类为引用函数\n    4. WQ公式为Alpha因子而设计，有大量的权重处理等函数\n\n## 目标\n\n1. 优先实现WorldQuant公式，然后实现通达信公式\n2. 通过在通达信中导入WQ公式并别名，来实现通达信公式覆盖\n3. 支持二维矩阵计算\n4. 支持长表和宽表，支持NaN跳过\n5. 最终实现WQ的本地版\n\n## 实现方案优先级\n\n1. bottleneck。支持二维数据，优先使用\n2. TA-Lib。封装了常用函数，次要选择\n3. numba。速度受影响，最后才用它\n\n## 安装\n\n1. 只想使用二维矩阵TA-Lib，只需安装基础版即可\n\n```commandline\npip install ta_cn -i https://mirrors.aliyun.com/pypi/simple --upgrade\n```\n\n2. 使用中国版指标加速\n\n```commandline\npip install ta_cn[cn] -i https://mirrors.aliyun.com/pypi/simple --upgrade\n```\n\n3. 开发人员安装。开发迭代很快，只有版本稳定才会发布到`PyPI`，需要时效更高的安装方法\n    1. 从github下载zip文件\n    2. 解压zip, 进入解压后目录，输入以下命令\n\n```commandline\npip install .[cn] -i https://mirrors.aliyun.com/pypi/simple --upgrade\n```\n\n4. 库维护者安装。可修改本地文件\n\n```commandline\npip install -e .\n```\n\n## 常见使用方法\n\n1. 转发原生talib，输入一维向量\n    - 优点: 本库提供了跳过空值的功能\n    - 缺点: 不要在大量循环中调用，因为跳过空值的功能每调用一次就要预分配内存\n2. 封装原生talib，输入二维矩阵，同时支持参数一维向量化\n    - 优点：可为不同股票指定不同参数，可用于按天遍历计算指标。只分配一次内存\n3. 直接调用包中定义的指标，如KDJ等\n    - 优点：符合中国习惯的技术指标\n    - 缺点：指标数目前比较少。一般没有跳过空值功能\n4. 输入为长表，分组计算\n    - 优点：使用简单，可进行指标嵌套\n    - 缺点：速度会慢一些。准备工作偏复杂\n5. 输入为宽表\n    - 优点：计算快\n    - 缺点：计算前需要准备数据为指定格式，占大量内存\n\n## 停牌处理，跳过空值\n\n1. TA-Lib遇到空值后面结果全为NaN\n2. 跳过NaN后，导致数据长度不够，部分函数可能报错\n3. 方案一：将所有数据进行移动，时序指标移动到最后，横截面指标移动到最右。\n    - 优点：原指标不需要改动，只要提前处理数据。处理速度也快\n    - 缺点：时序指标与横截面指标不能混合使用，得分别处理\n4. 方案二：预先初始化空白区，计算指标时屏蔽NaN,算完后回填\n    - 优点：外部调用简单，不需要对数据提前处理\n    - 缺点：由于有大量的是否跳过NaN的处理，所以速度慢\n\n### 常见示例\n\n```python\nimport numpy as np\n\n# 新版talib,只要替换引用，并添加一句init即可\nimport ta_cn.talib as ta\nfrom ta_cn.utils_wide import pushna, pullna\n\n# 原版talib,不支持二维数据\n# import talib as ta\n\n# 准备数据\nh = np.random.rand(1000000).reshape(-1, 5000) + 10\nl = np.random.rand(1000000).reshape(-1, 5000)\nc = np.random.rand(1000000).reshape(-1, 5000)\n# 指定模式，否则对talib封装的所有函数都不存在\nta.init(mode=2, skipna=False, to_globals=True)\n\n# 几个调用函数演示\nr = ta.ATR(h, l, c, timeperiod=10)\nprint(r)\nx, y, z = ta.BBANDS(c, timeperiod=10, nbdevup=2, nbdevdn=2)\nprint(z)\n\n# 将少量值设置为空，用来模拟停牌\nc[c \u003c 0.4] = np.nan\n\n# 提前处理数据，跳过停牌进行计算，再还原的演示\n# 嵌套指标时，全为时序指标使用down,或全为截面使用right。混合时此方法不要轻易使用\narr, row, col = pushna(c, direction='down')\nrr = ta.SMA(arr, timeperiod=10)\nr = pullna(rr, row, col)\nprint(r)\n\n```\n\n### 使用ta_cn中定义的公式\n\n```python\nimport numpy as np\n\nfrom ta_cn.talib import init, set_compatibility_enable, set_compatibility\nfrom ta_cn.tdx.over_bought_over_sold import ATR_CN\nfrom ta_cn.tdx.trend import MACD\n\n# ta_cn.talib库底层是循环调用talib，部分计算效率不高\n# 可导入ta_cn中的公式\n\n# 准备数据\nh = np.random.rand(10000000).reshape(-1, 50000) + 10\nl = np.random.rand(10000000).reshape(-1, 50000)\nc = np.random.rand(10000000).reshape(-1, 50000)\n\ninit(mode=2, skipna=False)\n\nr = ATR_CN(h, l, c, timeperiod=10)\nprint(r)\n\n# 设置参数，让MACD中的EMA算法与国内算法相同\nset_compatibility_enable(True)\nset_compatibility(1)\nset_compatibility_enable(False)\n\nx, y, z = MACD(c, fastperiod=12, slowperiod=26, signalperiod=9)\nprint(z)\n```\n\n## 长宽表处理\n\n二维矩阵计算，的确方便，`Alpha101`中的公式很快就可以实现，即支持时序又支持截面，但其中有一个难点，\n就是NaN值的处理。`pushna`和`pullna`可用于解决此问题，但在公式中嵌入就比较棘手。\n\n所以，本项目还特别提供了长表与宽表的装饰器，按照一定的要求套用装饰器，就能让原本不可跳过空值的函数自动跳过空值。\n如果明确数据内不会产生空值，可以不使用长宽表装饰器，效率会更快。\n\n### 长表\n\n处理慢一些，但结果更适合于机器学习。\n底层主要通过`series_groupby_apply`（针对单列输入）和`dataframe_groupby_apply`（针对多列输入）装饰器来实现跳过空值。\n\n```python\nimport pandas as pd\n\nfrom ta_cn.imports.long_ta import ATR, SMA\nfrom ta_cn.imports.long_wq import group_neutralize, rank\n\npd._testing._N = 500\npd._testing._K = 30\n\nopen_ = pd._testing.makeTimeDataFrame() + 5\nhigh = pd._testing.makeTimeDataFrame() + 10\nlow = pd._testing.makeTimeDataFrame() + 5\nclose = pd._testing.makeTimeDataFrame() + 5\ngroup = close.copy() * 100 // 1 % 5\n\ndf = {\n    'open_': open_.stack(),\n    'high': high.stack(),\n    'low': low.stack(),\n    'close': close.stack(),\n    'group': group.stack(),\n}\ndf = pd.DataFrame(df)\ndf.index.names = ['date', 'asset']\nkwargs = df.to_dict(orient='series')\n\n# 单输入\nr = SMA(df['close'], timeperiod=10)\nprint(r.unstack())\n# 多输入\nr = ATR(df['high'], df['low'], df['close'], 10)\nprint(r.unstack())\n# 横截面\nr = rank(df['close'])\nprint(r.unstack())\nr = group_neutralize(df['close'], df['group'])\n\nprint(r.unstack())\n\n\n```\n\n### 宽表\n\n处理速度通常比长表要快。核心是输入需要封装成`WArr`,输出要`.raw()`提取。\n底层通过`wide_wraps`装饰器来实现空值跳过，通过`long_wraps`装饰器来实现长表函数转宽表函数\n\n```python\nimport pandas as pd\n\nfrom ta_cn.imports.wide_ta import ATR\nfrom ta_cn.utils import np_to_pd\nfrom ta_cn.utils_wide import WArr\n\npd._testing._N = 250\npd._testing._K = 30\nh = pd._testing.makeTimeDataFrame() + 10\nl = pd._testing.makeTimeDataFrame()\nc = pd._testing.makeTimeDataFrame()\n\n# 数据需要封装成特殊对象，实现NaN的堆叠和还原\nh_ = WArr.from_array(h, direction='down')\nl_ = WArr.from_array(l, direction='down')\nc_ = WArr.from_array(c, direction='down')\n\nr = ATR(h_, l_, c_, 10)\n# 返回的数据可能是np.ndarray\nprint(r.raw())\n\n# 可以再封装回pd.DataFrame\nd = np_to_pd(r.raw(), copy=False, index=c.index, columns=c.columns)\nprint(d.iloc[-5:])\n\n\n```\n\n## 指标对比清单\n\n参考 [指标对比](指标对比.xlsx) 未完工，待补充\n\n## Alpha101/Alpha191\n\n本项目，试着用公式系统实现`Alpha101`、`Alpha191`，请参考examples文件下的测试示例。它最大的特点是尽量保持原公式的形式，\n少改动，防止乱中出错。然后再优化代码提高效率。\n\n## 停牌处理，空值填充\n\n1. 板块指数，停牌了也要最近的行情进行计算，否则指数过小\n2. 停牌期的开高低收都是最近的收盘价，收盘价可以ffill\n\n## 参考项目\n\n1. [TA-Lib](https://github.com/TA-Lib/ta-lib) TA-Lib C语言版，非官方镜像\n2. [ta-lib](https://github.com/mrjbq7/ta-lib) TA-Lib Python版封装\n3. [MyTT](https://github.com/mpquant/MyTT) My麦语言 T通达信 T同花顺\n4. [funcat](https://github.com/cedricporter/funcat) 公式移植\n5. [pandas-ta](https://github.com/twopirllc/pandas-ta) 支持Pandas扩展的技术指标\n6. [ta](https://github.com/bukosabino/ta) 通过类实现的技术指标\n7. [WorldQuant算子](https://platform.worldquantbrain.com/learn/data-and-operators/operators)\n8. [WorldQuant算子详情](https://platform.worldquantbrain.com/learn/data-and-operators/detailed-operator-descriptions)\n\n## 交流群\n\nta_cn技术指标交流群: 601477228","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwukan1986%2Fta_cn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwukan1986%2Fta_cn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwukan1986%2Fta_cn/lists"}