买基金是上班族用零钱进行投资的正确姿势。而自个用数据来选基金比听别人推荐买什么基金要好上一百倍。
步骤如下:
1.获取网上的基金的排名信息,使用四四三三法则筛选出排名靠前的基金。2.获取网上的基金的基本信息和夏普比率,筛选出夏普比率高的基金。
接下来就一步一步介绍方法。
准备工作:
使用工具是Python3。不过一般会使用conda3的安装包进行安装。一些库都会安装进来。
- 获取网上的基金的排名信息,使用四四三三法则筛选出排名靠前的基金。
天天基金网上有基金的排名,可以用Python进行抓取和筛选。四四三三法则即选择出3年/2年/1年的排名在前四分之一,6个月/3个月的排名在前三分之一的基金。
下面就是抓取的URL。(只抓取混合基金)
http://fund.eastmoney.com/data/rankhandler.aspx?op=dy&dt=kf&ft=hh&rs=&gs=0&sc=qjzf&st=desc&sd=2019-05-06&ed=2020-05-05&es=1&qdii=&pi=1&pn=5&dx=1
URL中有几个需要理解的参数。sd 和 ed 是起始和结束日期。分别对应要考察的期间。pi 对应的是页数,pn 对应的是每页的记录数。
下面就是返回的内容。有点难懂?其实只需要datas后面的内容。这个例子里可以看到最近1年共有5053支基金。那么排名四分之一就是在25%*5053=1263支基金。
(返回数据已经按照从高到低进行了排序,抽取前n支基金即可。)
Python很容易处理这些信息。
上代码进行说明。
import pandas as pd
import urllib.request
url = 'http://fund.eastmoney.com/data/rankhandler.aspx?op=dy&dt=kf&ft=hh&rs=&gs=0&sc=qjzf&st=desc&sd=2019-05-06&ed=2020-05-05&es=1&qdii=&pi=1&pn=5&dx=1'
r = urllib.request.urlopen(url, timeout=15)
content = r.read().decode('utf-8')
content2 = content[15:-1]
m = ['datas', 'allRecords', 'pageIndex', 'pageNum', 'allPages', 'allNum', 'gpNum', 'hhNum', 'zqNum', 'zsNum',
'bbNum', 'qdiiNum', 'etfNum', 'lofNum', 'fofNum']
for c in m:
content2 = content2.replace(c, '"' + c + '"')
d = {'allRecords': 0, 'pageIndex': 0, 'pageNum': 0, 'allPages': 0, 'allNum': 0, 'gpNum': 0, 'hhNum': 0,
'zqNum': 0, 'zsNum': 0, 'bbNum': 0, 'qdiiNum': 0, 'etfNum': 0, 'lofNum': 0, 'fofNum': 0}
d = eval(content2)
num = int(d['allRecords'])
df = pd.DataFrame.from_records(pd.Series(d['datas']).str.split(',').values)
df_fin = df[[0, 1, 2, 3]]
df_fin.columns = ['code', 'name', 'name2', 'rose(1y)']
df_fin.set_index('code', inplace=True)
df_fin['rank(1y)'] = df_fin.index + 1
df_fin['rank_r(1y)'] = df_fin['rank('1y'].astype(str) + '/' + str(num)这样就把数据抽出了。当然,只是部分。需要循环把数据补充完整。dataframe 内的数据是这样的。
2. 获取网上的基金的基本信息和夏普比率,筛选出夏普比率高的基金。
通过四四三三法则选择出排名靠前的基金共有171个。需要继续进行筛选。目标是从171支基金里选出20支基金。规则是资金规模超过1亿的高夏普比率的基金。
同样从天天基金网获取资金规模和获取夏普比率。URL如下。
http://fund.eastmoney.com/f10/006279.html
http://fund.eastmoney.com/f10/tsdata_006279.html
Python很容易处理。
url = 'http://fund.eastmoney.com/f10/006279.html'
tables = pd.read_html(url)
df = tables[1]
df1 = df[[0, 1]]
df2 = df[[2, 3]]
df1.set_index(0, inplace=True)
df2.set_index(2, inplace=True)
df1 = df1.T
df2 = df2.T
df1['code'] = '006279'
df2['code'] = '006279'
df1.set_index('code', inplace=True)
df2.set_index('code', inplace=True)
df_fin2 = pd.concat([df1, df2], axis=1)dataframe 内的数据是这样的。
url2 = 'http://fund.eastmoney.com/f10/tsdata_006279.html'
tables2 = pd.read_html(url2)
df = tables2[1]
df['code'] = '006279'
df.set_index('code', inplace=True)
df.drop(u'基金风险指标', axis='columns', inplace=True)
df_fin3 = df[1:]
df_fin3.columns = u'夏普比率(' + df_fin3.columns + ')'dataframe 内的数据是这样的。
接下来把这些dataframe粘在一起就可以了。
df_fin4 = df_fin2.combine_first(df_fin3)
df_fin4 = df_fin.combine_first(df_fin4)把3年/2年/1年/6个月/3个月的排名乘上权重(0.3/0.25/0.2/0.15/0.1)计算综合排名并排序。取前50条数据。
df_fin4['rank'] = df_fin4['rank_r2(3y)'] * 0.3 + df_fin4['rank_r2(2y)'] * 0.25 + df_fin4['rank_r2(1y)'] * 0.2 + df_fin4['rank_r2(6m)'] * 0.15 + df_fin4['rank_r2(3m)'] * 0.1
df_fin4.sort_values(by='rank', inplace=True)
df_fin5 = df_fin4[:50]再按照夏普比率进行排名,取前20条数据。
cols = ['基金代码', '基金简称', '基金管理人', '基金类型', '基金经理人',
'rank_r(3y)', 'rank_r(2y)', 'rank_r(1y)', 'rank_r(6m)', 'rank_r(3m)',
'rose(3y)', 'rose(2y)', 'rose(1y)', 'rose(6m)', 'rose(3m)',
'夏普比率(近3年)', '夏普比率(近2年)', '夏普比率(近1年)', '资产规模(亿)']
df_fin5.sort_values(by=['夏普比率(近3年)', '夏普比率(近2年)', '夏普比率(近1年)'], ascending=False, inplace=True)
df_fin7 = df_fin6[:20][cols]最后导出到CSV里看一下。
df_fin7.to_csv('out7.csv', encoding='gbk', index=False)
如何样?自个通过数据选择出来的基金是不是买起来更安心? |