写在前面

股票期货等历史数据可以通过很多接口以及库来获取,而针对基金数据获取的方式则比较少。下面这篇文章的主要内容是介绍如何通过Python爬取天天基金网的基金历史数据,以便于我们对基金进行数据分析以及计算其他分析指标。完整源码在文末。

准备工作

下面的代码是基于python3.7.2的版本实现的,需要用到的库有:

requests== 2.22.0
bs4== 4.8.2
numpy== 1.18.1
pandas== 1.0.1
matplotlib== 3.1.3

天天基金网是东方财富旗下的基金网站,其同样也提供了用于获取基金数据的接口:

http://fund.eastmoney.com/f10/F10DataApi.aspx

在使用这个接口时需要传入几个参数,像下面的形式:

http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code=050026&page=1&sdate=2020-01-01&edate=2020-03-01&per=20

其中,每个参数的意义是:

  • type:lsjz表示历史净值

  • code:表示基金代码,如050026表示博时医疗保健行业混合

  • page:表示获取的数据的页码

  • per:表示获取的数据每页显示的条数

  • sdate:表示开始时间

  • edate:表示结束时间

上面的例子获取的是050026基金从2020年01月01号到2020年03月01号的历史净值数据,其中结果返回第一页,一页有20条数据,通过浏览器打开如下图所示:

可以看到返回的结果是一个表格的形式,包含了基金的单位净值,累计净值,日增长率,申购状态以及赎回状态。其中单位净值即是当前基金的价格,它的计算方式是:单位净值=总净资产/基金份额。如果在交易日的交易结束(15:00之前)购买基金则是以当日的基金净值确认份额,即:购入份额=购买金额/当日基金净值。如果在交易日的交易时段结束后购买,则会以下一个交易日的基金净值来确认份额。累计净值则是基金的单位净值加上以往的分红,可以反应该基金自成立至今的整体收益。日增长率的计算方式是:(当前交易日净值-上一交易日净值)/上一交易日净值。在上面的返回结果中,还需要注意的是,记录一共有36条,有两页数据,返回的结果是第一页。

代码编写

在分析完接口以及返回数据类型之后,下面进行具体代码的编写。

首先,需要导入相关的库:

# 导入需要的模块
import requests
import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup

接下来先需要先编写一个函数用于获取来自这个接口的返回结果,以便于后面的调用:

def get_html(code, start_date, end_date, page=1, per=20):url = 'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={0}&page={1}&sdate={2}&edate={3}&per={4}'.format(code, page, start_date, end_date, per)rsp = requests.get(url)html = rsp.textreturn html

下面再写一个用于返回获取得到基金数据的函数,其中调用bs4中的BeautifulSoup将html结果解析为一个对象,便于从网页中直接抓取数据。

def get_fund(code, start_date, end_date, page=1, per=20):# 获取htmlhtml = get_html(code, start_date, end_date, page, per)soup = BeautifulSoup(html, 'html.parser')

由于前面提到的原因,这个接口返回的数据不是直接全部返回,而是以表格分页的形式返回的。所以我们可以先获取返回数据的总页数,然后分别遍历每一页的数据。同时将返回表格的表头信息保存下来以便于将其作为后面转换为DataFrame数据类型的列名。

# 获取总页数pattern = re.compile('pages:(.*),')result = re.search(pattern, html).group(1)total_page = int(result)# 获取表头信息heads = []for head in soup.findAll("th"):heads.append(head.contents[0])

接下来需要对表格每一页的数据进行遍历,并将数据存储到一个列表中。

# 数据存取列表records = []# 获取每一页的数据current_page = 1while current_page <= total_page:html = get_html(code, start_date, end_date, current_page, per)soup = BeautifulSoup(html, 'html.parser')# 获取数据for row in soup.findAll("tbody")[0].findAll("tr"):row_records = []for record in row.findAll('td'):val = record.contents# 处理空值if val == []:row_records.append(np.nan)else:row_records.append(val[0])# 记录数据records.append(row_records)# 下一页current_page = current_page + 1

最后将数据转换为一个DataFrame对象,然后按照日期进行升序排序,最后将其返回。

# 将数据转换为Dataframe对象np_records = np.array(records)fund_df = pd.DataFrame()for col, col_name in enumerate(heads):fund_df[col_name] = np_records[:, col]# 按照日期排序fund_df['净值日期'] = pd.to_datetime(fund_df['净值日期'], format='%Y/%m/%d')fund_df = fund_df.sort_values(by='净值日期', axis=0, ascending=True).reset_index(drop=True)fund_df = fund_df.set_index('净值日期')# 数据类型处理fund_df['单位净值'] = fund_df['单位净值'].astype(float)fund_df['累计净值'] = fund_df['累计净值'].astype(float)fund_df['日增长率'] = fund_df['日增长率'].str.strip('%').astype(float)return fund_df

运行实例

下面对代码进行运行,以基金050026从2020年02月01号到2020年06月01号的数据获取为例:

fund_df = get_fund('050026' ,start_date='2020-02-01',end_date='2020-06-01')
print(fund_df)

返回结果如下:

              单位净值    累计净值    日增长率  申购状态  赎回状态 分红送配
净值日期
2020-02-03  2.2860  2.4250  -4.31%  开放申购  开放赎回  nan
2020-02-04  2.3600  2.4990   3.24%  开放申购  开放赎回  nan
2020-02-05  2.4210  2.5600   2.58%  开放申购  开放赎回  nan
2020-02-06  2.4980  2.6370   3.18%  开放申购  开放赎回  nan
2020-02-07  2.4630  2.6020  -1.40%  开放申购  开放赎回  nan
...            ...     ...     ...   ...   ...  ...
2020-05-26  3.1830  3.3220   2.91%  开放申购  开放赎回  nan
2020-05-27  3.1130  3.2520  -2.20%  开放申购  开放赎回  nan
2020-05-28  3.0820  3.2210  -1.00%  开放申购  开放赎回  nan
2020-05-29  3.1480  3.2870   2.14%  开放申购  开放赎回  nan
2020-06-01  3.2160  3.3550   2.16%  开放申购  开放赎回  nan

下面对其单位净值,累计净值以及日增长率进行可视化:

fig, axes = plt.subplots(nrows=2, ncols=1)
fund_df[['单位净值', '累计净值']].plot(ax=axes[0])
fund_df['日增长率'].plot(ax=axes[1])
plt.show()

效果如下图所示:

完整源码

完整代码如下:

# 导入需要的模块
import requests
from bs4 import BeautifulSoup
import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib# 处理乱码
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'
matplotlib.rcParams['axes.unicode_minus'] = Falsedef get_html(code, start_date, end_date, page=1, per=20):url = 'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={0}&page={1}&sdate={2}&edate={3}&per={4}'.format(code, page, start_date, end_date, per)rsp = requests.get(url)html = rsp.textreturn htmldef get_fund(code, start_date, end_date, page=1, per=20):# 获取htmlhtml = get_html(code, start_date, end_date, page, per)soup = BeautifulSoup(html, 'html.parser')# 获取总页数pattern = re.compile('pages:(.*),')result = re.search(pattern, html).group(1)total_page = int(result)# 获取表头信息heads = []for head in soup.findAll("th"):heads.append(head.contents[0])# 数据存取列表records = []# 获取每一页的数据current_page = 1while current_page <= total_page:html = get_html(code, start_date, end_date, current_page, per)soup = BeautifulSoup(html, 'html.parser')# 获取数据for row in soup.findAll("tbody")[0].findAll("tr"):row_records = []for record in row.findAll('td'):val = record.contents# 处理空值if val == []:row_records.append(np.nan)else:row_records.append(val[0])# 记录数据records.append(row_records)# 下一页current_page = current_page + 1# 将数据转换为Dataframe对象np_records = np.array(records)fund_df = pd.DataFrame()for col, col_name in enumerate(heads):fund_df[col_name] = np_records[:, col]# 按照日期排序fund_df['净值日期'] = pd.to_datetime(fund_df['净值日期'], format='%Y/%m/%d')fund_df = fund_df.sort_values(by='净值日期', axis=0, ascending=True).reset_index(drop=True)fund_df = fund_df.set_index('净值日期')# 数据类型处理fund_df['单位净值'] = fund_df['单位净值'].astype(float)fund_df['累计净值'] = fund_df['累计净值'].astype(float)fund_df['日增长率'] = fund_df['日增长率'].str.strip('%').astype(float)return fund_dfif __name__ == '__main__':fund_df = get_fund('050026' ,start_date='2020-02-01',end_date='2020-06-01')print(fund_df)fig, axes = plt.subplots(nrows=2, ncols=1)fund_df[['单位净值', '累计净值']].plot(ax=axes[0])fund_df['日增长率'].plot(ax=axes[1])plt.show()

了解更多人工智能与量化金融知识<-请扫码关注

【python量化】用Python获取基金历史净值数据相关推荐

  1. 2 获取基金历史净值数据

    一 功能介绍 功能:获取基金历史净值数据 数据来源: https://fundf10.eastmoney.com/F10DataApi.aspx?type=lsjz&code={}&p ...

  2. python爬取基金历史净值_Python学习笔记之抓取某只基金历史净值数据实战案例

    摘要:这篇Python开发技术栏目下的"Python学习笔记之抓取某只基金历史净值数据实战案例",介绍的技术点是"Python学习笔记.Python.历史净值数据.学习笔 ...

  3. python历史净值分析_Python 爬取基金历史净值数据

    # -*- coding: utf-8 -*- """ * DataSource : 天天基金网 (http://fund.eastmoney.com/161005.ht ...

  4. 利用Excel Power Query获取基金历史净值、估值和日增长率等信息

    利用Excel Power Query获取基金历史净值.估值和日增长率等信息 先展示结果 Excel Power Query说明 基金数据源 数据查询API接口分析 Excel query 查询获取基 ...

  5. python爬取天天基金_用Python抓取天天基金网基金历史净值数据

    请关注微信公众号:金融数学 FinancialMathematics玩基金的朋友应该都深有体会,2018是相当惨淡的一年,尤其下半年,能够保本就不错了.2019迎来了开门红,从2月11日到14日,连续 ...

  6. python 基金净值_用Python抓取天天基金网基金历史净值数据

    请关注微信公众号:金融数学 FinancialMathematics玩基金的朋友应该都深有体会,2018是相当惨淡的一年,尤其下半年,能够保本就不错了.2019迎来了开门红,从2月11日到14日,连续 ...

  7. python爬取天天基金历史净值_用Python抓取天天基金网基金历史净值数据

    请关注微信公众号:金融数学 FinancialMathematics 玩基金的朋友应该都深有体会,2018是相当惨淡的一年,尤其下半年,能够保本就不错了.2019迎来了开门红,从2月11日到14日,连 ...

  8. 通达信行情数据获取--python_利用 Python 获取余额宝历史收益数据

    最近想做一个关于用一些指数基金与余额宝组成的简单 风险-无风险 投资组合的实验计算,发现通达信之类的行情软件并没有提供完整的余额宝收益信息,如通达信仅有年化收益率的数据,并没有万份收益的数据.因此考虑 ...

  9. 利用 Python 获取余额宝历史收益数据

    最近想做一个关于用一些指数基金与余额宝组成的简单 风险-无风险 投资组合的实验计算,发现通达信之类的行情软件并没有提供完整的余额宝收益信息,如通达信仅有年化收益率的数据,并没有万份收益的数据.因此考虑 ...

最新文章

  1. R语言使用Repeat函数多次执行代码块内的语句,实现循环执行任务的功能:repeat没有提供任何检查条件,所以编码者必须给出退出重复循环的条件(一般使用if和break)
  2. Nginx学习总结(13)——Nginx 重要知识点回顾
  3. python 画风场 scipy_Python库之SciPy教程
  4. 创建美区苹果账户ID
  5. Origin软件绘制柱形图
  6. 论文阅读:Aspect-based Sentiment Classification with Aspect-specific Graph Convolutional Networks
  7. js执行拼接变量的方法字符串
  8. vlookup匹配的文字显示0_VLOOKUP函数用法大全
  9. 分享111个HTML艺术时尚模板,总有一款适合您
  10. APMSERV 配置失败 或80端口被占用最全解决办法 100%解决
  11. 京东股权众筹平台的玩法和价值
  12. 【C++】一个简单的模拟实现鼠标脚本精灵
  13. Unity3d学习笔记 var 关键字
  14. scheme唤醒外部APP
  15. DPDK-IP分片和重组库
  16. 玩转达梦の 多表关联更新改写
  17. Spring学习:Spring的IOC注解
  18. C语言旅途之用switch计算本利和
  19. DFS、BFS实例(啊哈算法)
  20. 关于化工行业如何报警

热门文章

  1. Android响应式UI教程
  2. python3实现微信公众号文章爬取
  3. 跨域 Response to preflight request doesn‘t pass access control check: It does not have HTTP ok status.
  4. 【VerilogHDL】Verilog开发流程
  5. swing 布局设计
  6. 中国无人商店未来5年或将爆发 带动传感器迎来新蓝海
  7. 机器学习-K-近邻算法
  8. mosquito 和QTMQTT测试记录
  9. 服务器主机接显示器,服务器主机连接显示器
  10. RPA之家手把手带你入门Blue Prism教程系列4_认识Blue Prism的界面