项目状态 · 版本与时间线

FinTA 最新版本是 1.3:pip 装到的和 GitHub 上的不是同一份代码

很多人以为 pip install finta 拿到的是仓库里的最新代码。实际上:PyPI 上最后 一个版本 1.3 发布于 2021-04-03,而 GitHub 的 master 分支在此之后还改了 OBV、 WTO 和 PSAR,并新增了两个方法;仓库则在 2022-07-24 归档为只读。

本站把这两份源码在同一个进程里同时加载、喂同一份 OHLCV,逐个方法对比输出, 得到可以直接引用的差异清单:90 个同名方法里 82 个数值完全一致, OBV 在 874 根 K 线中有 834 行不同,WTO 最大差 30.14, 另外 VC 与 WAVEPM 只存在于 master。

pinned af01fa5+74/−9 行5 个 hunk82/90 数值一致
PyPI 1.32021-04-03 上传,pip 装到的就是它
GitHub master2022-07-24 最后提交,仓库已归档只读
差异:2 个指标 + 2 个新方法OBV / WTO 数值不同,VC / WAVEPM 只在 master
依据 PyPI releases、GitHub API 与本机双源码并跑实测(_evidence/version_behaviour.txt)整理的版本状态示意;不是官方版本路线图。

版本现状

FinTA 的最新版本到底是哪一个?三条来源怎么对上

表 1:同一个项目的三份「最新」
来源版本 / 提交时间你能从它拿到什么本站核验方式
PyPI(pip install finta)1.32021-04-03wheel 与 sdist;finta/finta.py 共 2243 行、90 个公开方法下载 sdist 解包后做 AST 清点
GitHub 默认分支 masteraf01fa594995de78f5ada5c336e61cd87c46b1512022-07-24(最后一次推送)finta/finta.py 共 2308 行、92 个公开方法;含 1.3 之后的所有修复GitHub API 取默认分支首个提交作 pinned sha,再按该 sha 抓 tarball
GitHub 仓库状态archived = true(只读),归档于 2022-09-02页面顶部横幅写明归档日仍可 clone 与下载,但 issue 不再修、PR 不再合仓库页截图 + GitHub API repo.archived、pushed_at
GitHub 仓库页可见计数Star 2.3k / Fork 715 / Issues 22 / Pull requests 2 / 394 commits / 23 tags / Releases 18 / Used by 6602026-10-12 快照核对项目活跃度;注意 Releases 18 与 PyPI 的 15 个版本不是同一个口径仓库页截图(已存档,SHA-256 见证据矩阵)

这三个来源不会互相矛盾:PyPI 的 1.3 是 2021 年发的包,master 是 2022 年停更前的代码,而归档只是一道「不再维护」的标记。真正要小心的是——中文教程几乎都基于 README,而 README 在 master 上比 PyPI 上多一条指标(详见方法清单页)。

差异总览

1.3 和 master 差多少?94 个方法逐个比对的结果

表 2:同一个进程里同时加载两份源码后的比对结果
比对维度结果说明
源码行数1.3:2243 行 → master:2308 行diff = +74 / −9 行、5 个 hunk
公开方法数1.3:90 个 → master:92 个多出 VC(Value Chart)与 WAVEPM
数值完全一致的方法82 个包括 SMA、EMA、RSI、MACD、BBANDS、ATR、ADX、ICHIMOKU 等主要指标
数值不同的方法2 个OBV(平盘处理)与 WTO(ESA 的 span 与参数名拼写)
列顺序变化的方法PSAR1.3 返回 [psar, psarbear, psarbull],master 返回 [psar, psarbull, psarbear]
参数名变化的方法WTO1.3 的形参拼写为 channel_lenght / average_lenght,master 改成正确拼写——用关键字传参的代码会在换版本时报 TypeError
已删除的方法VR0.4.4 还有,1.x 起移除;老代码调用会 AttributeError

结论:换版本不会让大多数指标变数,但会让 OBV 与 WTO 变数、让按位置取列的 PSAR 代码取错列。如果你的管道里已经存了历史指标值,升级(或改用 master 源码)之后这两列会与历史不一致——这件事在官方 CHANGELOG 里查不到,因为仓库没有 CHANGELOG。

数值差异

OBV 和 WTO 到底差多少?可复现的读数

表 3:同一份 874 行 OHLCV(仓库自带 tests/data/bittrex_btc-usdt.csv)上的实测差异
指标1.3 的结果master 的结果差异量根因(源码 diff)
OBV最后一根 −6731.5451最后一根 −6729.8338874 行中 834 行不同,最大绝对差 1.7112,首个不同点在 2016-01-271.3 把「收盘价不变」归入下跌分支(减成交量);master 改成 >= 并新增「不变则沿用上一值」分支
WTO(WT1)最后一根 −60.29最后一根 −69.74最大绝对差 30.1381.3 里 esa 用的是 channel_length,master 改用 average_length——等于换了平滑窗口
PSAR[psar, psarbear, psarbull][psar, psarbull, psarbear]数值相同、列顺序不同两列的赋值语句写反后又被修正
VC / WAVEPMAttributeError(方法不存在)可正常返回——这两个方法在 1.3 发布后才加入,从未发版
# 复现方式:把两份源码放在同一个进程里,用同一份数据各算一遍
import importlib.util, pandas as pd
from finta import TA as TA_13                      # pip 装到的 1.3

spec = importlib.util.spec_from_file_location('fm', r'.\master\finta.py')
fm = importlib.util.module_from_spec(spec); spec.loader.exec_module(fm)
TA_master = fm.TA                                  # 2022 年的 master

ohlc = pd.read_csv('tests/data/bittrex_btc-usdt.csv', index_col='date', parse_dates=True)
a, b = TA_13.OBV(ohlc), TA_master.OBV(ohlc)
print((a - b).abs().max())        # 实测:1.711236
print(int(((a - b).abs() > 1e-9).sum()), len(a))   # 实测:834 874

print(list(TA_13.PSAR(ohlc).columns))       # ['psar', 'psarbear', 'psarbull']
print(list(TA_master.PSAR(ohlc).columns))   # ['psar', 'psarbull', 'psarbear']

上面的数字来自一次真实运行(日志见 _evidence/version_behaviour.txt),但只代表这一份数据:换数据、换周期,具体差值会变,方向不会(OBV 的平盘处理与 WTO 的窗口不同是结构性的)。要判断自己的结果是否受影响,照上面的片段跑一次即可。

判定版本

怎么确认自己用的是哪一份代码

四步确认版本

  • 先看包版本:python -m pip show finta 会打印 Version: 1.3。不要用 finta.__version__——这个包没有导出该属性,会直接 AttributeError。
  • 再看方法是否存在:hasattr(TA, 'WAVEPM') 与 hasattr(TA, 'VC')。1.3 上两者都是 False;如果你从 GitHub 源码装了,会是 True。
  • 用行为判据兜底:对同样的数据算 OBV,看平盘日(收盘价与前一交易日的差值等于 0)那几行。1.3 会输出 NaN,master 会沿用上一值——这是最直接的版本指纹。
  • 记录进你的实验笔记:把版本判定结果、pandas/numpy 版本、数据文件哈希一起写下,否则三个月后无法解释「为什么同样的代码结果变了」。
  • 表 4:三种处置方式,分别适合什么情况
    处置怎么做优点代价
    ① 就用 PyPI 的 1.3什么都不改,把 pandas 钉在 <2最省事,pip 可复现OBV 的平盘处理保留旧行为;VC/WAVEPM 用不了
    ② 装 master 源码pip install git+https://github.com/peerchemist/finta.git(仓库已归档但仍可 clone)拿到 2022 年的全部修复不是发布版,没有 wheel、没有版本号,团队协作时要额外记录 commit
    ③ 只借公式、自己实现把需要的 3–5 个指标照源码抄进自己的工具函数并写单测彻底摆脱上游冻结要自己维护公式;跨库数值差异仍要自己承担

    本站不推荐某一种,只提示判断依据:如果你的结果要长期复用或与历史数据对齐,先固定版本再谈算法;如果只是一次性研究、且不需要 VC/WAVEPM,用 PyPI 的 1.3 就够了。

    归档影响

    仓库归档之后,实际会失去什么

    表 5:归档的实际影响逐项拆开
    项目归档前归档后对你意味着什么
    Bug 修复issue 会有人处理(归档时仍开着 22 个 issue 与 2 个 PR)issue 不再被处理遇到未记录的坑只能自己绕过或改源码
    新 pandas 兼容曾有多次适配提交不会再有iteritems 这类破坏性变更永久留在库里(本站实测已有 4 个方法因此失效)
    新指标0.x → 1.3 期间持续新增停止在 master 的 VC / WAVEPM想要更多指标只能换库或自己写
    安全与依赖依赖只有 numpy/pandas,攻击面小同样小风险点不是安全,而是依赖树上游变动
    文档README 会随代码更新README 冻结在 2022 年PyPI 页面上的清单比代码少 1 条(WAVEPM)
    社区支持有 PR 与讨论讨论仍在但不再合并网上的答案可能对应更老的 0.x 版本,TS 类就是这类残留

    把上面几条合起来看:归档的代价集中在「依赖上游变动」与「没有权威答案」,而不是「今天就跑不了」。也因此本站每页都给可自行复现的判定方法,而不是让你相信任何二手结论——包括本站的结论。

    FAQ

    关于 FinTA 版本状态的常见问题

    FinTA 的 PyPI 最新版本是多少?
    1.3,上传于 2021-04-03。此后 PyPI 上没有 1.4;GitHub 仓库最后一次代码推送是 2022-07-24,并在 2022-09-02 被归档为只读。全部 15 个版本、25 个分发文件的时间戳可查(本站证据目录保留了 PyPI JSON 原文件)。另外注意 GitHub 页面上显示的是 Releases 18 个,那与 PyPI 的 15 个版本不是同一个口径。
    pip 装到的 1.3 和 GitHub 上看到的不一样,哪个才是「真的」?
    两个都是真的,只是不是同一份代码。pip 给你的是 2021 年的发布版;GitHub master 是 2022 年的开发态,包含未发版的修复,多出 VC 与 WAVEPM 两个方法。写文档或写测试时,必须先声明你指的是哪一份——本站全站以 pinned commit af01fa5 与 PyPI 1.3 两个口径并列标注。
    我看到的中文教程里有 from finta import TA, TS,能用吗?
    不能。本站把 8 个历史版本(0.2.8 / 0.3.6 / 0.4.0 / 0.4.4 / 1.0 / 1.1 / 1.2 / 1.3)的源码逐个做 AST 解析,class TS 一次都没有出现,只有 class TA。写 from finta import TS 在任何版本上都会 AttributeError。
    既然归档了,还能用它吗?
    能——本站实测 1.3 在 pandas 1.5.3 上有 84/90 个方法默认可调用。但要把两件事讲清楚:一是不会有新修复;二是新 pandas 上的失效方法不会有人修。把归档库用在一次性研究、教学或读源码学公式上没有问题;用在需要长期维护的生产管道上要先评估替代方案。
    有没有 CHANGELOG 能看版本差异?
    没有。仓库里没有 CHANGELOG 文件,PyPI 页面也不列变更。这就是本站要做「双源码并跑」的原因——版本差异只能从 diff 与实测反推,本站的证据目录里保留了完整 unified diff。
    我怎么把结论记进自己的项目里?
    建议的最小记录是四行:finta 的版本(pip show finta)、是否含 WAVEPM、pandas/numpy 的实际版本、以及数据文件的哈希。本站安装页给出的验收脚本会一次性打印这些信息,可以直接放进你的 notebook 头部。

    相关阅读:安装与运行时实测、90 个方法清单。本页结论绑定 2026-10-12 的实测环境(Python 3.11.9),数值口径以官方源码为准。

    接下来读哪一页?

    版本状态清楚了,下一步是确认它在你的环境里能不能跑——安装页给出 14 个失败方法的报错原文、控制组对照与可以复制运行的验收脚本。