Python基金选取实例
目标:
选择多个周期内,同时出现在排名前列的基金
工具:
l Python3
l Pycharm——Python IDE,社区版免费
l Chrome
l Pandas,requests,lxml——用到的Python库
可能了解:
l Python爬虫
l Pandas操作
l 抓取JS生成的网页
l 纯属技术娱乐,不作为投资建议
准备数据:
1、既然是挑选基金,我们选比较热的天天基金网为例,用Chrome打开,选择基金排行
2、右键->查看源代码,我们居然找不到基金数据
3、没事,F12—Network—F5,找到用时最长的那个
4、右键—Open in new tab,然后把链接贴出来,好长……
5、数据正是我们要的,这里有两个日期,是自定义数据的开始和结束日期,我们要用到,另外有意思的是,我们已经做好一页页爬数据的准备了,但是,这里有“&pi=1&pn=50&dx=”,实验得,改成5000都木有问题。
6、有了这些就可以写代码了……
准备包:
Pycharm为例,file-settings-project inspector—加需要的包,具体怎么换源啥的,自己搜,如果不是pycharm,自己pip install或者conda install,pandas,requests,lxml,这里会自动加一些必须的包
代码部分:
1、引用包
Python Code
1 |
import pandas as pd |
2、获得网页
这个函数利用requests来获取网页信息,返回字符串
Python Code
1 |
def get_html(url): #取得HTML文本 |
3、凑出URL
这里,我们利用字符串的replace方法,来替换url中需要动态处理的部分,包括自定义时间的开始和结尾,每页显示的基金数等。
Python Code
1 |
def get_fund(): #取得基金列表 |
4、具体处理数据
这部分代码写的我并不满意,很不美观和优雅,有点凑的意思,但抱着实用主义的态度,我们就那么凑凑吧。最后返回一个Dataframe对象,并写入到相应的csv文件中。其实到了这里,已经可以直接用Excel打开这个csv分析了。
Python Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
#取得文本 s = get_html(url) #去掉冗余信息,这里应该有更好的方法,但懒得折腾了,这样简单,十分钟搞定 s = s[ 22:- 159] s = s. replace( '"', '') s = s. replace( '[', '') s = s. replace( ']', '[') lst = s. split( ',') lst = split_list(lst, 25) frame = pd.DataFrame(lst,columns=[ 'code', 'name', 'py', '3', '4', 'jz', 'day1', 'week1', 'month1', 'month3', 'month6', 'year1', 'year2', 'year3', 'year0', 'yearall', 'fromdate', '17', 'year5', '19', '20', '21', '22', '23', '24']) frame = frame.iloc[:,[ 0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18]] frame.to_csv( 'fund.csv') return frame |
5、最后的处理
这里我们可以直接用刚才的函数获得数据,也可以用刚才函数保存的数据做基础来计算。读取数据后,我们先分别对数据用不同期限的列进行排序,然后赋值给相应的Dataframe,然后去做一个交集,Dataframe的交集用merge函数,具体参数不再罗列,也可以做并集的。最后我们打印结果保存数据,以备后查。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
def main():
get_fund() #如果每次都需要用最新数据,用这句 df_full = pd.DataFrame.from_csv( 'fund.csv') #节省网络流量,就用这句 X = 50 #取排名前多少的基金 df_full = df_full.sort_values(by= 'year1', axis= 0, ascending= False) df = df_full.head(X) for xx in [ 'year1', 'year2', 'year3', 'year5', 'month6']: tmp = df_full.sort_values(by=xx, axis= 0, ascending= False).head(X) df=df.merge(tmp,on=[ 'code']) df=df.iloc[:, 0: 15] df.to_csv( 'result.csv') print(df) |
6、完整代码
import pandas as pd import requests import datetime def get_html(url): #取得HTML文本 try: r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "" #转换list维度,从1维到2维 def split_list(datas, n): length = len(datas) size = length // n + 1 if length % n else length//n _datas = [] for i in range(size): start = i * n end = (i + 1) * n _datas.append(datas[i * n: (i+1)*n]) return _datas def get_fund(): #取得基金列表 #先凑一个我们需要的URL出来 max_jj='5000' #调试5 工作5000 一页 5000行 fromstr = datetime.datetime.now().strftime('%Y-%m-%d') url = "http://fund.eastmoney.com/data/rankhandler.aspx?op=ph&dt=kf&ft=all&rs=&gs=0&sc=zzf&st=desc&sd=#custday&ed=#nowdate&qdii=&tabSubtype=,,,,,&pi=1&pn=#count&dx=1" url = url.replace('#count',max_jj) url = url.replace('#nowdate',fromstr) tostr = (datetime.datetime.now()- datetime.timedelta(days=5*365+1)).strftime('%Y-%m-%d') #5年的基金 url = url.replace('#custday',tostr) print(url) #取得文本 s = get_html(url) #去掉冗余信息,这里应该有更好的方法,但懒得折腾了,这样简单,十分钟搞定 s = s[22:-159] for x in ['"',"'",']','[']: s = s.replace(x,'') lst = s.split(',') lst = split_list(lst,25) frame = pd.DataFrame(lst,columns=['code','name','py','3','4','jz','day1','week1','month1','month3','month6','year1','year2','year3','year0','yearall','fromdate','17','year5','19','20','21','22','23','24']) frame = frame.iloc[:,[0,1,2,5,6,7,8,9,10,11,12,13,14,15,16,18]] frame.to_csv('fund.csv', encoding='utf_8_sig') return frame def main(): get_fund() #如果每次都需要用最新数据,用这句 df_full = pd.DataFrame.from_csv('fund.csv') #节省网络流量,就用这句 X = 50 #取排名前多少的基金 df_full = df_full.sort_values(by='year1', axis=0, ascending=False) df = df_full.head(X) for xx in ['year1','year2','year3','year5','month6']: tmp = df_full.sort_values(by=xx, axis=0, ascending=False).head(X) df=df.merge(tmp,on=['code']) df=df.iloc[:,0:15] df.to_csv('result.csv') print(df) main()
l 改变选取范围,例如,加入短期指标(6个月涨幅,3个月涨幅,甚至1周涨幅)的排名
l 改变样本数量,把前50名增加到100名
l 进一步爬去基金的规模、最大回撤的相关信息进行分析
l 找基金经理、基金公司的相关信息进行分析
有Python,有爬虫,有dataframe,我们想的到就能做的到。
最后,投资有风险,入市需谨慎。
原文链接:http://blog.sina.com.cn/s/blog_727a8da80102x6lx.html