跳转至


课程  因子投资  机器学习  Python  Poetry  ppw  tools  programming  Numpy  Pandas  pandas  算法  hdbscan  聚类  选股  Algo  minimum  numpy  algo  FFT  模式识别  配对交易  GBDT  LightGBM  XGBoost  statistics  CDF  KS-Test  monte-carlo  VaR  回测  过拟合  algorithms  machine learning  strategy  python  sklearn  pdf  概率  数学  面试题  量化交易  策略分类  风险管理  Info  interview  career  xgboost  PCA  wavelet  时序事件归因  SHAP  Figures  Behavioral Economics  graduate  arma  garch  人物  职场  Quantopian  figure  Banz  金融行业  买方  卖方  story  量化传奇  rsi  zigzag  穹顶压力  因子  ESG  因子策略  投资  策略  pe  ORB  Xgboost  Alligator  Indicator  factor  alpha101  alpha  技术指标  wave  quant  algorithm  pearson  spearman  tushare  因子分析  Alphalens  涨停板  herd-behaviour  momentum  因子评估  review  SMC  聪明钱  trade  history  indicators  zscore  波动率  强化学习  顶背离  freshman  resources  others  AI  DeepSeek  network  量子计算  金融交易  IBM  weekly  LLT  backtest  backtrader  研报  papers  UBL  quantlib  jupyter-notebook  scikit-learn  pypinyin  qmt  xtquant  blog  static-site  duckdb  工具  colors  free resources  barra  world quant  Alpha  openbb  数据  risk-management  llm  prompt  CANSLIM  Augment  arsenal  copilot  vscode  code  量化数据存储  hdf5  h5py  cursor  augment  trae  Jupyter  jupysql  pyarrow  parquet  数据源  quantstats  实盘  clickhouse  notebook  redis  remote-agent  AI-tools  Moonshot  回测,研报,tushare 

readme


基本面量化系列(14):在手之鸟,红利优选策略-策略复现

一、复现思路

通过多因子策略构建量化回测系统,共构建4个筛选条件和9个因子,9个因子等权配置,对经过4个筛选条件筛选后的股票进行打分,最终筛选出得分最高的30只股票。。调仓频率:月度调仓。数据来源:Tushare、wind、baostock、聚宽等

二、因子体系介绍

4个筛选条件分别为:每期股息率排名前500(股息率定义为调仓日前12个月股息率,使用总分红金额/市值,考虑了多次分红的情况,这个方法可以不用再单独考虑股本变化的影响。股息率的定义参考了华泰证券的一篇研报)、连续两年分红、过去十年没有审计保留意见、市值大于50亿。9个因子分别是两年股息率均值因子(dividend_yield_z)、净利润稳定性因子(net_profit_stability_z)、换手率因子(turnover_rate_z)、股东变化因子(holder_num_z)、ep因子(ep_signal)、bp因子(bp_signal)、派息率因子(dividend_yield_signal)、经营现金流资产比(opercashflow_to_assets_signal)、留存收益资产比(retained_earnings_to_assets_signal) 筛选条件 (1)每期股息率排名前500。调用Tushare数据的接口,输出字段dv_ttm,即股息率TTM=∑近12个月现金股利(税前)/指定日股票市值×100%(与wind中的股息率(近12个月)指标结果一样,用数据验证过)。每月调仓时,将股票的dv_ttm排名,筛选出前500只股票。湘财证券2025年3月25日的研报《高股息股票精选策略》中对于股息率的定义也是最近12个月内的现金分红/当前日股票市值。依据MSCI最新发布的中国权益市场风险模型TheBarra China Equity Model (CNE6),股息率因子(dividendto price ratio/DTOP)被定义为最近12个月的每股股息除以上个月月末的股价。东方财富计算股息率分母是用的是最近一个交易日总市值。考虑到数据的可获得性,本文将股息率定义为股息率_TTM=∑近12个月现金股利(税前)/最近一个交易日股票市值。通过调用Tushare数据接口pro.daily_basic可获取每日股息率_TTM,排序取前500只股票。 因为是每月末调仓,即每个月最后一个交易日调仓,使用的是倒数第二个交易日的数据。因此,将所有股票在回测区间的倒数第二个交易日的股息率TTM数据下载至本地保存,不用每次运行都访问Tushare,提高运行效率。

(2)连续两年分红 考察调仓日前两个财年是否连续分红。通过Tushare的pro.vidend接口,导出分红数据存储到本地。构建连续两年分红函筛选函数is_consecutive_dividend_stock(date),输入参数为调仓日date。设调仓日的月份为T,则调仓日晚于最新分红预案公告日(ann_date),则考察T-1和T-2是否连续分红。否则,考察T-2和T-3是否连续分红。只使用在调仓日已披露的数据,可以避免使用未来函数。连续两年分红输出结果为True,否则输出为False,输出的数据类型为DataFrame。

(4)市值大于50亿元筛选函数 每月最后一个交易日调仓,则需要获取倒数第二个交易日的数据。一是因为当天收盘之后,才会有当天股票的市值数据,要当天调仓执行股票买卖,只能使用前一个交易日的数据。另外,如果当天调仓使用当天的市值数据,会产生未来函数的问题。使用tushare数据daily_basic接口输出total_mv参数获得总市值数据,筛选大于50亿元的股票。因为一个月调仓一次,只获取调仓日前一个交易日的total_mv数据即可,可以大量减少不必要的数据。 (5)过去十年没有审计保留意见筛选函数 获取股票在调仓日(end_date)已公告的前十年的审计报告,筛选出十年全部为标准无保留意见的股票(剔除带强调事项段的无保留意见的股票,查看了曾经出具过此类审计报告的股票,很多被ST了,绝大部分股票在分红方面不具备优势,因此,应该被筛除),返回值为True,否则为False。使用Tushare数据fina_audit接口将审计数据下载至本地。

(2)在分红预案日和股东大会公告日之间的股票+1。这个因子比较简单,对于单只股票,给定回测时间,只需要判断回测日是否处于分红预案公告日和股东大会公告日之间。但数据获取难度比较大,tushare只有预案公告日,没有股东大会公告日。Wind、东方财富有预案公告日、股东大会公告日,但受制于试用账号限流,也拿不到数据。最终通过在咸鱼买到了聚宽的数据,取到了2018年-2023年的所有股票的分红信息,输出字段为股票代码、预案公告日、股东大会公告日。数据验证,通过与wind数据较差对比,抽查了部分数据,数据一致。但聚宽数据抓取了公告中所有与分红相关的内容,包括不分红的内容,数据清洗的难度比较大一些。本文使用的是聚宽的数据。 另外,还找到了baostock数据源可以提供分红预案公告日、股东大会公告日,且是开源免费的,但只能一次导出单只股票数据,通过先遍历每年所有股票,再遍历每一年,获得2018年-2023年所有股票分红信息。通过与wind数据交叉验证发现,数据的准确性一般,比如民生银行2018年的预案公告日,baostock上的日期为4月12日,而wind上的数据是3月30日。通过查看分红公告,3月30日、4月12日均有关于独立董事对上一年度利润分配的独立意见公告,wind抓取了较早的数据,而baostock抓取了较晚的数据,同样,还有风华高科2018年的预案公告日,baostock上的日期是4月28日,而wind上的数据是3月27日,查看公告具体内容,发现确实是3月27日已发布分红预案公告,但4月28日也发布了分红信息,两次发布的关于分红预案的信息均混同在其他公告日内容中,无法从公告标题上识别,咨询了wind客服,wind抓取的是较早发布预案公告的时间。综上看,还是wind的数据质量较高(因为较早发布预案公告日所提供的信息质量比较高,选股效果也会更好)。年度分红,基本在次年度3-4月份发布分红预案公告,绝大部分都是年度分红,年中分红、特殊分红非常少。

9个因子,等权配置,对每只股票打分

三、因子定义介绍

(1)两年股息率均值因子(dividend_yield_z) 采用过去两个财年股息率均值,例如,回测2023年的数据,则取2022年、2021年股息率均值。 年度股息率=年度每股股利之和/上个月末股价。年度若有多次分红,则将每股股利相加得到年度每股股利之和。上个月末股价指回测日的上个月末不复权收盘价。 在tushare数据pro.vidend接口中为end_date字段,绝大部分股票年度最后一次分红的end_date都是当年12月31日。实践中,采用年度每股股利之和/上个月末的股价的案例比较多,比如国泰君安研报《基于BarraCNE6的A股风险模型实践:风险因子篇》按上述方法定义股息率因子的。江海证券研报《股票多因子系列(二):基本面类因子实测》定义股息率因子为:过去 12个月每股分红/上月末股价(更倾向于股息率TTM的概念)。天风证券研报《因子跟踪周报:盈利、股东持股比例因子表现较好-20240525》中定义股息率为:最近年度分红/当前市值。可见,计算年度股息率,分子为年度每股股利之和,分母股价采用上个月末股价具备一定的参考性,本文也采用回测日上月末收盘价(不复权)。考虑到当年年度分红预案公告日集中在3、4月份,调仓日在4月30号(含)之前,使用上上年度的年度每股股利之和(如2022年3月30日回测,用的是2020年度每股股利之和/2021年2月28日收盘价),调仓日在4月30日以后,使用上一年度每股股利之和(如2022年5月30日回测,用的是2021年度每股股利之和/2022年4月30日收盘价)。计算前面连续两年股息率,然后求均值。这种算法虽然导致股息率有一定的滞后性,但很好的规避了未来函数问题(一般只有4月30日以后才能拿到上一年度分红数据),同时,本文中定义股息率因子(筛选排名前500的股票)的时候用的是股息率_TTM,弥补了年度股息率时效性滞后的缺陷。 (2)换手波动率因子 取过去20天换手率的波动率(参考东吴证券研报《因子方法论之一:基于日内模式的因子改进-以流动性因子为例》中定义流动性因子的时候也是考虑前20个交易日换手率,调仓频率为月度调仓。天风证券研报《因子跟踪周报:盈利、股东持股比例因子表现较好- 20240525》定义换手率因子时,窗口也是取的过去20个交易日)。本文中也是月度调仓,选用20天换手率波动率,具备合理性。属于连续性因子,直接取绝对数,后面对其标准化。 (3)股东数量变化因子 股东户数在时序上的变化,定义为(最近一期股东数据-过去4个季度数据均值)/过去4个季度数据的标准差,并取相反数。Tushare中股东人数是按季度披露的最近开源证券研报《扎堆效应的识别:以股东户数变动为例》定义股东户数因子时,选取4期(即过去4个季度数据)时,稳定性及RankICIR值最高。因此,本文也选取过去4个季度的数据因为股东数量越少,说明在吸筹,因此,取相反数。也属于连续性因子,直接取绝对数,后面对其标准化 (4)ep标准分因子 定义为pe_ttm的倒数(招商证券研报《估值因子的内涵与逻辑-基本面量化系列研究之一》中定义了估值因子pe_ttm。华泰证券系列研报《上周市场整体偏弱,估值因子亮眼》也定义了估值因子pe_ttm)。通过调用tushare数据接口daily_basic输出参数pe_ttm(若pe为负值,则数据为空,通过dropna过滤掉了)再取倒数。属于绝对数,也属于连续性因子,后面对其标准化。 (5)bp因子(研报的结尾并没提到使用这个因子,本文中也不使用) 直接取pb的倒数。取绝对数,也属于连续性因子,后面对其标准化。 (6)派息率因子 定义为:派息率_TTM=股息率_TTMPE_TTM。因为股息率_TTM=过去12个月的每股股息/当前股价,PE_TTM=当前股价/过去12个月的每股收益。则派息率_TTM=股息率_TTM当前股价/(当前股价/PE_TTM)=股息率_TTM*PE_TTM。股息率_TTM和PE_TTM均可以通过调用Tushare的daily_basic接口直接获得。属于离散型因子,排名前20%和后20%的赋值-1,其余取值1,无需标准化。 (7)经营现金流资产比因子 经营性现金流资产比=最近一期财报经营活动产生的现金流量净额/最近一期财报总资产。经营性现金流就是经营活动产生的现金流量净额,因为只有充裕的净现金才具备分红的条件。研报原文提到了经营性现金流比总资产,因此,分母使用总资产。根据研报原文图31-35,可以看出,经营性现金流资产比、自由现金流资产比、现金流资产比,其中经营性现金流资产比的选股单调性最好,未来每股分红均值group5是最高的,且稳定性是最强的。因此选用经营性现金流资产比这个因子。中银证券研报《基本面财报因子的构建框 架初探》中也分析了净经营现金流比总资产_TTM是比较有效的选股因子。因受限于数据获取难度(现有数据库无法直接获取单季度财报数据,后续考虑收费数据库或者通过写函数计算),本文暂时采用最近一期财报数据代替。 通过调用Tushare数据接口pro.cashflow_vip输出参数n_cashflow_act获取区间内所有报告期的经营活动产生的现金流量净额数据(包括季度、半年度、年度)调用Tushare数据接口pro.balancesheet_vip输出参数total_assets获取区间内所有报告期的总资产数据(包括季度、半年度、年度),去除重复数据,按end_date升序排列,取最后一个数据,即得到最近一期财报数据,并将现金流量数据、总资产数据按照ts_code(股票代码)、end_date(对应报告期)合并在一起,将二者相除,即得到经营现金流资产比(要注意,回测时应该使用已经披露的数据,不能使用未披露数据,否则会产生未来数据问题,如7月10号披露0630中报,6月30日回测的时候,就不能用0630中报数据,只能用0331季报数据)。该指标属于离散型因子,排名后20%的赋值-1,其余取值0,无需标准化。 (8)留存收益资产比因子 这个定义比较明确,等于留存收益/总资产=最近一期财报留存收益/总资产。通过调用Tushare数据的pro.balancesheet_vip接口,输出参数total_assets获得总资产(total_asset)。输出参数surplus_rese获取盈余公积数据,参数undistr_porfitretained_获取未分配利润数据,将二者相加得到留存收益数据(retained_earnings)。将数据按照公告日期ann_date排序,按照股票代码ts_code、报告期end_date去重,保留最后一个数据,即得到最新一期财报数据(最近一期财报有可能为季度、半年度、年度),用retained_earnings/ total_asset得到留存收益资产比因子。排名后20%的赋值-1,其余取值0,无需标准化。 (9)财务收益稳健性因子 研报原文正文中提到计算过去八期的净利润、营业收入和营业利润的标准分,构建财务收益稳健因子,但研报结尾因子合成是净利润业绩稳健。考虑到使用净利润、营业收入和营业利润更加综合,本文使用计算过去八期的净利润、营业收入和营业利润的标准分,构建财务收益稳健因子。构建方法是,通过Tushare数据调用pro.income接口,输出revenue(营业收入)、operate_profit(营业利润)、n_income_attr_p(不含少数股东损益的净利润)取过去两年,共8期财报,将每期标准化(减去最小值,除以最大值减去最小值),再计算三者的均值。 (10)较上一个月的分红金额TTM增长因子 此处指过去12个月累计分红金额的变化值,而非每月分红,累计12个月。分红是非常低频的数据,很多情况下可能12个月只有一次。比如回测日的月份为k,则考察k到k-12月累计分红与k-1月到k-13月累计分红变化。对于分红当月,具备一定的区分度,尤其3、4月份,为分红高峰期。而对于非分红月份,则区分度较低。使用Tushare数据pro.dividend接口,输出参数cash_div_tax(税前每股分红,预案公告日会有数据,而税后每股分红cash_div只有在实施阶段才有数据)获取每股分红数据。输出参数ann_date(预案公告日,通过对比tushare分红数据和上市公司公告内容、wind数据库中的分红信息,发现只有预案公告日ann_date是准确的,可以使用。股东大会公告日和实施日的日期与ann_date是同一天,显然是不准确的,没有使用价值)。通过ts_code、end_date、ann_date、cash_div_tax去重,相同日期的数据只留一条。然后筛选过去12个月内每股分红数据求和(dividend_ttm),再筛选过去1-13个月内每股分红数据并求和(pre_dividend_ttm),二者作差,dividend_ttm – pre_dividend>0,则记为1,否则记为0 (11)

四、复现结果及问题分析

最终复现结果是2016年-2024年,策略年化收益率约14%,与研报中差距较大。可能原因如下:(1)研报中,在分红预案日和股东大会公告日之间的股票、较上一个月的分红金额TTM增长的股票,在回测中这两个因子没有考虑进去。tushare数据库中,只有分红预案日数据,没有股东大会公告日数据,因此,没法生成这个因子。较上个月的分红金额TTM增长,股票的分红是离散型变量而非连续型变量,且一年分红的次数也不会太多,如过用分红金额TTM增长来作为一个因子,没有太大意义,如果用分红/股价的TTM值,那就是股息率了,因此,也没有考虑这个因子。(2)因子定义差距。换手率因子,研报中未说明取多长周期的换手率,回测中我取的是过去20天换手率的波动率。股东数量变化因子同理,研报中未说明取多长周期的变化率,回测中取的过去120天的变化率。ep、bp因子研报中也未说明是否直接取pe、pb的倒数,回测中简单取前一交易日pe、pb的倒数。经营现金流资产比因子、留存收益比因子,研报中未说明取多长周期的数据,回测中取的是上一财务年度的数据。净利润稳定性因子,研报内容描述的是计算过去八期的净利润、营业收入和营业利润的标准分,构建财务收益稳健因子,但在文章结尾构建因子部分描述为净利润业绩稳健。回测中简化处理取过去八期净利润,并对其进行标准化。如果研报中对因子的定义不同或者对数据进行过特殊处理,生成的因子与本次回测生成的因子会有很大差异,导致不同的选股结果。(3)回测本身的问题。数据处理相对简单粗暴。比如ep因子数据,应该把负值过滤掉(但分红良好且净利润为负的可能性比较小)。另外,回测中未对因子的IC值、因子单调性、因子相关性进行检验及测试。

未来研究思路:重点在基本面因子研究方面,更好的配合主观投资。也可以加入技术面因子,比如MACD,KDJ,RSI等指标进行过滤。看看测试的效果。