| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 区块链 -> 买股不如买基?Python实现快速追踪基金的收益情况!谁还不是个买基高手? -> 正文阅读 |
|
[区块链]买股不如买基?Python实现快速追踪基金的收益情况!谁还不是个买基高手? |
? 大家知道,近几年,不少同学都是经由基金进入到股市中的。去年就很流行“买股不如买基”的说话,至于股票和基金到底谁更好,这个仁者见仁智者见智,恐怕一时半会儿也说不清楚。 今天,阳哥给大家分享的主题是 用 Python 来追踪和更新基金的收益情况,涉及到的Python库主要是 pandas 和 tushare 。 最终实现的效果如下: ? ? 上面表格中的信息,主要涉及四个方面:
上面的这些信息,在财经工具 tushare 中,目前是都已经提供了的。因此,咱们有必要稍微介绍下 tushare 。 01 tushare 介绍关于财经数据,有多个Python库可以供咱们选择,其中 tushare 是国内较早开始发布财经数据的社区,其内容比较完善,今天我们使用的就是 tushare 。 Tushare 是一个金融大数据平台,数据内容包含股票、指数、基金、期货、债券、外汇、行业大数据等,同时包括了数字货币行情等区块链数据,为各类金融投资和研究人员提供适用的数据和工具,概览如下: ? ?? ? tushare概览 全部内容很丰富,为了有助于大家有个整体的了解,阳哥绘制了一张完整的思维导图,截图如下: 使用 TushareTushare 平台的数据,已全面升级到 tushare pro 了,通常情况下,还是称之为 tushare。 想使用 tushare 中的数据和功能,首先需要进行注册,获得一份 token (一串字母和数字组成的文本),然后才可以获取到数据,大家可以通过以下链接来注册(也可以点击文末的“阅读原文”): https://tushare.pro/register?reg=129033 在? ? tushare接口TOKEN 复制 token 值,然后在代码中进行如下设置: # 设置 token # tushare 注册地址:https://tushare.pro/register?reg=129033 # 以上方法只需要在第一次或者token失效后调用,完成调取tushare数据凭证的设置,正常情况下不需要重复设置。 ts.set_token('你的token值') pro = ts.pro_api() 在设置好 token 值后,我们就可以开始获取数据。 关于 tushare 的详细介绍,请点击下面的链接前往: 02 基金信息获取首先,导入本次需要用到的python库,并设置好tushare,如下: import pandas as pd import datetime import numpy as np import tushare as ts # token='XXXXXXX' # ts.set_token(token) pro = ts.pro_api()
获取基金基础信息首先,咱们来获取基金基础信息,包括基金名称、基金费率、基金公司、基金成立时间等。在 tushare 中,提供了? ? 该接口有两个参数,咱们主要关注的是第一个参数? 所有基金的基础信息获取代码如下: # 获取基金中文名称信息 df_e = pro.fund_basic(market='E') df_o = pro.fund_basic(market='O') df_fund_info = df_e.append(df_o) df_fund_info = df_fund_info[['ts_code','name', 'management','m_fee', 'c_fee','found_date']] df_fund_info.columns = ['fund_code','fund_name', 'management','m_fee', 'c_fee','found_date'] df_fund_info = df_fund_info.reset_index(drop=True) df_fund_info 结果如下: ? 目前整个市场上有 1.5万多支基金,是不是超出你的想象了啊~~~ 当然了,这是包括了混合型、股票型、债券型、货币基金类等全部的基金。 获取基金经理信息对于主动型基金而言,挑选基金时,选择一个好的基金经理是很重要的因素,因此,在追踪基金的收益情况时,是有必要将基金经理的信息一并获取的。 在tushare 中,可通过接口? 在获取基金经理信息后,可以跟之前获取基金基础信息进行合并。 这个过程,阳哥写了一个自定义函数,如下: # 获取单个基金的信息 def get_fund(fund_code,df_fund_info): # 获取基金经理信息,以及开始管理该基金的日期 df_manager = pro.fund_manager(ts_code=fund_code) df_manager = df_manager[df_manager['end_date'].isna()] df_manager = df_manager.sort_values('begin_date',ascending=True).head(1) begin_date = df_manager['begin_date'].values[0] # 开始管理该基金的日期 df_manager = df_manager[['ts_code', 'name', 'gender','begin_date']] df_manager.columns = ['fund_code', 'manager_name', 'gender','begin_date'] # 合并 df_fund = pd.merge(df_manager,df_fund_info,how='left',on='fund_code') return df_fund 假如你想获取易方达中小盘基金的信息,可以基于上面的自定义函数? # 110011.OF,易方达中小盘 df_fund = get_fund('110011.OF',df_fund_info) df_fund 获取的信息如下: ? 计算基金规模和收益情况接下来,咱们还需要获取两个信息,基金规模和基金近几年的收益情况。 基金规模,可以从一个角度来观察该基金在市场上的受欢迎度,一般来说,规模较大的基金,说明该基金过往的表现应该还是可以的。不过这里也有两点需要注意:
除了基金规模,另一个咱们经常关注的,也是基金营销机构经常拿出来宣传的,就是基金的过往收益情况。 基金规模的计算公式如下: 基金规模亿元基金份额数量基金单位净值 在 tushare 中 基金份额数量由函数? 此外,在计算基金的过往年度收益时,也是基于其累计净值(accum_nav)来实现的。 因此,阳哥将基金规模获取过程和基金近几年收益情况计算合并在一个自定义函数里,代码如下: # 获取单支基金的年度收益,基金规模等信息 def get_returns(fund_code,start_year): df_fund_nav = pro.fund_nav(ts_code=fund_code) df_fund_nav['date'] = pd.to_datetime(df_fund_nav['end_date']) df_fund_nav = df_fund_nav.set_index('date').sort_index() years = df_fund_nav['accum_nav'].resample('AS').sum().to_period('A') # 获取年度数据,类型为 pandas 的 period years = years.index.tolist() # 有些基金的开始日期晚于2018年,需要对齐列,补空白 year_list = [yr.year for yr in years if yr.year>=start_year] # 将 period 时间数据转为 string 的年度数据 years = [str(yr.year) for yr in years] df_yrs_index = pd.DataFrame() for yr in years: df_yr_index = df_fund_nav.loc[yr].tail(1) df_yrs_index = df_yrs_index.append(df_yr_index) df_yrs = df_fund_nav.head(1).append(df_yrs_index) # 计算每年的收益率,即涨跌幅度 df_yrs['returns'] = df_yrs['accum_nav'].pct_change() # 删除收益率为 NA 的行 (第1天有数据记录的日期) df_yrs = df_yrs.dropna(subset=['returns']) # 筛选自开始年份以来的数据 df_yrs = df_yrs.loc[str(start_year):] df_yrs = df_yrs.reset_index() df_yrs['year'] = df_yrs['date'].dt.year # 透视表 df_yr_returns = pd.pivot_table( df_yrs, index=['ts_code'], values=['returns'], columns=['year'], fill_value="" ) # 将多层索引转变为单层索引 df_yr_returns = df_yr_returns['returns'] df_yr_returns = df_yr_returns.reset_index() df_yr_returns.columns.name = None df_yr_returns = df_yr_returns.rename(columns={'ts_code':'fund_code'}) # 基金份额 df_fund_share = pro.fund_share(ts_code=fund_code).head(1) df_fund_share.columns = ['fund_code', 'fd_share_date', 'fd_share', 'fund_type', 'market'] # fd_share,单位是 万份 fd_share_date = df_fund_share['fd_share_date'].values[0] # 份额对应的日期 # 份额日期的净值数据 df_ann_nav = df_fund_nav.loc[fd_share_date:fd_share_date].sort_values('update_flag',ascending=False).head(1) df_ann_nav = df_ann_nav[['ts_code', 'accum_nav','unit_nav']] df_ann_nav.columns = ['fund_code', 'accum_nav','unit_nav'] # 计算基金规模,amount,单位:亿元 df_fund_amount = pd.merge(df_fund_share,df_ann_nav,how='left',on='fund_code') df_fund_amount['amount'] = df_fund_amount['fd_share'] * df_fund_amount['unit_nav']/10000 df_fund_amount = df_fund_amount[['fund_code','amount','fd_share_date']] # 合并数据 df_yr_returns = pd.merge(df_fund_amount,df_yr_returns,how='left',on='fund_code') for yr in year_list: if yr not in df_yr_returns.columns.tolist(): df_yr_returns[yr]=np.nan return df_yr_returns 假如你想获取易方达中小盘基金的2018年以来的收益情况信息,可以基于上面的自定义函数? df_return = get_returns('110011.OF',2018) df_return 获取的信息如下: ? 同时获取多只基金的信息上面已经实现了获取单只基金所需要的信息,接下来,咱们需要拼接之前获取的信息。 同时,我们一般会同时关注多只基金,因此同时获取多只基金的信息,也是基本必备的需求。 实现的代码如下: # 获取多只基金的信息 def get_data_fund(df_fund_info,fund_code_short,code_exception,start_year): df_filter_info = pd.DataFrame() for code in fund_code_short: df_tmp = df_fund_info[df_fund_info['fund_code'].str.contains(code)].head(1) df_filter_info = df_filter_info.append(df_tmp) df_filter_info = df_filter_info.reset_index(drop=True) fund_codes = df_filter_info['fund_code'].tolist() # fund_codes df = pd.DataFrame() for code in fund_codes: if code in code_exception: code_update = code[:-2]+'OF' code_short = code[:-3] df_fund = get_fund(code_update,df_fund_info) df_fund['fund_code'] = code df_fund = df_fund[['fund_code','manager_name','gender','begin_date']] df_fund = df_fund.dropna(axis=1) # 删除含 NaN 的列 test_m = df_fund_info[df_fund_info['fund_code'].str.contains(code_short)] df_fund = pd.merge(df_fund,test_m,how='left',on='fund_code') else: df_fund = get_fund(code,df_fund_info) df_return = get_returns(code,start_year) df_fund_merge = pd.merge(df_fund,df_return,how='left',on='fund_code') df = df.append(df_fund_merge) df = df.reset_index(drop=True) df = df.rename(columns={ 'fund_code':'基金代码','manager_name':'基金经理', 'gender':'性别','begin_date':'上任日期', 'fund_name':'基金名称','management':'基金公司', 'm_fee':'管理费','c_fee':'托管费', 'found_date':'成立时间','amount':'基金规模(亿元)', 'fd_share_date':'规模对应日期' }) # 调整列的排序 cols = df.columns.tolist() col_1 = cols[:4] col_2 = cols[4:5] col_3 = cols[5:] cols = col_2 + col_1 + col_3 df = df[cols] return df 上面的自定义函数? 这个特列,主要是有一类基金,叫做LOF基金,场内和场外的数字代码是一样的,比如谢治宇的兴全合润基金,在tushare中,场内的完整代码是163406.SZ,场外的完整代码是163406.OF,对于LOF基金,我们只需要获取一个的信息即可。 同时,由于LOF基金获取信息是基金基础信息和基金经理信息用的代码有些区别,需要分开应用。因此,需要在上面的函数? 在上面的函数? 基于自定义函数? # 需要获取的基金代码简称列表 fund_code_short = ['000772', '003095','166005','320007', '163406','260101','161005','162605', '163402','005827','110022','110011', '164908','000800','590008', '360007','118001', '519736','007119','002190','005911', '001938','166002','377240' ] # ['200011','690003','200010',] # 特列:LOF 基金,基金经理和管理费等费用所用的代码两处不一致,需要调整 # 输入的是 LOF 基金在场内的完整代码 code_exception = ['163406.SZ','160632.SZ','160222.SZ','159843.SZ','515920.SH'] # 设置基金收益开始的年份 start_year = 2018 # 设置基金收益截止的年份 end_year = 2021 year_list = list(range(start_year,end_year+1)) df_fund_final = get_data_fund(df_fund_info,fund_code_short,code_exception,start_year) df_fund_final 得到的结果如下: ? Pandas 中,可以通过 Style 对表格样式进行设置,对收益情况进行红涨绿跌的设置。 代码如下: def color_returns(val): if val >=0: color = '#EE7621' # light red elif val <0: color = '#99ff66' # light green else: color = '#FFFAFA' # ligth gray return f'background-color: {color}' format_dict = {'基金规模(亿元)': '¥{0:.1f}', '管理费': '{0:.1f}', '托管费': '{0:.2f}', 2017: '{0:.1%}', 2018: '{0:.1%}', 2019: '{0:.1%}', 2020: '{0:.1%}', 2021: '{0:.1%}', } df_fund_final = df_fund_final.sort_values('基金经理',ascending=True) df_fund_final.style.hide_index()\ .hide_columns(['规模对应日期','成立时间'])\ .format(format_dict)\ .applymap(color_returns,subset=year_list)\ .background_gradient(subset=['基金规模(亿元)'],cmap='Blues') 得到的结果如下: ? 关于 Pandas 中表格样式设置,阳哥之前分享了一份详细的内容,有兴趣的同学可以前往查看:03 小结 至此,咱们就获取了本次想要得到的信息,这个表格可以定期更新,用于给其他人员分享基金的基本信息以及年度收益情况。 在今天的这个财经案例里,需求其实是很常见的。在这个案例里,主要用到的是 Pandas 和 Tushare 工具。 对于 Pandas 而言,用到的知识点还是挺多的,包括数据筛选、数据合并、数据排序、数据透视表、样式设置等,虽然都是基础知识点,但要做到熟练运用,也是需要一定功底的。 对于 tushare ,主要是关注该工具中财经信息的完整性、准确性以及及时性。 如果其他财经工具有这样的功能,也是可以了。 ??完整源码或安装教程点:这里领取 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 20:32:53- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |