├── GetAstockFactors.py └── README.md /GetAstockFactors.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Author: Hugo 3 | Date: 2021-10-08 12:51:17 4 | LastEditTime: 2021-10-13 20:22:55 5 | LastEditors: Please set LastEditors 6 | Description: 获取FactorWar的模型数据 7 | 数据来源 https://www.factorwar.com/data/factor-models/ 8 | ''' 9 | 10 | from bs4 import BeautifulSoup 11 | from collections import defaultdict 12 | from typing import (List, Tuple, Dict, Callable, Union) 13 | import requests 14 | from urllib.parse import quote 15 | import string 16 | 17 | import pandas as pd 18 | 19 | 20 | class Get_FactorWar_Data(object): 21 | ''' 22 | 获取factorWar的因子模型数据 23 | ------ 24 | 输入参数: 25 | model_name:CAPM模型, 26 | Fama-French三因子模型, 27 | Carhart四因子模型, 28 | French五因子模型,Novy-Marx四因子模型, 29 | Hou-Xue-Zhang四因子模型, 30 | Stambaugh-Yuan四因子模型, 31 | Daniel-Hirshleifer-Sun三因子模型, 32 | BetaPlusA股混合四因子模型, 33 | 全部多因子模型basisportfolios月均收益率 34 | 35 | model_type:模型算法:1.经典算法 2.极简算法 36 | freq:因子数据频率:1.日频-daily 2.月频-monthly 37 | ''' 38 | 39 | def __init__(self) -> None: 40 | 41 | self.MODEL_NAME_DIC = { 42 | 'CAPM模型': 0, 43 | 'Fama-French三因子模型': 1, 44 | 'Carhart四因子模型': 2, 45 | 'Fama-French五因子模型': 3, 46 | 'Novy-Marx四因子模型': 4, 47 | 'Hou-Xue-Zhang四因子模型': 5, 48 | 'Stambaugh-Yuan四因子模型': 6, 49 | 'Daniel-Hirshleifer-Sun三因子模型': 7, 50 | 'BetaPlusA股混合四因子模型': 8, 51 | '全部多因子模型basisportfolios月均收益率': 9 52 | } 53 | 54 | url_model = 'https://www.factorwar.com/data/factor-models/' 55 | url_index = 'https://www.factorwar.com/data/betaplus-1000-index/' 56 | 57 | soup_model = self._get_soup(url_model) 58 | 59 | self.soup_index = self._get_soup(url_index) 60 | 61 | self.soups_model: List = soup_model.select( 62 | 'div.entry-content > p.has-normal-font-size')[4:] 63 | 64 | @staticmethod 65 | def _get_soup(url: str) -> BeautifulSoup: 66 | '''获取网页''' 67 | response = requests.get(url) 68 | 69 | html_str = response.text 70 | soup = BeautifulSoup(html_str, "lxml") 71 | 72 | return soup 73 | 74 | def get_betaplus1000(self) -> pd.DataFrame: 75 | '''获取betaplus指数''' 76 | 77 | e = self.soup_index.select_one( 78 | '#post-153 > div > div.wp-block-group > div > p:nth-child(3) > a') 79 | csv_url = e['href'] 80 | 81 | return pd.read_csv(csv_url, encoding='gbk', index_col=[0], parse_dates=[0]) 82 | 83 | def get_model_data(self, model_name: str, model_type: str, freq: str) -> pd.DataFrame: 84 | ''' 85 | model_type:模型算法:1.经典算法 2.极简算法 86 | freq:因子数据频率:1.日频-daily 2.月频-monthly 87 | ''' 88 | 89 | select_model = self.MODEL_NAME_DIC[model_name] 90 | 91 | soups = self.soups_model[select_model] 92 | 93 | self.urls: Dict = self._get_urls(soups) 94 | url = self.urls[model_name][model_type][freq] 95 | 96 | return pd.read_csv(url) 97 | 98 | @staticmethod 99 | def _get_urls(children_soup: BeautifulSoup) -> Dict: 100 | 101 | dic: Dict = defaultdict(dict) 102 | 103 | for i, e in enumerate(children_soup.children): 104 | 105 | if i == 0: 106 | 107 | k = e.string 108 | k = k.string 109 | k = k.replace(' ', '') 110 | 111 | dic[k] = { 112 | '经典算法': { 113 | 'daily': None, 114 | 'monthly': None 115 | }, 116 | '极简算法': { 117 | 'daily': None, 118 | 'monthly': None 119 | } 120 | } 121 | 122 | elif i == 3: 123 | 124 | dic[k]['经典算法']['daily'] = quote(e['href'], 125 | safe=string.printable) 126 | 127 | elif i == 5: 128 | 129 | dic[k]['经典算法']['monthly'] = quote(e['href'], 130 | safe=string.printable) 131 | 132 | elif i == 8: 133 | 134 | dic[k]['极简算法']['daily'] = quote(e['href'], 135 | safe=string.printable) 136 | 137 | elif i == 10: 138 | 139 | dic[k]['极简算法']['monthly'] = quote(e['href'], 140 | safe=string.printable) 141 | 142 | return dic 143 | 144 | 145 | # if __name__ == '__main__': 146 | 147 | # gfd = Get_FactorWar_Data() 148 | 149 | # ff_model_data: pd.DataFrame = gfd.get_model_data( 150 | # 'Fama-French三因子模型', '经典算法', 'monthly') 151 | 152 | # print(ff_model_data.tail()) 153 | 154 | # betaplus1000_index: pd.DataFrame = gfd.get_betaplus1000() 155 | 156 | # print(betaplus1000_index.tail()) 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GetAstockFactors 2 | 3 | 获取经典的多因子模型数据 4 | 数据来源:https://www.factorwar.com/data/factor-models/ 5 | 6 | **使用说明** 7 | 8 | ``` 9 | from GetAstockFactors import Get_FactorWar_Data 10 | 11 | # 获取CAPM模型 12 | gfd = Get_FactorWar_Data() 13 | 14 | # 获取经典算法 频率使用日频 15 | capm_daily_df: pd.DataFrame = gfd.get_model_data('CAPM模型','经典模型','daily') 16 | 17 | # 获取极简算法 频率使用月频 18 | capm_monthly_df: pd.DataFrame = gfd.get_model_data('CAPM模型','极简算法','monthly') 19 | 20 | # 获取BetaPlus1000指数数据 21 | betaplus1000: pd.DataFrame = gfd.gfd.get_betaplus1000() 22 | ``` 23 | 24 | **使用get_model_data方法可以获取以下模型:** 25 | 26 | 1. CAPM模型 27 | 2. Fama-French三因子模型 28 | 3. Carhart四因子模型 29 | 4. French五因子模型,Novy-Marx四因子模型 30 | 5. Hou-Xue-Zhang四因子模型 31 | 6. Stambaugh-Yuan四因子模型 32 | 7. Daniel-Hirshleifer-Sun三因子模型 33 | 8. BetaPlusA股混合四因子模型 34 | 9. 全部多因子模型basisportfolios月均收益率 35 | 36 | **使用get_betaplus1000方法可以获得BetaPlus1000指数数据** 37 | 38 | BetaPlus 1000指数系列包括BetaPlus 1000基准指数和7个BetaPlus 1000因子指数,旨在反应A股市场整体以及常见风格的风险收益特征。其涵盖的因子包括价值、盈利、成长、红利、低波动、规模以及动量。具体编制方案见[算法说明](https://www.factorwar.com/wp-content/uploads/2020/08/BetaPlus_Indexes_MethodologyNote_20200813.pdf)。 39 | 40 | **数据说明:** 41 | 1. 如无特殊说明,多因子模型中因子收益率的起始日期为:1995 年 1 月 1 日。 42 | 2. 股票范围:全部在市股票,包括深圳主板、中小板和创业板,上海主板和科创板。 43 | 3. 剔除股票:剔除黑名单股票和不可交易股票,其中黑名单包括新股(上市不满 12 个月)、风险警示股、待退市股和净资产为负股,不可交易股票包括停牌股票和一字涨跌停股票。 44 | 4. 无风险收益率:不同时间段采用不同数据,具体如表1所示。 45 | 表一: 46 | |时间区间|数据来源| 47 | |--|--| 48 | |2002/08/06之前|三个月期定期银行存款利率| 49 | |2002/08/07至2006/10/07|三个月期中央银行票据的票面利率| 50 | |2006/10/08至今|上海银行间三个月同业拆放利率| 51 | 52 | 5. 股票价格数据:后复权收盘价。 53 | 6. 用来构建因子的变量:如表2所示。 54 | 表二: 55 | |因子|变量| 56 | |--|--| 57 | |规模|总市值,即收盘价乘以总股本| 58 | |价值|账面市值比(Book-to-Market ratio,简称 BM),即净资产除以总市值| 59 | |动量|过去 12 个月(剔除最近 1 个月)累计收益率,其中一个月包含21个交易日| 60 | |盈利|营业利润除以净资产| 61 | |投资|总资产增长率或净资产增长率| 62 | 63 | *不同版本的模型中,投资因子将使用总资产增长率或净资产增长率为变量来构建。* 64 | 65 | # 经典版本与极简版本 66 | 67 | 在针对 A 股的实证研究中,本文档提供经典版本和极简版本两个多因子模型版本。经典版本又称为学术界版本,它严格按照关于多因子模型的学术论文中描述的方法选择因子变量,构建因子投资组合,计算因子收益率。极简版本是在经典版本的基础上,针对 A 股市场特点而开发的简化版多因子模型,一边更好的适应 A 股市场。经典版本和极简版本的主要差异包括:(1)经典版本严格遵循学术界惯例,因此因子投资组合每年再平衡;极简版本则按照业界惯例,因此因子投资组合每月再平衡,从而更快地利用最新的因子变量取值。(2)经典版本在构建因子投资组合时,往往采用市值和目标变量的双重排序;但在极简版本中,将使用因子变量单变量排序构建因子投资组合。 68 | 69 | # 详细算法说明 70 | 71 | [因子模型构建细节](https://www.factorwar.com/wp-content/uploads/2021/09/BetaPlus_FactorModels_MethodologyNote_20210904.pdf) 72 | 73 | --------------------------------------------------------------------------------