目录
免责声明:本文由作者参考相关资料,并结合自身实践和思考独立完成,对全文内容的准确性、完整性或可靠性不作任何保证。同时,文中提及的数据仅作为举例使用,不构成推荐;文中所有观点均不构成任何投资建议。请读者仔细阅读本声明,若读者阅读此文章,默认知晓此声明。
1. 实现步骤
1. 获取基准的数据,本文以中证500指数为例,频率为日度。
2. 获取标的的数据,本文以招商中证500指数A(004192)为例。
3. 计算单日超额收益,单日超额收益 = 指数单日涨跌幅-标的单日涨跌幅。
4. 迭代获取超额收益的时序数据。
5. 令初始净值为1,根据超额收益的时序数据,迭代出对应的超额净值序列。
2. 源代码
import akshare as ak
import pandas as pd
import datetime
class get_alpha(object):
def __init__(self, index_code, fund_code, st=None, et=None):
'''
index_code: 基准代码,格式为str
fund_code: 标的代码,格式为str
st: 开始时间,不写默认为'20180101'
et: 结束时间,不写默认为'最新'
'''
self.index_code = index_code
self.fund_code = fund_code
self.st = '20180101' or st
self.et = datetime.datetime.now().strftime("%Y%m%d") or et
@classmethod
def Daychange(cls, day): # 日期转换,不带"-"
return pd.to_datetime(day).strftime("%Y%m%d")
@classmethod
def get_return(cls, data): # 获取百分比收益率序列
return data.copy().pct_change().fillna(0)
@classmethod
def normalized_nav(cls, data): # 净值归一处理
new_data = [x / data.tolist()[0] for x in data.tolist()]
return new_data
def get_index_data(self):
# 获取指数数据
data_source = ak.stock_zh_index_daily_em(symbol=self.index_code) \
.sort_values(by=['date'], ascending=True)
data_source['date'] = data_source['date'].apply(lambda x: self.Daychange(x))
data_df = pd.DataFrame({'tradingDay': data_source['date'], 'index_nav': data_source['close']})
return data_df
def get_fund_data(self):
# 获取标的数据
data_source = ak.fund_open_fund_info_em(fund=self.fund_code, indicator="累计净值走势") \
.sort_values(by=['净值日期'], ascending=True)
data_source['date'] = data_source['净值日期'].apply(lambda x: self.Daychange(x))
data_df = pd.DataFrame({'tradingDay': data_source['date'], 'fund_nav': data_source['累计净值']})
return data_df
def get_alpha_nav(self):
# 获取超额序列
index_df = self.get_index_data()
fund_df = self.get_fund_data()
# 合并数据
me_df = pd.merge(index_df, fund_df, on='tradingDay', how='right')
# 筛选日期
new_data = me_df.loc[(me_df['tradingDay'] >= self.st) & (me_df['tradingDay'] <= self.et)]
# 计算超额收益
new_data['alpha_re'] = self.get_return(new_data['fund_nav']) - self.get_return(new_data['index_nav'])
# 计算超额净值序列
nav = 1
nav_list = []
for x in new_data['alpha_re']:
nav = nav * (1 + x)
nav_list.append(nav)
# 合成表格,并对净值进行归一处理
out_df = pd.DataFrame({'日期': new_data['tradingDay'],
'基准指数': self.normalized_nav(new_data['index_nav']),
'标的': self.normalized_nav(new_data['fund_nav']),
'超额': nav_list})
return out_df
if __name__ == '__main__':
index_code = "sh000852"
fund_code = '004192'
model = get_alpha(index_code, fund_code)
res = model.get_alpha_nav()
3. 结果
最终结果如下图,此处不再进行可视化的演示。
本期分享结束,有何问题欢迎交流。
免责声明:本文由作者参考相关资料,并结合自身实践和思考独立完成,对全文内容的准确性、完整性或可靠性不作任何保证。同时,文中提及的数据仅作为举例使用,不构成推荐;文中所有观点均不构成任何投资建议。请读者仔细阅读本声明,若读者阅读此文章,默认知晓此声明。