⼿把⼿教你利⽤Python爬⾍分析基⾦、股票(实现财富⾃由)
yk 坤帝
42篇原创内容
来源:nxw.so/5cOIp
python爬虫开发从前⼤家朋友圈都在晒美⾷,晒旅游,晒玩乐,现在翻来朋友圈⼀看,竟然有很多⼈在晒炒股。这是⼀个好现象,说明⼈民⽇益增长的美好⽣活需要,已经从温饱休息,变成了投资和理财。股票和基⾦等似乎依在通货膨胀的时代,钱放着就是在贬值。如果你有余钱且有些许碎⽚化时间的话,投资和理财是很有必要的。股票对于⼤部分散户来说,⽆疑是坐等着被割⾲菜。所以,⽐起股票,对于散户,我更建议买⼀些基经常会听到别⼈喜欢给⼈推荐股票,这种⼈都是新⼿。因为真正经历了股海沉浮的⼈,是不敢给⼈推荐股票的,这句话懂的⼈都懂。每⼀个炒股的⼈,都应该有⾃⼰的选股系统,否则,你凭别⼈推荐赢得的钱,我想了想,花了⼀天的时间,爬了些数据,写了两个基⾦推荐的程序。⼀个是⽹上流⾏的 4433 法则,另外⼀个我⾃⼰想的,基于最受欢迎股票的持仓稳合度。我不买基⾦。需要我推荐基⾦的可以我。去年来不妨和⼤家分享⼀下我的选股和选基⾦的思路。简单来说就是“抄作业”。
作为专业投资机构,基⾦公司选择股票都有特定的程序,⼀般基⾦公司有⾃⼰的研究⼈员,研究⼈员把⾃⼰的研究结果汇总给基⾦经理,基⾦公司也会从券商的研究机构那⾥付费买研究报告,另外,基⾦公司的作为普通⼈,我们⼤概率是⽐不上这些机构的。那么我们应该怎么做?我们可以抄基⾦公司的作业呀,把别⼈的成果据为⼰有,站在巨⼈的肩膀上看问题,不⾹么。现在问题来了,根据法律规定基⾦公司在特定学数据科学的应该清楚,数据分析的三板斧,其实⾮常有⽤的⼀招就是“count”(数数),⼩学就会的,最简单的,也是⾮常有效的。
废话不多说,直接上菜。
第⼀步:基⾦数据爬取
打开天天基⾦⽹(fund.eastmoney/),通过浏览器的开发者⼯具,我们能观察到⽤户的请求和数据的返回过程。从⽽利⽤正则表达式,以及 xpath 等⼯具,辅以⼀点 python 爬⾍的知识,很容易就能获取到我所⽤到的代码如下。
XMtool.py:
# In[]: #!/usr/bin/env python# coding: utf-8# encoding=utf-8import pandas as pdimport requestsfrom lxml import etreeimport re#import collectionsimport numpy as np
# In[]: sample = '150000'#样本数量sc = '6yzf'#排序键值st = 'desc'#排序⽅式ft = 'gp'#基⾦类型dx = '1'#是否可购season = 1#季度选择
r1r = 1#⽇增长率r1z = 1#近1周r1y = 1#近1⽉r3y = 0.3333#近3⽉r6y = 0.3333#近6⽉r1n = 0.25#近1年r2n = 0.25#近2年r3n = 0.25#近3年rjnl = 0.25#今年来rcll = 1#成⽴来
sd = '2021-01-07'ed = '2021-02-07'
# In[] 在参数⽂书写单元后加上这么⼀段就可以了#from PyQt5.QtWidgets import QInputDialog, QLineEdit, QDialogfrom PyQt5.QtWidgets import QDialogimport sysfrom PyQt5.QtWidgets import QApplicationimport dialogclass TestDialog1(QDialog,dialog.Ui_XMto app=QApplication(sys.argv) dlg=TestDialog1() dlg.show() _()
sample = () #样本数量sc = dlg.sc.currentText() #排序键值st = dlg.st.currentText() #排序⽅式ft = dlg.ft.currentText() #基⾦类型dx = dlg.dx.currentText() #是否可购season = int(dlg.season.currentText()) #季度选择
r1r = float(()) #⽇增长率r1z = float(())#近1周r1y = float(())#近1⽉r3y = float(())#近3⽉r6y = float(())#近6⽉r1n = float(())#近1年r2n = float(())#近2年r3n = float(())#近3年
# In[]:header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', 'Referer': 'fund.eastmoney/data/fundranking.html', 'Cookie':'st_si=74949607860286; st_asi=delete # In[]:df_picked_part = df_partrates = [r1r,r1z,r1y,r3y,r6y,r1n,r2n,r3n,rjnl,rcll]i = -1for sc in ['⽇增长率', '近1周', '近1⽉', '近3⽉', '近半年', '近1年', '近2年', '近3年', '今年来', '成⽴来']: i = i+1 #print(sc) rate = rates[i] rate_num = int(total*rate) df_tmp = df_part.sort_values # In[]:rank_codes = df_part['基⾦代码'].list()#len_codes = len(rank_codes)stocks_array = []stock_funds = []total_part = int(total/100)+1 #每百分之⼀报⼀次进度for index, code in enumerate(rank_codes):# if index < 1:# print('<' * 30 + '所有基⾦的股票池前1
# In[]:stock_info_list = []for row in df_funds_info_extend.iterrows(): tenpos = row[1]['⼗⼤重仓'] fund_jc = row[1]['基⾦简称'] if len(tenpos)!=0: tmp = [tenpos[0][0],fund_jc,tenpos[0][1],tenpos[0][2],tenpos[0][3]] stock_info_list.append(tmp)df_stock_info = pd.DataFra # In[]#df_stock_info.loc[:,['股票简称','持股数_万','持仓市值_万','占净值⽐例']]df_stock_info_cp = df_stock_infodf_stock_info_cp['所属基⾦cp'] = df_stock_info['所属基⾦']df_stock_info_gb = df_stock_upby('股票简称')#df_stock_info.drop(axis=1,['所属基⾦# In[]rank = 10stock_agg_result = stock_agg_result.sort_values(by='所属基⾦数⽬',ascending=False)stock_agg_result_head0 = stock_a
gg_result.head(rank)stock_agg_result = stock_agg_result.sort_values(by='被持仓市值_万',ascending=False)stock_agg_resul
dialog.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'dialog.ui'## Created by: PyQt5 UI code generator 5.9.2## WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_XMtool(object):    def setupUi(self, XMtool):        XMtool.setObjectName('XMtool')        size(701, 622)        self.verticalLayout = QtWidgets.QVBoxLayout(XMtool)        self.verticalLayout.setObjectName('verticalLayout')        self.formGroupBox        anslateUi(XMtool)        self.t(XMtool.accept)        tSlotsByName(XMtool)
def retranslateUi(self, XMtool):        _translate = anslate        XMtool.setWindowTitle(_translate('XMtool', '股林秘籍⼩明三式'))        XMtool.setToolTip(_translate('XMt
ool', '<html><head/><body><p>欢迎使⽤⼩明选股软件!</p></bod
运⾏之后,需要填⼀些参数,如下。
确定之后,除了爬下来了我们后⾯所要⽤到的全部数据之外,我们还利⽤ 4433 法则,对于基⾦进⾏了⼀个初步的分析和筛选。
第⼆步:股票增持计算
有了上⾯爬下来的原始数据之后,我们就可以统计:单股票被基⾦公司持有的数量、单股票被基⾦公司持有的市值和持有单股票基⾦公司的数⽬。对于不同的相邻季度,我们可以计算这三个量的增长,⼜得到三个新的我所⽤的代码如下:
#!/usr/bin/env python# coding: utf-8# In[]:import pandas as pd#import osimport tkinter as tkfrom tkinter import filedialogdef getLocalFile(): root=tk.Tk() root.withdraw() filePath=filedialog.askopenfilename() print('⽂件路径:',filePath) return filePath#if __name__ == # In[]:sheet3['增持市值'] = sheet3['被持仓市值_万_x'] - sheet3['被持仓市值_万_y']#sheet3['增持占⽐'] = sheet3['平均占⽐_x'] - sheet3['平均占⽐_y']sheet3['增持基⾦数量'] = sheet3['所属基⾦数⽬_x'] - sheet3['所属基⾦数⽬_y']_csv('增持情况统计.csv'
第三步:好股基⾦选取
第⼆步中,我们其实已经得到了被基⾦公司看重的股票,如果炒股,直接取其前⼏,按其权重进⾏⾦额
配置即可。现在问题是,国内股票交易,⼀⼿起步,选出来的股票很贵,⽐如说茅台,你不⼀定买得起。这时候,下⾯是我所⽤到的代码,细节可看。
#!/usr/bin/env python# coding: utf-8
# In[]:import pandas as pd#import os
# In[]:import tkinter as tkfrom tkinter import filedialogdef getLocalFile():    root=tk.Tk()    root.withdraw()    filePath=filedialog.askopenfilename()    print('⽂件路径:',filePath)    return filePath#if __name__ == '__main__':
# In[]print('请输⼊增持情况统计:')increase_hold_add  = getLocalFile()inc = pd.read_csv(increase_hold_add,index_col = 0)inc# In[]:#print('请输⼊⽐率:')str_num = input('Enter your number: ')rate = int(str_num)rate
# In[]:
inc_sort_zcgs = inc.sort_values(by=['增持股数'], ascending=False, axis=0)inc_sort_zcsz = inc.sort_values(by=['增持市值'], ascending=False, axis=0)inc_sort_zcjjsl = inc.sort_values(by=['增持基⾦数量'], ascending=False, axis=0)inc_sort_zcgsinc_sort_zcgs = i # In[]:
print('请选择基⾦持仓:')funds_hold_add = getLocalFile()funds_hold = pd.read_csv(funds_hold_add,index_col = 0)stock_funds = funds_holdstock_fundsintersecintersec_ex = pd.merge(intersec,inc,how='inner',on='股票简称')intersec_ex['权重_增持市值'
# In[ ]:
result = []# pd.DataFrame()for row in stock_funds.iterrows():    tenpos = row[1]['⼗⼤重仓']    exec('tps='+tenpos)    fund_jc = row[1]['基⾦简称']    #tmp = [i[0] for i in tps]      #rate = [r[1] for r in tps]    list_tmp = [[i[0],i[1]] for i in tps]    df_stock_rate = pd.DataFram pd_result = pd.DataFrame(result,columns = ['基⾦简称','好股数⽬','好股占⽐','加权好股占⽐_增持市值','加权好股占⽐_增持基⾦数量'])pd_result = pd_result.sort_values(by='加权好股占⽐_增持市值',ascending=False)
pd_result = pd.merge(pd_result,stock_funds,how='inner',on='基⾦简称')
# In[]:
_csv('./基⾦持好股情况统计.csv', encoding='utf_8_sig')print('完成!按任意键退出!')stop = input()
使⽤以往的数据做个测试验证,如下:
从上图可看出,⽤我的基⾦选择策略,选出来的基⾦⼀个⽉涨跌为 15 个点,两个指数基⾦翻车,只有百分之五,勉强跑得赢上证。
“风险越⾼,收益越⾼”总是不变的铁律,从这个⾓度来看,似乎就不必纠结于哪种⽅案或者策略收益是最⾼的,差不多就⾏了。