Skip to main content

Silars

Silars 是基于 Polars 的因子分析与回测工具库,提供数据预处理、组合权重、策略和回测入口。

安装

Silars 需要 Python 3.12 或更高版本;CI 持续验证 Python 3.12 和 3.13。

pip install silars

使用 uv:

uv add silars

最小示例

下面按每个 (date, time) 截面选择得分最高的两个资产,并生成等权组合:

from copy import deepcopy

import polars as pl

from silars.alphalens import top_k

scores = pl.DataFrame(
    {
        "date": ["2026-01-02"] * 3,
        "time": ["09:31:00"] * 3,
        "asset": ["A", "B", "C"],
        "score": [0.2, 0.8, 0.5],
    }
)

selector = deepcopy(top_k).set_params(num=2)
weights = selector.transform(scores)
print(weights.select("date", "time", "asset", "target_weight"))

主要入口

  • Preprocessor 及预处理函数:因子清洗、标准化和中性化。
  • top_k、qcut、MFEs / MFEConfig:组合权重生成。
  • Strategy、FactorStrategy:策略编排。
  • BacktestEngine、bt:回测。
  • Zoo、zoo:因子数据工作区。

这些入口均从 silars.alphalens 导入。

MFEs 的行业、板块、个股和风格偏离均相对完整输入基准;Zoo.mfe 使用 挂载的风险基准。候选过滤和缺分只限制可买入资产,不重算基准。 启用基准约束时,基准总权重必须为正,基准成分必须有完整的对应风险暴露; 标量风格约束要求至少一列 *Barra。求解不可行、后验校验失败或建仓后 没有可选资产会抛错,不再沿用旧权重。约束验收针对目标权重,实际成交持仓 仍受涨跌停、停牌和回测执行规则影响。

归因主账的行业、风格贡献使用全样本平均暴露:组合、基准分别按每个日内区间、 每个行业或风格因子求平均暴露,乘以当期因子收益,并沿用原收益链接。行业暴露 就是行业持仓权重,零持仓参与均值;缺行业系数的区间不补零。pure_alpha 为实际 主动收益减去市场、平均行业和平均风格贡献,四项直接闭合;扩大样本窗口会重算 平均暴露及历史分账。暴露字段和风格暴露图仍展示实际持仓暴露。

Zoo.attribution 默认追加原始风险账本的风格收益预测诊断:只用过去 252 期 因子收益均值,对照实际变化暴露下的预测贡献与预测误差,不重复计入四项主账。 用 style_forecast_window=60 调整窗口,或传 None 关闭;Zoo.mfe 对应参数为 attribution_style_window。窗口必须为至少 2 的整数。 预测对应贡献不是净 Alpha,也不是可直接投资的收益。风险暴露必须在被解释 区间起点已知;隔夜归因不能使用开盘后才得到的风险信息。

归因遇到基准股票的 VWAP 无成交价时,先复用同键交易账本或已挂载的 valuation.close;两者均缺失且无法按全天平价规则估值时,默认按缺失的 (date, time, asset) 从已有 DC 股票分钟缓存只读获取 close。原 zoo.mfe(...) 无需 额外挂载或参数。该值只补归因区间估值,不改变交易价格、持仓或基准权重。 非 DC 行情可通过 valuation_price_col 显式指定自己的同键估值列;显式指定后 不会另换数据源。缓存或估值仍缺失、非有限或非正时继续报错,不补算缓存, 也不用日收盘倒填早盘。

研究期 tree shortlist

silars.feature_selection.select_features 用固定的单特征浅树,按独立验证期的每日 prediction RankIC 对已物化数值特征做粗筛:

from silars.feature_selection import select_features

ranking = select_features(
    train,
    valid,
    feature_names,
    "forward_return",
    max_features=100,
)

它衡量的是 tree(feature) 对下游模型的排序潜力,不是原始特征 RankIC、独立 OOS、 显著性结论或可直接传给 MFEs 的 score。PIT、purge/embargo 和后续使用边界由 调用方保证。该入口也不同于 silars.alphalens.evaluate.select_features 的多重检验与相关性筛选。

同一模块也可以把一组显式特征通过一棵相同参数的浅树融合为 predict 区间的新特征:

from silars.feature_selection import fuse_features

fused = fuse_features(
    train,
    valid,
    ["feature_a", "feature_b", "feature_c"],
    target="forward_return",
    output_name="tree_fusion",
)
valid = valid.with_columns(fused["tree_fusion"])

该入口只返回 predict prediction,不返回模型或 train in-sample prediction。若输入 特征是利用同一 predict 区间的 target 选出的,结果仍有 post-selection bias,不是 独立 OOS;完整历史融合列应由调用方 walk-forward/cross-fit 生成。

若 valid 含 target,可用同一棵 train-only 树得到一行 holdout 摘要及可直接执行的 Polars 表达式:

from silars.feature_selection import evaluate_fusion

report = evaluate_fusion(
    train,
    valid,
    ["feature_a", "feature_b", "feature_c"],
    target="forward_return",
    output_name="tree_fusion",
)

expression = report.item(0, "expression")
valid = valid.with_columns(expression)

# 可持久化并交给另一个进程 / Dataset
lidb_expression = report.item(0, "lidb_expression")

返回列为 feature、source_features、model_rank_ic_mean、 model_rank_icir、expression、lidb_expression。expression 是当前进程可直接 执行的 pl.Expr;lidb_expression 是同一棵树生成的 LiDB/QDF 三元表达式字符串, 格式如 ((feature_a<=0.5)?(0.1):(0.2)) as tree_fusion,可持久化并由另一个进程 转成 Dataset。融合树的输入和输出统一量化为 6 位小数,表达式中的 threshold 与 leaf value 也最多保留 6 位小数。这里只能证明 train/valid 时间分离;PIT、label 实现时点、 purge/embargo、valid 前冻结特征集合且未重复使用 valid 选 winner 均由调用方保证。 holdout 审查只调用 evaluate_fusion,未来预测再选择 fuse_features 或冻结 expression,避免对同一区间重复 fit。

大量显式组合应一次交给批量入口,避免循环调用 evaluate_fusion 重复准备公共数据:

from itertools import product

import polars as pl

from silars.feature_selection import evaluate_fusions

groups = product(features_a, features_b)
ranking = evaluate_fusions(
    train,
    valid,
    groups,
    target="forward_return",
    output_prefix="tree_fusion",
    min_rank_ic=0.03,
    n_jobs=7,
)

expressions = (
    ranking.filter(pl.col("selected")).get_column("expression").to_list()
)
predict = predict.with_columns(expressions)

portable_ranking = ranking.drop("expression")
portable_ranking.write_parquet("fusion_ranking.parquet")

组合按输入顺序稳定命名为 tree_fusion_00000、tree_fusion_00001 等;组内特征名 排序,规范化后重复的组合会在首次 fit 前报错。公共 row-domain、target ranks、 sample weights 和特征值校验只准备一次,每组只保留自己的小型 Float32 矩阵。 只有通过 min_rank_ic 的行保存两种表达式,其余为 null。Object 列不能写 Parquet;持久化排名时只需移除 expression,lidb_expression 可直接保留。

另一个进程加载源 Dataset 后,可把筛选出的字符串直接交给 LiDB:

import lidb
import polars as pl
from lidb import dataset

selected = pl.read_parquet("fusion_ranking.parquet").filter(pl.col("selected"))
SOURCE_FEATURES = sorted(
    {feature for group in selected["source_features"] for feature in group}
)
LIDB_EXPRESSIONS = tuple(
    selected
    .get_column("lidb_expression")
    .drop_nulls()
)


@dataset(ds_feature_source)
def ds_tree_fusions(depend: pl.LazyFrame):
    prepared = depend.with_columns(
        pl.col(SOURCE_FEATURES).cast(pl.Float64).round(6).cast(pl.Float32)
    )
    return lidb.from_polars(prepared).sql(*LIDB_EXPRESSIONS)

源 Dataset 必须提供 source_features 中完全相同的列名;表达式版本变化时应同步 更新 Dataset 的稳定版本名,避免复用旧缓存。LiDB 不支持的列名或输出名不会被猜测 转义,对应 lidb_expression 返回 null,当前进程的 pl.Expr 仍然可用。源特征在 进入 LiDB 前必须使用相同的 round(6) -> Float32 预处理,否则不保证与评估结果 一致。

批量入口使用 ygo 的 threading backend 并行各组合,线程共享只读的 train/valid 和公共统计状态,不复制整张 DataFrame。n_jobs 必须为正整数,实际 worker 数不会超过组合数;外层已经并发或内存受限时传 n_jobs=1。

批量筛选会把 valid 变成 selection set;无论筛选多少行,它都不再是独立 OOS。 筛出的表达式必须在未参与组合筛选的后续 predict/test 区间验证。

基准对冲回测

对已加载的 Zoo,可复用原多头回测并得到 1:1 对冲收益。传入指数代码时读取对应 指数日收益:

from silars.alphalens import FactorStrategy, zoo

results = zoo.hedge(
    ["KMID"],
    FactorStrategy(),
    index_code="000300",
    times=["09:31:00", "10:00:00"],
)
print(results["KMID"]["ret"])
print(results["KMID"]["metric"])

hedge() 会立即完成回测,并返回每个因子的 pos、ret、figure 和对冲组合 metric,不是延迟任务生成器;show=False 可跳过主动展示。

index_code="" 时不读取指数,直接从回测输入的 prev_close/open/close 构造等权市场 日收益,结果列为 mkt 和 long-mkt。指数路径运行时需要当前环境可导入 dc.data.base.ds_index_retC2C;period 仅控制原组合持仓周期,不缩放日度基准收益。

许可证

Silars 使用 MIT License。silars/empyrical 包含 Apache-2.0 许可的第三方代码,详见 THIRD_PARTY_NOTICES.md 和 LICENSES/Apache-2.0.txt。

Metadata

Release files for silars 2026.9.22.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for silars 2026.9.22.1
File Size Uploaded
silars-2026.9.22.1.tar.gz 357.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for silars 2026.9.22.1
File Interpreter ABI Platform
silars-2026.9.22.1-py3-none-any.whl Python 3 none any Details

Total release size: 529.1 kB

Release files / silars-2026.9.22.1.tar.gz

Download URL silars-2026.9.22.1.tar.gz
Size 357.7 kB
Tags Source
SHA-256 checksum
How to use checksums
3b020a3190aecb9d46404bef8441354cab68867ad3c2d58e5d1fdfc4bc95285b
BLAKE2b-256 checksum
How to use checksums
90c9fe787c55edae6aa7180138564df259f0ffd8bd5bd5e5aa6c8a0aa28ab35a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / silars-2026.9.22.1-py3-none-any.whl

Download URL silars-2026.9.22.1-py3-none-any.whl
Size 171.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a372187ce08f59ff16e24d7daff563b5c6147dfdd47af930180f56fc753ac13e
BLAKE2b-256 checksum
How to use checksums
af466dd5ced5063e765f025510b45abcd7dfcf0124e398f205d466051067418e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

2026.9.22.1 This release

2 release files

1.3.5

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.9

2 release files

1.2.8

2 release files

1.2.7

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.25

2 release files

1.1.24

2 release files

1.1.23

2 release files

1.1.22

2 release files

1.1.21

2 release files

1.1.20

2 release files

1.1.19

2 release files

1.1.18

2 release files

1.1.17

2 release files

1.1.16

2 release files

1.1.15

2 release files

1.1.14

2 release files

1.1.13

2 release files

1.1.12

2 release files

1.1.11

2 release files

1.1.10

2 release files

1.1.9

2 release files

1.1.8

2 release files

1.1.7

2 release files

1.1.6

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.47

2 release files

1.0.46

2 release files

1.0.45

2 release files

1.0.44

2 release files

1.0.43

2 release files

1.0.42

2 release files

1.0.41

2 release files

1.0.40

2 release files

1.0.39

2 release files

1.0.38

2 release files

1.0.37

2 release files

1.0.36

2 release files

1.0.35

2 release files

1.0.34

2 release files

1.0.33

2 release files

1.0.32

2 release files

1.0.31

2 release files

1.0.30

2 release files

1.0.29

2 release files

1.0.28

2 release files

1.0.27

2 release files

1.0.26

2 release files

1.0.25

2 release files

1.0.24

2 release files

1.0.23

2 release files

1.0.22

2 release files

1.0.21

2 release files

1.0.20

2 release files

1.0.19

2 release files

1.0.18

2 release files

1.0.17

2 release files

1.0.16

2 release files

1.0.15

2 release files

1.0.14

2 release files

1.0.13

2 release files

1.0.12

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page