MIT License

项目介绍

Yvictor/polars_ta_extension 是一个托管在 GitHub 上的开源项目,主要使用 Rust 编写,采用 MIT License 许可证,目前获得 257 个 Star、39 次 Fork。

仓库全名
Yvictor/polars_ta_extension
开源许可证
MIT License
Star 数
257
Fork 数
39
未关闭 Issue
4

README 摘要

Polars Extension for Ta-Lib Version 0.2.1 bundles TA-Lib 0.8.1: all 201 batch indicators, including SuperTrend, VWAP, HMA, KDJ and Heikin-Ashi. Python 3.10+; Polars 1.20+ and 2.x. Binary wheels include the C library. Upgrade notes, platform matrix and source builds Install the skill for Codex, Claude Code or Cursor Reproducible performance results Native AI plugin installation The repository supports the same native…

完整内容见 GitHub 原始 README 或本页 。

常见问题

polars_ta_extension 用什么语言开发?

主要使用 Rust 编写,采用 MIT License 许可证,目前有 257 个 Star。

polars_ta_extension 可以免费商用吗?

仓库采用 MIT License 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 polars_ta_extension 的源码?

可以直接克隆仓库:git clone https://github.com/Yvictor/polars_ta_extension.git,默认分支为 master;安装与运行步骤见仓库 README。

polars_ta_extension 最近还在维护吗?

仓库最近一次更新为 1 周前,当前有 4 个未关闭 Issue;Star 数为 257,可作为社区活跃度的参考。

关于

Polars extension for Ta-Lib: Support Ta-Lib functions in Polars expressions

描述取自 GitHub 官方 API,中文内容由 GitRead 中文社区 编辑团队整理。

简要分析

热度分
341
价值分
166
活跃状态
活跃

语言占比

C
Makefile
Python
Rust
Shell

Release

README

Polars Extension for Ta-Lib

Version 0.2.1 bundles TA-Lib 0.8.1: all 201 batch indicators, including SuperTrend, VWAP, HMA, KDJ and Heikin-Ashi. Python 3.10+; Polars 1.20+ and 2.x. Binary wheels include the C library.

Native AI plugin installation

The repository supports the same native marketplace/install flow as Shioaji:

# Claude Code
claude plugin marketplace add Yvictor/polars_ta_extension
claude plugin install polars-talib@polars-ta-extension

# Codex
codex plugin marketplace add Yvictor/polars_ta_extension
codex plugin add polars-talib@polars-ta-extension

See skill installation for invocation, updates, local checkouts, standalone installation, and Cursor support. The plugin supplies coding guidance; install the Python library separately.

Getting Started

pip install 'polars-talib==0.2.1'
# or, in a uv project
uv add 'polars-talib==0.2.1'

and

import polars
import polars_talib as plta

Usage

single symbol usage

df.with_columns(
    pl.col("close").ta.ema(5).alias("ema5"),
    pl.col("close").ta.macd(12, 26, 9).struct.field("macd"),
    pl.col("close").ta.macd(12, 26, 9).struct.field("macdsignal"),
    pl.col("open").ta.cdl2crows(pl.col("high"), pl.col("low"), pl.col("close")).alias("cdl2crows"),
    pl.col("close").ta.wclprice("high", "low").alias("wclprice"),
)

typed namespace access

plta.col(...) returns the same .ta namespace with a static return type, so editors and type checkers resolve every indicator method:

df.with_columns(
    plta.col("close").ema(5).alias("ema5"),
    plta.col(pl.col("close") * 2).rsi(14).alias("rsi_doubled"),
)

multiple symbol usage using over syntax

Sort by symbol and timestamp before computing history-dependent indicators.

df.with_columns(
    pl.col("close").ta.ema(5).over("symbol").alias("ema5"),
    pl.col("close").ta.macd(12, 26, 9).over("symbol").struct.field("macd"),
    pl.col("close").ta.macd(12, 26, 9).over("symbol").struct.field("macdsignal"),
    pl.col("open").ta.cdl2crows(
        pl.col("high"), pl.col("low"), pl.col("close")
    ).over("symbol").alias("cdl2crows"),
    pl.col("close").ta.wclprice("high", "low").over("symbol").alias("wclprice"),
)

missing values

A Polars null marks a missing observation. Leading nulls are skipped as warm-up. After that, every output row that can depend on a null input is null: to the end of the partition for recursive indicators such as RSI, EMA, MACD or OBV, and for the indicator’s lookback window for window-bounded ones such as MAX, WILLR or the math operators. A null never turns into a plausible number, and under .over("symbol") it only affects its own symbol. NaN and infinity are ordinary float values and are passed to TA-Lib unchanged, so its results for them are undefined; use pl.col("close").fill_nan(None) when NaN means missing. To restart an indicator after each gap instead, or to skip gaps:

# restart after every gap, per symbol
gap = pl.col("close").is_null().cum_sum()
df = df.with_columns(pl.col("close").ta.rsi(14).over("symbol", gap).alias("rsi_restart"))

# compute over observed rows only (e.g. market-closed days), then join back
observed = df.filter(pl.col("close").is_not_null()).with_columns(
    pl.col("close").ta.rsi(14).over("symbol").alias("rsi_observed")
)
df = df.join(observed.select("symbol", "date", "rsi_observed"), on=["symbol", "date"], how="left")

usage just like talib.abstract with more flexible

df.with_columns(
    plta.ht_dcperiod(),
    plta.ht_dcperiod(pl.col("close")),
    plta.aroon(),
    plta.aroon(pl.col("high"), pl.col("low"), timeperiod=10),
    plta.wclprice(),
    plta.wclprice(
        pl.col("high"), pl.col("low"), pl.col("close"), 
        timeperiod=10
    ),
)

Performance

See the 0.2.0 release benchmark for a controlled comparison against 0.1.6, raw samples and a reproducible script. The notebook comparison below is historical and measures a different workload.

Polars with polars_talib

%%timeit
df = p.with_columns(
    plta.sma(timeperiod=5).over("Symbol").alias("sma5"),
    plta.macd(fastperiod=10, slowperiod=20, signalperiod=5).over("Symbol").alias("macd"),
    plta.stoch(pl.col("high"), pl.col("low"), pl.col("close"), fastk_period=14, slowk_period=7, slowd_period=7).over("Symbol").alias("stoch"),
    plta.wclprice().over("Symbol").alias("wclprice"),
).with_columns(
    pl.col("macd").struct.field("macd"),
    pl.col("macd").struct.field("macdsignal"),
    pl.col("macd").struct.field("macdhist"),
    pl.col("stoch").struct.field("slowk"),
    pl.col("stoch").struct.field("slowd"),
).select(
    pl.exclude("stoch")
).filter(
    pl.col("Symbol") == "AAPL"
).collect()

135 ms ± 5.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Pandas with talib

%%timeit
df["sma5"] = df.groupby("Ticker")["close"].transform(lambda x: ta.SMA(x, timeperiod=5))
df["macd"] = df.groupby("Ticker")["close"].transform(lambda x: ta.MACD(x, fastperiod=10, slowperiod=20, signalperiod=5)[0])
df["macdsignal"] = df.groupby("Ticker")["close"].transform(lambda x: ta.MACD(x, fastperiod=10, slowperiod=20, signalperiod=5)[1])
df["macdhist"] = df.groupby("Ticker")["close"].transform(lambda x: ta.MACD(x, fastperiod=10, slowperiod=20, signalperiod=5)[2])
df["slowk"] = df.groupby("Ticker").apply(lambda x: ta.STOCH(x, fastk_period=14, slowk_period=7, slowd_period=7)).droplevel(0)["slowk"] 
df["slowd"] = df.groupby("Ticker").apply(lambda x: ta.STOCH(x, fastk_period=14, slowk_period=7, slowd_period=7)).droplevel(0)["slowd"]
df["wclprice"] = df.groupby("Ticker").apply(lambda x: ta.WCLPRICE(x)).droplevel(0)
df.loc["AAPL"]

19.2 s ± 367 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

That historical notebook measured about 150x for this workload; see basic.ipynb

Supported Indicators and Functions

import polars_talib as plta

# list of functions
plta.get_functions()

# dict of functions by group
plta.get_function_groups()

The complete 201-indicator catalog includes every function in the pinned upstream release. New examples:

df.with_columns(
    plta.supertrend().alias("supertrend"),
    plta.vwap().alias("vwap"),
    pl.col("close").ta.hma(timeperiod=20).alias("hma"),
    plta.kdj().alias("kdj"),
)

Multi-output indicators return Struct columns. For example, plta.supertrend().struct.field("trend") returns the Int32 trend flag.

评论

暂无评论