""" 财务因子模块 包含基于股票截面的财务因子实现 """ import numpy as np import polars as pl from main.factor.operator_framework import DateWiseFactor, StockWiseFactor class CashflowToEVFactor(StockWiseFactor): """现金流-to-企业价值因子""" def __init__(self): super().__init__( name="cashflow_to_ev", parameters={}, required_factor_ids=["n_cashflow_act", "total_liab", "money_cap", "total_mv"] ) def calc_factor(self, group_df: pl.DataFrame) -> pl.Series: # 计算企业价值 total_mv = group_df["total_mv"] total_liab = group_df["total_liab"] money_cap = group_df["money_cap"] # 企业价值 = 市值 + 负债合计 - 货币资金 enterprise_value = total_mv + total_liab - money_cap # 计算现金流-to-EV比率 n_cashflow_act = group_df["n_cashflow_act"] cashflow_ev_ratio = n_cashflow_act / (enterprise_value + 1e-8) # 避免除零 return cashflow_ev_ratio.alias(self.factor_id) class BookToPriceFactor(StockWiseFactor): """账面价值-to-价格因子""" def __init__(self): super().__init__( name="book_to_price", parameters={}, required_factor_ids=["bps", "close"] ) def calc_factor(self, group_df: pl.DataFrame) -> pl.Series: # 计算账面价值-to-价格比率 bps = group_df["bps"] close = group_df["close"] book_to_price = bps / (close + 1e-8) # 避免除零 return book_to_price.alias(self.factor_id) class DebtToEquityFactor(StockWiseFactor): """资产负债率因子""" def __init__(self): super().__init__( name="debt_to_equity", parameters={}, required_factor_ids=["total_liab", "equity"] ) def calc_factor(self, group_df: pl.DataFrame) -> pl.Series: # 计算资产负债率 total_liab = group_df["total_liab"] equity = group_df["equity"] debt_to_equity = total_liab / (equity + 1e-8) # 避免除零 return debt_to_equity.alias(self.factor_id) class ProfitMarginFactor(StockWiseFactor): """净利润率因子""" def __init__(self): super().__init__( name="profit_margin", parameters={}, required_factor_ids=["net_profit", "revenue"] ) def calc_factor(self, group_df: pl.DataFrame) -> pl.Series: # 计算净利润率 net_profit = group_df["net_profit"] revenue = group_df["revenue"] profit_margin = net_profit / (revenue + 1e-8) # 避免除零 return profit_margin.alias(self.factor_id) class BMFactor(StockWiseFactor): """账面市值比(Book-to-Market, BM)因子""" def __init__(self): super().__init__( name="bm", parameters={}, required_factor_ids=["total_hldr_eqy_exc_min_int", "total_mv"] ) def calc_factor(self, group_df: pl.DataFrame) -> pl.Series: book_value = group_df["total_hldr_eqy_exc_min_int"] market_cap = group_df["total_mv"] bm = book_value / (market_cap + 1e-8) # 可选:过滤无效值(如负权益) # bm = pl.when((book_value > 0) & (market_cap > 0)).then(bm).otherwise(None) return bm.alias(self.factor_id)