Skip to main content

Alpha Library: A high-performance rolling window calculation library implemented in Rust with Python bindings. Used for financial data analysis and factor research.

Project description

betaquant

高性能量化金融算子库。Rust 实现 + Python 绑定 (PyO3)。

提供因子量化交易中常用的滚动窗口高效计算。

项目源:py-alpha-lib

安装

pip install betaquant

授权(License Token)

betaquant 的算子受许可证(license)保护,使用前需持有有效的 license token

取得机器指纹(机器绑定用)

import betaquant

machine = betaquant.machine_fingerprint()   # 跨 Linux/Windows,机器绑定以它为准
print(machine)

把该指纹提交给签发方,换取绑定到本机的 token。

启用 token:算子入口自动鉴权(推荐)

调用 set_license_token 把 token 设入进程级状态后,每个算子入口都会自动鉴权: 未授权 / 过期 / 未设 token 时算子直接抛 ValueError,无需在每次调用前手写判断。

import betaquant

token = "<从签发方取得的 license key>"
betaquant.set_license_token(token)   # 启动时一次

result = betaquant.ts_ma(data, 3)     # 已授权 → 正常计算
# 若 token 未设置 / 过期 / 该算子不在 allow,betaquant.ts_ma(...) 直接抛 ValueError

不调用 set_license_token 而直接调算子会抛 ValueError。这是与早期版本的关键区别: 鉴权不再依赖调用方自觉判断,而是内嵌在每个算子入口。

手动校验(可选)

也可显式验签或单独判断某算子是否授权(不改变进程级 token 状态):

# 验签 + 校验(失败 / 过期 / 机器不符抛 ValueError),返回声明 dict
# 机器绑定自动按本机指纹校验,无需传 machine
claims = betaquant.verify_license(token)

# 判断某算子是否被授权(token 无效 / 过期直接返回 False)
if betaquant.license_allows(token, "ts_ma"):
    ...

授权语义(默认拒绝):算子必须显式出现在 allow(或 allow"*")才放行; deny 优先级高于 allowallow=[] 表示全部拒绝,并非不限制。

使用

上下文设置

通过 betaquant.set_ctx() 控制计算行为:

  • groups — 数据数组中的标的数量。每个 group 独立并行处理。cc_rank 等截面算子要求 groups >= 2
  • flags — 位标志:
    • FLAG_SKIP_NAN (1):滚动窗口中跳过 NaN。
    • FLAG_STRICTLY_CYCLE (2):窗口未填满前返回 NaN(与 pandas rolling() 默认行为一致)。
    • | 组合:flags=FLAG_SKIP_NAN | FLAG_STRICTLY_CYCLE

set_ctx 只更新传入的字段,其它字段保持当前值。要恢复默认 (groups=0, flags=0) 调用 betaquant.reset_ctx()

如需只算某一段,请在调用前自行切片输入数组(如 betaquant.ts_ma(data[start:end], 3))。

NaN 处理合约(所有滑窗算子)

输入条件 默认 FLAG_SKIP_NAN FLAG_STRICTLY_CYCLE 两者同时
periods == 0 全 NaN(除累计语义算子) 全 NaN 全 NaN 全 NaN
当前位置是 NaN NaN NaN NaN NaN
窗口含 NaN(当前有效) NaN 跳过窗口里的 NaN,对剩余有效值算 NaN 有效值数 < periods → NaN
i + 1 < periods(窗口未填满) partial 输出 partial 输出 NaN NaN

FLAG_SKIP_NANfixed-time-slot 语义:窗口固定 periods 个时间槽,里面的 NaN 被跳过。 不是 "expand-window 找最近 N 个有效值"。

少数算子有特殊"最少有效值"门槛:var/stddev/zscore ≥ 2,skewness ≥ 3,kurtosis ≥ 4, 不满足时仍返回 NaN。

非滑窗算子(ts_ema / ts_lwma / ts_dma / ts_sma / ts_sumbars / ts_ref / ts_barslast 等) 有自己的 NaN 语义,详见各算子文档。

截面算子(cc_*)的 NaN 处理

上表只适用于滑窗算子。截面算子(cc_rank / cc_zscore / cc_neutralize / cc_bins / cc_group_rank / cc_group_zscore)跨 group 维度计算,没有滚动窗口概念, 不受 FLAG_SKIP_NAN / FLAG_STRICTLY_CYCLE 影响,固定按下面的规则处理:

  • 某个位置输入为 NaN ⇒ 该位置输出 NaN;
  • 计算截面统计量(均值 / 标准差 / 排名 / 分箱)时自动剔除 NaN,只用有效值;
  • 有效值不足时返回 NaN(如 cc_zscore / cc_group_zscore 需要 ≥ 2 个有效值, 否则该截面 / 组输出 NaN)。

也就是说截面算子始终是"跳过 NaN"的语义,无需也无法通过 flag 切换。

算子专门约束

少数算子对输入有额外要求,不满足时返回 NaN 或报错:

  • ts_max_drawdown — 输入应为严格正的价格 / 权益曲线。 窗口里出现 ≤ 0 的 peak 时返回 NaN(百分比回撤无定义),不会静默返回 0。

  • ts_dma / ts_smaweight / alpha 必须是 [0, 1] 内的有限值; NaN±infts_sma(n=0, ...) 都会报 InvalidParameter,而不是产生 NaN 输出。

    import betaquant
    import numpy as np
    
    data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=np.float64)
    
    # 3 周期均线(预热阶段返回部分窗口结果)
    result = betaquant.ts_ma(data, 3)
    # [1.  1.5 2.  3.  4.  5.  6.  7.  8.  9.]
    
    # 严格模式:窗口填满前返回 NaN
    betaquant.set_ctx(flags=betaquant.FLAG_STRICTLY_CYCLE)
    result = betaquant.ts_ma(data, 3)
    # [nan nan 2.  3.  4.  5.  6.  7.  8.  9.]
    
    # 跳过 NaN(fixed-time-slot:窗口里跳过 NaN,剩余有效值算均值)
    betaquant.set_ctx(flags=betaquant.FLAG_SKIP_NAN)
    data_nan = np.array([1, 2, np.nan, 4, 5, 6, 7, 8, 9, 10], dtype=np.float64)
    result = betaquant.ts_ma(data_nan, 3)
    # [1.   1.5   nan 3.   4.5  5.   6.   7.   8.   9. ]
    # i=2 当前是 NaN ⇒ NaN;i=3 窗口 [2,NaN,4] valid [2,4] mean=3.0;
    # i=4 窗口 [NaN,4,5] valid [4,5] mean=4.5;之后窗口无 NaN,恢复正常。
    

命名规范

  • 时序算子(rolling-window)以 ts_ 开头:ts_mats_sumts_deltats_rank
  • 截面算子(cross-sectional,跨 group)以 cc_ 开头:cc_rankcc_zscorecc_neutralize
  • 元素级算子(max/min/abs/log/sign 等)无前缀

数据布局:扁平化的一维数组 [stock1_day1, stock1_day2, ..., stockN_dayM],先按 securityid 再按 tradetime 排序。groups 参数告诉算子库每只股票的数据从哪里开始。

因子表达式 → Python 代码

使用 lang 模块把因子表达式(GTJA / WQ101 风格的 DSL)转成 Python 代码:

python -m betaquant.lang examples/wq101/alpha101.txt > factors.py

会读取 examples/wq101/alpha101.txt 中的因子表达式, 生成对应的、调用 betaquant 的 Python 代码。

跑生成的因子:

import betaquant
from factors import alpha_001

# 用合成面板做最小可运行例子;自己的数据用 polars.DataFrame 传入也行
data = betaquant.make_synthetic_panel(securities=50, trades=252)
ctx = betaquant.ExecContext(data)   # 自动推断 groups
result = alpha_001(ctx)

转译完成后可能仍需手动调整:

  • 修正 floatbool 之间的类型转换
  • 按需添加上下文设置

完整示例

GTJA Alpha 191

国泰君安 Alpha 191 因子集,190 / 191 已实现,见 examples/gtja191/

python examples/gtja191/main.py

默认用 betaquant.make_synthetic_panel() 生成 50 股 × 252 天的合成面板,跑全部因子并打印 绩效统计。要换成自己的数据,直接调用 examples.gtja191.al.run(data=<polars.DataFrame>, alphas=[1, 2, 3])

WorldQuant Alpha 101

完整实现 101 Formulaic Alphas,见 examples/wq101/

  • al/ — betaquant 实现(Rust 后端)
python examples/wq101/main.py

默认用合成数据跑全部 101 个因子。要换成自己的数据,编辑 wq101/main.py 顶部的 DATA_FILE 常量、或直接调用 examples.wq101.al.run(data_path=...) / run(data=<polars.DataFrame>)

已支持的算子

完整函数签名与说明:python/betaquant/algo.md

入门示例

examples/quickstart/ 下放了几个最小可运行示例:

  • usage.py —— 演示 set_ctx、各种 flag 与常见时序/截面算子
  • rank.py —— 截面 rank 与 pandas 对比
  • verify_sumif.py —— ts_sumif 行为验证
  • full_demo.py —— 从 long-format DataFrame → matrix_transformExecContext → 因子计算 → 与 pandas 对照的端到端例子
python examples/quickstart/usage.py

开发

环境要求:

  • Rust(最新 stable)
  • Python 3.11+
  • maturin
# 编译并以开发模式安装
maturin develop --release
cargo build --release
# 运行 Rust 单元测试
cargo test

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

betaquant-0.6.3.tar.gz (190.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

betaquant-0.6.3-cp311-abi3-win_amd64.whl (823.4 kB view details)

Uploaded CPython 3.11+Windows x86-64

betaquant-0.6.3-cp311-abi3-musllinux_1_2_x86_64.whl (811.4 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

betaquant-0.6.3-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (811.5 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

File details

Details for the file betaquant-0.6.3.tar.gz.

File metadata

  • Download URL: betaquant-0.6.3.tar.gz
  • Upload date:
  • Size: 190.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for betaquant-0.6.3.tar.gz
Algorithm Hash digest
SHA256 b8b26cf1dd9b2a32331439e2a24fbae1ced59459bba930f8f69496b1f3f39fd7
MD5 2d79e0084770150db4ef59ddd5337e77
BLAKE2b-256 fa4a6ae9cb0e0739abb10fba1998efefdb6ad6552527f72a2528f411a33b3f0e

See more details on using hashes here.

File details

Details for the file betaquant-0.6.3-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: betaquant-0.6.3-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 823.4 kB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for betaquant-0.6.3-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 fc5bfa8848045b71fc718af7a435c23fb55afed206e18d21a128f66e1da822b2
MD5 3a2b45ee190470839a9a003281f56ee2
BLAKE2b-256 7e4b88a639113ebe94fc43b6dad7f686e8de5a91d060d6ecc0a3a56fc3ae473a

See more details on using hashes here.

File details

Details for the file betaquant-0.6.3-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for betaquant-0.6.3-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ff533d1fbdc7bb5221ffc20af1b337aa218bbb521b87d0a56e1ddfe209637306
MD5 05893cd3ee8635d812c85d6c82408e0e
BLAKE2b-256 62410e91a6e2ccbe1110c430f5ab2a26ec08bedf48280ba50b9bfcec9ff974fa

See more details on using hashes here.

File details

Details for the file betaquant-0.6.3-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for betaquant-0.6.3-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f043899198fac8655d898f8fb6be66f0ff06669213e52127715e67aa0f912fe3
MD5 b47f97ed2ee2a8767370fe131f502a0d
BLAKE2b-256 e0c2381caee2d27911402f07e9937fd9535151fc6b48d6c818909dc63fde32e5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page