常见因子的Fama-Macbeth回归:EAP.fama_macbeth

本文根据Bail et al.的著作Empirical Asset Pricing编写相关程序,投资组合分析的模块是EAP.fama_macbeth,下面将对该模块进行详细介绍。本文的Package已发布于Github:

Github: GitHub – whyecofiliter/EAP: empirical asset pricing

Fama-Macbeth回归检验因子风险溢价的存在性。Fama Macbeth回归遵循两个步骤:

1.指定模型并进行横截面回归。

2.取回归系数的时间序列平均值

欲知更多详情,请阅读Empirical Asset Pricing: The Cross Section of Stock Returns. Bali, Engle, Murray, 2016.

检验特征对资产收益率是否具有系统性影响,需要在FM回归模型中加入股票特征。在本demo中,特征或因子包括规模、价值、盈利能力、投资、动量和换手率,其代理变量在模拟因素的投资组合demo中介绍。

%% set system path
import sys,os
sys.path.append(os.path.abspath(".."))

数据预处理

%% import data
Monthly return of stocks in China security market
import pandas as pd

month_return = pd.read_hdf('.\data\month_return.h5', key='month_return')
company_data = pd.read_hdf('.\data\last_filter_pe.h5', key='data')
trade_data = pd.read_hdf('.\data\mean_filter_trade.h5', key='data')
beta = pd.read_hdf('.\\data\\beta.h5', key='data')

%% data preprocessing
forward the monthly return for each stock
emrwd is the return including dividend
month_return['emrwd'] = month_return.groupby(['Stkcd'])['Mretwd'].shift(-1)
emrnd is the return including no dividend
month_return['emrnd'] = month_return.groupby(['Stkcd'])['Mretnd'].shift(-1)
select the A share stock
month_return = month_return[month_return['Markettype'].isin([1, 4, 16])]

% distinguish the stocks whose size is among the up 30% stocks in each month
def percentile(stocks) :
    return stocks >= stocks.quantile(q=.3)

month_return['cap'] = month_return.groupby(['Trdmnt'])['Msmvttl'].apply(percentile)

构建代理变量

%% Construct proxy variable
import numpy as np

SMB
log(Size)
month_return['Size'] = np.log(month_return['Msmvttl'])

HML
company_data['BM'] = 1 / company_data['PBV1A']

RMW
in this demo, the ROE(TTM) are used
ROE(TTM) = PBV1B/PE(TTM)
company_data['ROE(TTM)'] = company_data['PBV1B']/company_data['PE1TTM']

CMA
% calculate the total asset
asset = debt + equity
debt = company_value - market_value
equity = market_value / PB
company_data['debt'] = company_data['EV1'] - company_data['MarketValue']
company_data['equity'] = company_data['MarketValue']/company_data['PBV1A']
company_data['asset'] = company_data['debt'] + company_data['equity']
asset growth rate
company_data['asset_growth_rate'] = company_data['asset'].groupby(['Symbol']).diff(12)/company_data['asset']

Momentum
month_return['rolling_12'] = np.array(month_return.groupby(['Stkcd'])['Mretwd'].rolling(12).sum())
month_return['momentum'] = month_return['rolling_12'] - month_return['Mretwd']

Turnover
trade_data['rolling_Turnover'] = np.array(trade_data['Turnover'].groupby('Symbol').rolling(12).mean())
trade_data['specific_Turnover'] = trade_data['Turnover'] / trade_data['rolling_Turnover']

进一步数据预处理

%% merge data
from pandas.tseries.offsets import *

month_return['Stkcd_merge'] = month_return['Stkcd'].astype(dtype='string')
month_return['Date_merge'] = pd.to_datetime(month_return['Trdmnt'])
#month_return['Date_merge'] += MonthEnd()

company_data['Stkcd_merge'] = company_data['Symbol'].dropna().astype(dtype='int').astype(dtype='string')
company_data['Date_merge'] = pd.to_datetime(company_data['TradingDate'])
company_data['Date_merge'] += MonthBegin()

trade_data['Stkcd_merge'] = trade_data['Symbol'].dropna().astype(dtype='int').astype(dtype='string')
trade_data['TradingDate'] = trade_data.index.map(lambda x : x[1])
trade_data['Date_merge'] = pd.to_datetime(trade_data['TradingDate'])
#company_data['Yearmonth'] = company_data['Date_merge'].map(lambda x : 1000*x.year + x.month)
trade_data['Date_merge'] += MonthBegin()

%% dataset starts from '2000-01'
company_data = company_data[company_data['Date_merge'] >= '2000-01']
month_return = month_return[month_return['Date_merge'] >= '2000-01']
return_company = pd.merge(company_data, month_return, on=['Stkcd_merge', 'Date_merge'])
return_company = pd.merge(return_company, trade_data, on=['Stkcd_merge', 'Date_merge'])

beta
return_company = return_company.set_index(['Stkcd', 'Trdmnt'])
return_company = pd.merge(return_company, beta, left_index=True, right_index=True)

进行Fama-Macbeth回归

%% Fama-Macbeth regression
dataset : #1
exclude tail stocks
range from 2000-01-01 ~ 2019-12-01
from fama_macbeth import Fama_macbeth_regress

test_data_1 = return_company[(return_company['cap']==True) & (return_company['Ndaytrd']>=10)]
test_data_1 = test_data_1[['emrwd', 'beta', 'Size', 'BM', 'ROE(TTM)', 'asset_growth_rate', 'momentum', 'specific_Turnover', 'Date_merge']].dropna()
test_data_1 = test_data_1[(test_data_1['Date_merge'] >= '2000-01-01') & (test_data_1['Date_merge']

第一个数据集 不包括2000-01-01至2019-12-01期间30%的尾部股票。包括规模系数(size)、价值系数(BM)、盈利系数(ROE(TTM))和换手率(specific_Turnover)在内的因素具有 显著风险溢价。包括市场、投资和动量因子在内的因素具有 不显著的风险溢价。

%% Fama-Macbeth regression
dataset : #2
include tail stocks
range from 2000-01 ~ 2019-12-01
from fama_macbeth import Fama_macbeth_regress

test_data_2 = return_company[(return_company['Ndaytrd']>=10)]
test_data_2 = test_data_2[['emrwd', 'beta', 'Msmvttl', 'PE1A', 'ROE(TTM)', 'asset_growth_rate', 'momentum', 'specific_Turnover', 'Date_merge']].dropna()
test_data_2 = test_data_2[(test_data_2['Date_merge'] >= '2000-01-01') & (test_data_2['Date_merge']

第二个数据集 包含从2000-01-01到2019-12-01的30%尾部股票。包括规模系数(size)、价值系数(BM)、盈利能力(ROE(TTM))、换手率(specific_Turnover)在内的因素 具有显著风险溢价。包括市场、投资和动量因子在内的因素 具有不显著的风险溢价。

%% Fama-Macbeth regression
dataset : #3
exclude tail stocks
range from 2000-01-01 ~ 2016-12-01
from fama_macbeth import Fama_macbeth_regress

test_data_3 = return_company[(return_company['cap']==True) & (return_company['Ndaytrd']>=10)]
test_data_3 = test_data_3[['emrwd', 'beta', 'Size', 'BM', 'ROE(TTM)', 'asset_growth_rate', 'momentum', 'specific_Turnover', 'Date_merge']].dropna()
test_data_3 = test_data_3[(test_data_3['Date_merge'] >= '2000-01-01') & (test_data_3['Date_merge']

第三个数据集 不包括2000-01-01至2016-12-01期间30%的尾部股票。包括规模系数(size)、价值系数(BM)、盈利能力(ROE(TTM))、换手率(specific_Turnover)在内的因素 具有显著风险溢价。包括市场、投资和动量因素在内的因素 具有不显著的风险溢价。

%% Fama-Macbeth regression
dataset : #4
include tail stocks
range from 2000-01-01 ~ 2016-12-01
from fama_macbeth import Fama_macbeth_regress

test_data_4 = return_company[(return_company['Ndaytrd']>=10)]
test_data_4 = test_data_4[['emrwd', 'beta', 'Size', 'BM', 'ROE(TTM)', 'asset_growth_rate', 'momentum', 'specific_Turnover', 'Date_merge']].dropna()
test_data_4 = test_data_4[(test_data_4['Date_merge'] >= '2000-01-01') & (test_data_4['Date_merge']

第四个数据集 包含从2000-01-01到2016-12-01的30%尾部股票。包括规模系数(size)、价值系数(BM)、盈利能力(ROE(TTM))、换手率(specific_Turnover)在内的因子具有 显著风险溢价。包括市场、投资和动量因子在内的因素 具有不显著的风险溢价。

Original: https://blog.csdn.net/m0_37430356/article/details/122852050
Author: 鹦鹉螺平原
Title: 常见因子的Fama-Macbeth回归:EAP.fama_macbeth

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/630716/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球