最近在分析基金的相关数据,曾一度为找不到基金数据而发愁。目前我常用的数据平台有两个,一个是Tushare平台,但是我的积分不够,因此无法调取基金数据。另一个是优矿平台,但是优矿平台不能在本地调取数据,只能在优矿平台上面调取,然后保存到本地。

后来在网上发现了天天基金的数据接口,该接口返回的是文本数据,需要对原始数据进一步处理才可以使用。网上许多大佬都只是给了调用链接,并没有进一步分享数据处理的步骤。在这里,分享一下我的数据处理步骤,以方便大家直接调用基金数据。

1、当前基金净值获取

001186为基金代码,想要调取其他基金数据,替换掉该代码即可;

?rt=1463558676006为时间戳,避免浏览器缓存数据,其实没有这一部分也可以。

在浏览器中输入上面的数据接口,可以得到下面的返回结果:

jsonpgz({"fundcode":"001186","name":"富国文体健康股票","jzrq":"2022-09-20","dwjz":"1.9300","gsz":"1.9187","gszzl":"-0.58","gztime":"2022-09-21 15:00"});

fundcode

name

jzrq

dwjz

gsz

gszzl

gztime

基金代码

基金名称

净值日期

单位净值

估计净值

估计涨幅

估计时间

上面返回的数据是文本数据,我们无法进行分析,因此需要进行数据处理工作,将文本字符转化为字典、dataframe等格式的数据。

通过观察文本,我们可以看到jsonpgz()里面是一窜符合字典格式的文本,因此我们可以通过json,将该文本转换成字典格式,下面是具体的代码:

import requests
import pandas as pd
import json
import re
import time

def realtmfundinfo(fundcode):
    '''
    Parameters
    ----------
    fundcode : str
        基金代码.

    Returns
    -------
    fund_info : dict
        返回基金最近一个交易日的单位净值(dwjz)、基金名称(name)、净值日期(jzrq)、估计净值(gsz)、估计增长率%(gszzl)、估计日期(gztime).
    '''
    fund_id=fundcode
    real_time_url=str("http://fundgz.1234567.com.cn/js/"+fund_id+".js?rt=1463558676006")
    #?rt=1463558676006为时间戳,不写该部分也可以
    org_content = requests.get(real_time_url)#向网站发起请求
    fund_info = org_content.text#获取网站返回的文本,即上文中的文本字符串
    fund_info = re.findall(r"\{.+\}", fund_info)#运用正则表达式获取除去jsonpgz()之外的文本数据,即jsonpgz()中的文本
    fund_info = json.loads(fund_info[0])#使用json方法,将该字符串转化为字典格式
    return fund_info
fund_info = realtmfundinfo("001186")
print(type(fund_info),fund_info)

看一下输出结果:

<class 'dict'> {'fundcode': '001186', 'name': '富国文体健康股票A', 'jzrq': '2022-09-20', 'dwjz': '1.9300', 'gsz': '1.9187', 'gszzl': '-0.58', 'gztime': '2022-09-21 15:00'}

变成了我们期望的字典格式。

2、历史基金净值获取

001186为基金代码,想要调取其他基金数据,替换掉该代码即可;

?v=20160518155842为时间戳,避免浏览器缓存数据,其实没有这一部分也可以。

在浏览器中输入上面的数据接口,便可以得到该基金的申购费率、持仓股票、历史单位净值、历史累计净值等多个信息,由于返回的数据较多,这里就不一一列明。有兴趣的,可以点进该链接查看,数据有中文备注。

下面直接看文本处理代码:

def htrfundinfo(fundcode):
    '''
    Parameters
    ----------
    fundcode : str
        基金代码.

    Returns
    -------
    fund_nav : DataFrame
        返回基金的净值日期(date)、单位净值(nav)、累计净值(cumnav)、净值回报率(equityReturn)、每份派送金(unitMoney).
    '''
    fund_id = fundcode
    history_tmurl="http://fund.eastmoney.com/pingzhongdata/"+fund_id+".js?v=20160518155842"
    #?v=20160518155842为时间戳,避免浏览器缓存
    org_content = requests.get(history_tmurl)#向网站发起请求
    fund_info = org_content.text#获取网站返回的文本,即我们在浏览器中看到的全部文本数据
    temp_nav = re.findall(r"Data_netWorthTrend\s\=\s(\[\{.+\}\]);\/\*累计净值走势\*\/", fund_info)[0]#运用正则表达式,提取单位净值
    temp_nav = json.loads(temp_nav)#将文本数据,转化为字典格式
    temp_nav = pd.DataFrame(temp_nav)#将字典转化为dataframe格式
    temp_nav.rename(columns= {"x": "date", "y":"nav"}, inplace=True)#修改列名称,x修改为date,y修改为nav
    n = len(temp_nav["date"])
    for i in range(n):
        temp_nav["date"][i] = time.strftime('%Y-%m-%d',time.localtime(temp_nav["date"][i]/1000.))#因为返回的时间是个时间戳,所以需要将其转化为正常的时间
    temp_nav=temp_nav.set_index('date')#将时间设置为索引
    temp_cumnav = re.findall(r"Data_ACWorthTrend\s\=\s(\[.+\]);\/\*累计收益率走势\*\/", fund_info)[0]#运用正则表达式,提取累计净值
    temp_cumnav = eval(temp_cumnav)#累计净值的文本不是字典格式,是list格式,因此使用eval函数,将文本转化为list
    temp_cumnav = pd.DataFrame(temp_cumnav)#将list转化为dataframe
    temp_cumnav.rename(columns= {0: "date", 1:"cumnav"}, inplace=True)#从新修改列名
    m = len(temp_cumnav["date"])
    for i in range(m):
        temp_cumnav["date"][i] = time.strftime('%Y-%m-%d',time.localtime(temp_cumnav["date"][i]/1000.))#因为返回的时间是个时间戳,所以需要将其转化为正常的时间
    temp_cumnav = temp_cumnav.set_index('date')#将时间设置为索引
    fund_nav = pd.concat([temp_nav, temp_cumnav],axis=1,join="inner")#将两个dataframe表格按照index进行合并
    return fund_nav
fund_info = htrfundinfo("001186")
print(type(fund_info))
print(fund_info.head())

看一下输出结果:

<class 'pandas.core.frame.DataFrame'>
              nav  equityReturn unitMoney  cumnav
date                                             
2015-05-06  1.000           0.0             1.000
2015-05-08  1.004           0.0             1.004
2015-05-15  1.021           0.0             1.021
2015-05-22  1.078           0.0             1.078
2015-05-29  1.112           0.0             1.112

变成了我们想要的dataframe数据格式。

3、基金名称列表获取

在浏览器中输入上面的数据接口,就可以得到所有基金的基金代码、基金名称、基金类型这些信息。

下面是文本处理代码:

def getfundlist():
    '''
    Returns
    -------
    fund_list : DataFrame
        所有基金列表.
    '''
    list_url="http://fund.eastmoney.com/js/fundcode_search.js"
    org_content = requests.get(list_url)#向网站发起请求
    temp_list = org_content.text#获取请求结构,即我们在浏览器中观看到的文本数据
    temp_list = re.findall(r"\[.+\]",temp_list)[0]#运用正则表达式提取所需数据
    temp_list = eval(temp_list)#因为该文本是list格式,所有要用eval函数
    fund_list = pd.DataFrame(temp_list)#转化为dataframe格式
    fund_list.rename(columns= {0: "fundcode", 1:"jiancheng",2:"name",3:"type",4:"pingyinquangcheng"}, inplace=True)#重新命名列名
    fund_list = fund_list.set_index("fundcode")#设置基金代码作为索引
    return fund_list
fund_info = getfundlist()
print(type(fund_info))
print(fund_info.head())

查看返回结果:

<class 'pandas.core.frame.DataFrame'>
           jiancheng        name     type                     pingyinquangcheng
fundcode                                                                       
000001        HXCZHH      华夏成长混合   混合型-灵活                 HUAXIACHENGZHANGHUNHE
000002        HXCZHH  华夏成长混合(后端)   混合型-灵活                 HUAXIACHENGZHANGHUNHE
000003      ZHKZZZQA    中海可转债债券A  债券型-可转债          ZHONGHAIKEZHUANZHAIZHAIQUANA
000004      ZHKZZZQC    中海可转债债券C  债券型-可转债          ZHONGHAIKEZHUANZHAIZHAIQUANC
000005    JSZQXYDQZQ  嘉实增强信用定期债券   债券型-长债  JIASHIZENGQIANGXINYONGDINGQIZHAIQUAN

变成了我们想要的dataframe数据格式。

4、文件打包

我将上述文件保存为了.py格式的文本,大家可以将该文本放入到代码文件夹中,然后通过import的方式直接调用,例如:

import fund_api as fa
fundlist = fa.getfundlist()
print(fundlist.head())

查看一下输出结果:

jiancheng        name     type                     pingyinquangcheng
fundcode                                                                       
000001        HXCZHH      华夏成长混合   混合型-灵活                 HUAXIACHENGZHANGHUNHE
000002        HXCZHH  华夏成长混合(后端)   混合型-灵活                 HUAXIACHENGZHANGHUNHE
000003      ZHKZZZQA    中海可转债债券A  债券型-可转债          ZHONGHAIKEZHUANZHAIZHAIQUANA
000004      ZHKZZZQC    中海可转债债券C  债券型-可转债          ZHONGHAIKEZHUANZHAIZHAIQUANC
000005    JSZQXYDQZQ  嘉实增强信用定期债券   债券型-长债  JIASHIZENGQIANGXINYONGDINGQIZHAIQUAN

可以正常调用。