Files
sanguo_vnpy_v2/sanguo_factor/fundamental_library.py
T
claude_dev 66619c17d8 feat(factor): P1-B批library注册6因子(四新域5因子+D14双注册) [nas]
fund_ccc(-)/fund_send_total_12m(不定正向注册待实证)/fund_gdhs_chg(-)/
fund_topholder_chg(+)/fund_ep_vb(+)/fund_bp_vb(+);注册总数 69→75
(P0 32+P1 37+P1-B 6,既有计数契约同步更新);batch e2e 锁死 vb+dividend
域级引用瘦身 join 路径。
2026-09-09 12:12:00 +08:00

156 lines
9.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""财务因子批表达式库: P0 32 + P1 37 + P1-B 6 注册(category="fundamental").
选型来源 docs/fundamental_factor_survey_20260907.md(§3 候选池 96 个 + §4.1 去重),
首批 32 = P0 50 个按族去重后的主代表;全部「因子 = cs_rank(基础指标)」一层截面,
负 IC 因子表达式取负(统一高=好,与量价批 IC 口径一致;原始方向见下表)。
基础指标列由 fundamental_adapter.build_fundamental_features 产出并 join 到
alpha_df;估值族市值 = close × share_capital 自算(三表股本,规避 valuation
中文列名表,PIT 口径与报表一致)。
P0 32 因子名单(编号=调研文档 §3):
A 盈利能力(7): A01 ROE / A02 扣非ROE / A04 ROA / A05 GP/A(族主代表) /
A06 毛利率 / A07 净利率 / A13 CFO/TA
B 盈利质量(7): B01 TACC(Sloan,族核心) / B04 非经常占比 / B05 减值冲击 /
B07 投资收益依赖 / B08 应收异常 / B10 销售收现率 / B11 其他应收占比
C 成长(6): C01 营收单季同比 / C02 净利单季同比 / C09 增速剪刀差 /
C10 ΔGM(副代表) / C12 ΔROE / C15 资产增速(投资-融资群代表)
D 估值(4): D01 EP_TTM / D03 扣非EP(A股特色) / D04 BP / D06 CP(CNE5 CETOP)
E 资本结构/行为(4): E01 NSI 净股票发行 / E02 股权融资强度 / E05 有息负债率 /
E09 商誉占比
F 预期事件(4): F01 SUE(净利,Foster) / F02 SUE(营收) / F04 预告类型分 /
F05 预告幅度
同族被裁变体(A03/A08/A09/A10/A12/B02/B06/C03/C04/C05/C06/D02/D05/E04 等)
在 P1 或互证后再议,见文档 §4。
"""
from .registry import register_factor, _REGISTRY
# (name, expression, 文档编号, 原始 IC 方向)
FUNDAMENTAL_FACTORS: list[tuple[str, str, str, str]] = [
# ---- A 盈利能力(7) ----
("fund_roe_ttm", "cs_rank(roe_ttm)", "A01", "+"),
("fund_roe_deduct_ttm", "cs_rank(roe_deduct_ttm)", "A02", "+"),
("fund_roa_ttm", "cs_rank(roa_ttm)", "A04", "+"),
("fund_gp_over_assets", "cs_rank(gp_over_assets)", "A05", "+"),
("fund_gross_margin", "cs_rank(gross_margin)", "A06", "+"),
("fund_net_margin", "cs_rank(net_margin)", "A07", "+"),
("fund_cfo_over_assets", "cs_rank(cfo_over_assets)", "A13", "+"),
# ---- B 盈利质量(7) ----
("fund_tacc", "cs_rank(-tacc)", "B01", "-"),
("fund_nonrec_ratio", "cs_rank(-nonrec_ratio)", "B04", "-"),
("fund_impairment_ratio", "cs_rank(-impairment_ratio)", "B05", "-"),
("fund_invest_income_dep", "cs_rank(-invest_income_dep)", "B07", "-"),
("fund_receivables_anomaly", "cs_rank(-receivables_anomaly)", "B08", "-"),
("fund_sales_cash_ratio", "cs_rank(sales_cash_ratio)", "B10", "+"),
("fund_other_rece_ratio", "cs_rank(-other_rece_ratio)", "B11", "-"),
# ---- C 成长(6) ----
("fund_rev_q_yoy", "cs_rank(rev_q_yoy)", "C01", "+"),
("fund_np_q_yoy", "cs_rank(np_q_yoy)", "C02", "+"),
("fund_growth_scissors", "cs_rank(growth_scissors)", "C09", "+"),
("fund_gm_delta", "cs_rank(gm_delta)", "C10", "+"),
("fund_roe_delta", "cs_rank(roe_delta)", "C12", "+"),
("fund_asset_growth", "cs_rank(-asset_growth)", "C15", "-"),
# ---- D 估值(4) ----
("fund_ep_ttm", "cs_rank(np_ttm / (close * share_capital))", "D01", "+"),
("fund_ep_deduct_ttm", "cs_rank(dnp_ttm / (close * share_capital))", "D03", "+"),
("fund_bp", "cs_rank(equity / (close * share_capital))", "D04", "+"),
("fund_cp", "cs_rank(cfo_ttm / (close * share_capital))", "D06", "+"),
# ---- E 资本结构/行为(4) ----
("fund_nsi", "cs_rank(-nsi)", "E01", "-"),
("fund_equity_fin_intensity",
"cs_rank(-(acc_invest_cash_ttm / (close * share_capital)))", "E02", "-"),
("fund_ibd_ratio", "cs_rank(-ibd_ratio)", "E05", "-"),
("fund_goodwill_ratio", "cs_rank(-goodwill_ratio)", "E09", "-"),
# ---- F 预期事件(4) ----
("fund_sue_np", "cs_rank(sue_np)", "F01", "+"),
("fund_sue_rev", "cs_rank(sue_rev)", "F02", "+"),
("fund_forecast_type", "cs_rank(forecast_type_score)", "F04", "+"),
("fund_forecast_change", "cs_rank(forecast_change_pct)", "F05", "+"),
]
# P1 批第二批(35 因子 + 2 互评变体;编号 = 调研文档 §3,IC 列为文档预期原始方向,
# 负 IC 表达式取负统一「高=好」;IC「不定」按正向注册待实证)。
# 口径登记: EBIT=TP+利息费用(未披露按 0) / DA=四件折旧摊销 / τ 截断[0,0.5]缺 0.25 /
# IBD 含 LEASE_LIAB / VSIG 16 季 sample std / B12 为哑变量连续近似乘积 /
# F07 锚 = max(披露日, 预告公告日)——详见 fundamental_adapter 注释。
FUNDAMENTAL_P1_FACTORS: list[tuple[str, str, str, str]] = [
# ---- A 盈利能力 P1(7) ----
("fund_roe_avg", "cs_rank(roe_avg)", "A03", "+"),
("fund_roa_pretax", "cs_rank(roa_pretax)", "A09", "+"),
("fund_ebit_over_assets", "cs_rank(ebit_over_assets)", "A10", "+"),
("fund_ebitda_margin", "cs_rank(ebitda_margin)", "A11", "+"),
("fund_roic", "cs_rank(roic)", "A12", "+"),
("fund_rd_intensity", "cs_rank(rd_intensity)", "A15", "不定"),
("fund_sale_expense_ratio", "cs_rank(-sale_expense_ratio)", "A16", "-(弱)"),
# ---- B 盈利质量 P1(8) ----
("fund_inventory_anomaly", "cs_rank(-inventory_anomaly)", "B09", "-(弱)"),
("fund_cash_ibd_double", "cs_rank(-cash_ibd_product)", "B12", "-"),
("fund_vsig", "cs_rank(-vsig)", "B13", "-"),
("fund_vsig_acc", "cs_rank(-vsig_acc)", "B14", "-"),
("fund_vsig_cfo", "cs_rank(-vsig_cfo)", "B15", "-"),
("fund_da_intensity", "cs_rank(da_intensity)", "B16", "不定"),
("fund_gm_nm_scissors", "cs_rank(-gm_nm_scissors)", "B18", "-(弱)"),
("fund_profit_streak", "cs_rank(profit_streak)", "B19", "+"),
# ---- C 成长 P1(8) ----
("fund_np_accel", "cs_rank(np_accel)", "C07", "+"),
("fund_rev_accel", "cs_rank(rev_accel)", "C08", "+"),
("fund_nm_delta", "cs_rank(nm_delta)", "C11", "+"),
("fund_rev_cagr5", "cs_rank(rev_cagr5)", "C13", "+"),
("fund_np_cagr5", "cs_rank(np_cagr5)", "C14", "+"),
("fund_nwc_growth", "cs_rank(-nwc_growth)", "C16", "-"),
("fund_invest_growth", "cs_rank(-invest_growth)", "C18", "-"),
("fund_equity_growth", "cs_rank(equity_growth)", "C19", "不定"),
# ---- D 估值 P1(6;EV = close×share_capital + ev_ex_mv(=IBDMON)) ----
("fund_ebit_over_ev", "cs_rank(ebit_ttm / (close * share_capital + ev_ex_mv))", "D07", "+"),
("fund_ebitda_over_ev", "cs_rank(ebitda_ttm / (close * share_capital + ev_ex_mv))", "D08", "+"),
("fund_gp_over_m", "cs_rank(gp_ttm / (close * share_capital))", "D09", "+"),
# D12 非 alpha: 中性化控制变量(§3.4——财务估值因子上线必配 size 中性化)
("fund_ln_mv", "cs_rank(log(close * share_capital))", "D12", "控制变量"),
("fund_forward_ep", "cs_rank(forecast_np_annualized / (close * share_capital))", "D13", "+"),
("fund_fcf_over_ev", "cs_rank(fcf_ttm / (close * share_capital + ev_ex_mv))", "D15", "+"),
# ---- E 资本结构与行为 P1(3) ----
("fund_debt_issue", "cs_rank(-(debt_issue_ttm / (close * share_capital)))", "E03", "-"),
("fund_interest_cover", "cs_rank(interest_cover)", "E07", "+"),
("fund_goodwill_growth", "cs_rank(-goodwill_growth)", "E10", "-(弱)"),
# ---- F 预期事件 P1(3) ----
("fund_sue_eps", "cs_rank(sue_eps)", "F03", "+"),
("fund_disclosure_speed", "cs_rank(disclosure_speed)", "F06", "早=+"),
("fund_forecast_beat", "cs_rank(forecast_beat)", "F07", "高兑现=+"),
# ---- 互评变体(2) ----
# SUE 严窗: σ 只用 t−1 及更早差分(不含当期),与 F01 对照
("fund_sue_np_strict", "cs_rank(sue_np_strict)", "F01v", "+"),
# 资产增长负向对照: 原始方向(Cooper 2008 学术预期负 IC),与 C15 取负版互证
("fund_asset_growth_neg", "cs_rank(asset_growth)", "C15v", "学术负IC对照"),
]
# P1-B 批(四新域 6 注册 = 5 因子,D14 EP/BP 双注册;编号 = 调研文档 §3)。
# 口径登记: E08 CCC 三表自算(均值=t 与 t4 期末平均,COGS=OPERATE_COST TTM,
# 金融股置 NaN)/ E11 365 天滚动窗开区间下界,PIT 回退链
# dividPlanAnnounceDate→PreNotice→AgmPum→Plan / E12 相邻事件 Δln(公告日 asof,
# 不用「增减比例」列)/ E13 法定披露截止 PIT(Q1→04-30/H1→08-31/Q3→10-31/
# 年报→次年04-30) / D14 vb 长史(1990 起含退市,2026 缺口 ak 补)分域验证用
# ——详见 fundamental_adapter 注释。
FUNDAMENTAL_P1B_FACTORS: list[tuple[str, str, str, str]] = [
# ---- E 资本结构/行为 P1-B(4) ----
("fund_ccc", "cs_rank(-ccc)", "E08", "-(弱)"),
# E11 方向不定(公告前+/除权后−混合)→ 正向注册,由 IC 实测定去留
("fund_send_total_12m", "cs_rank(send_total_12m)", "E11", "不定"),
("fund_gdhs_chg", "cs_rank(-gdhs_chg)", "E12", "-"),
("fund_topholder_chg", "cs_rank(topholder_chg)", "E13", "+"),
# ---- D 估值 P1-B(D14 双注册;vb 域长史分域验证,2017 前后须分域报 IC) ----
("fund_ep_vb", "cs_rank(ep_vb)", "D14", "+"),
("fund_bp_vb", "cs_rank(bp_vb)", "D14", "+"),
]
def _register_all() -> None:
"""注册全部财务因子(已存在同名跳过,幂等;同 library.py 模式)."""
batches = [*FUNDAMENTAL_FACTORS, *FUNDAMENTAL_P1_FACTORS, *FUNDAMENTAL_P1B_FACTORS]
for name, expression, _doc_id, _ic in batches:
if name not in _REGISTRY:
register_factor(name, expression, category="fundamental")
# 模块导入时自动注册(与 library.py/alpha_datasets.py 同一模式)
_register_all()