116 lines
3.4 KiB
Python
116 lines
3.4 KiB
Python
"""
|
||
财务因子模块
|
||
包含基于股票截面的财务因子实现
|
||
"""
|
||
|
||
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) |