【Dash搭建可视化网站】项目9:智能选股器(结合行业、换手率、量比与60日k线图选择目标股票)
- 1 项目效果图
- 2 项目架构
- 3 文件介绍和功能完善
- 3.1 assets文件夹介绍
- 3.2 app.py和index.py文件完善
- 3.3 layoutleft.py文件完善
- 3.4 api.py和api.ipynb文件完善
- 3.5 layputmiddle文件完善
- 3.6 layoutright.py文件完善
- 4 样式修改
- 4.1 调整整体风格样式
- 4.2 调整左侧栏的样式
- 4.3 调整中侧栏的样式
- 4.4 调整右侧栏的样式
手动反爬虫: 原博地址 https://blog.csdn.net/lys_828/article/details/128599088
知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息
1 项目效果图
整个项目的页面包含三部分,由左中右三栏构成。项目已上传至个人Github仓库。
左侧栏是进行筛选的依据,中侧栏返回的是筛选的结果,右侧栏是根据鼠标点击任意单元格中返回当前单元格所对应股票的近60日的交易k线图。
2 项目架构
项目中各文件名称与对应功能见下表
3 文件介绍和功能完善
为了方便后续管理和查看项目,对于项目的起名可以设立一个标准,本项目的名称标准:【项目数. 项目名称】组件1-组件2-组件3-组件4,如:【9. Stock selecting】Dropdown-Rangeslider-Dashtable-Klinefigure。
3.1 assets文件夹介绍
assets文件夹中就是加载的样式和图片,样式这里可以使用之前已经下载好的bootstrap.min.css样式(也可以按照 项目6.2bootstrap组件 中的介绍下载其它的样式模板),本次项目中不需要加载本地图片。
3.2 app.py和index.py文件完善
主框架就是app.py项目初始化文件和index.py主程序运行文件,其中app.py文件中的信息较为简单,就是创建一个dash的应用,代码如下
index.py文件中引入初始化后的应用,然后进行布局及运行初始化设置。布局采用一行三列的方式,左侧栏的宽度为2,中侧栏宽度为5,右侧栏宽度为自动填充,也就是5,可以不用指定width
。
运行index.py,打开页面端口http://127.0.0.1:8050/,界面结果如下
然后把布局中的各项内容拆分到对应的文件中
接着就是在对应的文件中创建相关函数,layoutleft.py文件中的内容是
layoutmiddle.py文件中的内容是
layoutright.py文件中的内容是
3.3 layoutleft.py文件完善
由于整个项目的工作流是从左到右,所以先把layoutleft.py文件中的内容初步整出来,首先设置Dropdown组件,组件的内容先使用简单的示例数据,待整个左侧栏的组件都布置完毕后再调整数据。
然后再设置Rangeslider组件,直接把官网中的示例复制粘贴下来,设置滑动条的起始点、滑动间隔、默认选取的区间、不显示标签,使用浮点组件显示滑动数值
保存修改后的layoutleft.py文件后,重新运行index.py,此时在网页中可以看到左侧的组件显现出来了。此时Dropdown组件中可以进行标签选择,Rangeslider组件中的滑块也可以正常拖动
3.4 api.py和api.ipynb文件完善
其中api.py文件是为提供数据接口,api.iypnb文件方便进行数据处理和调式工作。左侧栏组件布置完毕后,需要进行数据的导入,使用到的股票数据来自于tushare这个模块,具体的使用说明文档可以参照tushare官网
借助api.iypnb方便查看运行结果,能够针对变量进行交互式输出,所以在构建数据接口时,先在api.ipynb文件中确认无误后,再把代码复制粘贴到api.py文件中。先解决Dropdown组件的标签信息,借助pro.stock_basic()
函数获取股票的所有行业,其中打马赛克的地方是要输入自己的TOKEN。
由于获取的数据中股票和行业是多对一的关系,即一个行业可以发行多支股票,所以获取行业数据时,先去唯一值,然后由于数据中存在空值,需要进行去重,代码及输出结果如下。
核实无误,可以把代码全部复制粘贴到api.py文件中保存,内容如下
然后在layoutleft.py文件中导入数据industry_list变量,然后把存放标签的列表替换掉,并重新设置一个默认值,如下。
此时刷新网址,Dropdown组件的标签信息就被替换掉了
而对于Rangeslider组件,由于要采用多个滑动选择条,所以对于重复的代码可以封装成为一个函数。对于各种指标,可能取值的范围以及设定的默认范围不同,因此可以设置几个参数进行控制,Slider函数是用来控制每一个滑动条,还需要使用一个name变量接受显示的指标名称,默认指标范围是-10到10,间隔未指定,默认滑动范围是-2到2。
更改之后保存,刷新网址后,
3.5 layputmiddle文件完善
由于此栏需要根据左侧栏的选择进行更新,所以只需要设置一个表格容器即可,里面需要指定id
,然后回调时候返回的就是data
,而接受的输入来自于左侧的Dropdown组件和Rangeslider组件的输入值。首先测试一个输入的传递,以Dropdown组件中的id
,传入的就是行业标签的value
,容易忽视的一点就是回调的内容需要把DataFrame数据类型转化一下,借助to_dict('records)
方法,具体代码如下。
保存修改后,刷新网页,中侧栏能够正确输出表格信息,在点击左侧栏的下拉选项标签后,表格信息会进行交互变化,结果如下
然后再添加Rangeslider组件中的筛选条件,代码如下。注意此时update()
函数中变量的个数需要和Input()
函数的个数一致,如果第一次使用该组件,不清楚返回的数据类型,可以尝试直接print
打印对应变量。
保存文件后,刷新界面,随着鼠标滑动选择条,此时终端输出对应的选择范围
筛选条件的功能满足了,接下来就是在获取的股票数据中添加换手率和量比的字段数据(根据个人选择股票的标准,还可以指定其它的指标),在tushare官网中,此两指标在每日行情的数据接口下,但是要想获取此数据,需要达到对应的积分要求。
有些同学只是想了解一下整个流程,并不是想要进行炒股,对于2000积分需要200RMB那么就不必要了,可以自行构造数据。需要使用到random模块下面的choice()
函数,回到api.ipynb文件中,根据表格df的长度构建随机数据的长度。其中warnings模块是对提示的警示进行忽略。
由于表格的数据是基于左侧栏的筛选回调生成,所以把代码复制粘贴到api.py文件中时,可以封装函数add_fields()
,只需要保留一个筛选行业标签的参数即可。
然后回到layoutmiddle.py文件中,把add_fields
函数导入,并把回调部分的代码进行修改。
保存文件后刷新界面,核实是否表格中的字段添加了“换手率”和“量化”的信息,输出结果如下,实现了对应筛选字段的添加。
结合Rangeslider组件的筛选结果进行表格数据的筛选。由于滑动滑块,回调返回的结果是一个列表,因此,可以尝试在api.ipynb文件中践行筛选,核实无误后在添加到回调中。具体筛选的方式为df[(df['字段']>最小值) & (df['字段']<最大值)]
。
核实无误后添加到回调中,由于Rangeslider组件的筛选结果是列表,所以需要进行元素索引。表格输出结果中不需要全部的字段,可进行部分字段的展示,代码中只提取了五个字段,并对字段进行重新命名,代码如下。
保存文件后刷新界面,滑动左侧的滑块,表格部分的数据会发生相应的变化
在结合下拉菜单栏的功能,就可以实现左侧的所有的筛选,比如选择摩托车,输出结果如下
3.6 layoutright.py文件完善
由于次本分内容也是基于回调得到的,因此只需要创建一个容器即可,标记容器的id
为content
,用于回调。具体回调的方式,可以采用之前项目7宝可梦案例中通过点击单选按钮实现一行数据的选择,这里提供另外一个方式,即是通过鼠标点击单元格,系统返回当前单元格所在的坐标信息,进一步通过坐标可以获取当前行数据。输入的内容变成了active_cell
,可以打印输入的值,然后测试回调输出的结果,这里就简单使用demo
字符串核实输出是否正常。
保存文件后,刷新网址,点击表格中的数据,在终端和网页的右侧部分均正常显示。
由于是要获取鼠标点击单元格所在的行记录,从而实现获取当前行记录中的股票名称,故需要使用表格中的data
,因此需要加入另一个输入,然后结合着表格数据的提取功能,成功提取股票名称,并显示在右侧栏中。
核心代码:v1 = pd.DataFrame(v2).iloc[v1['row'],0] if v1 is not None else v2[0]['股票代码']
。
代码解读:由于默认加载后,没有任何鼠标点击事件,所以v1
的返回值就是None
,此时设置当前表格的第一行数据中的股票代码为v1
,如果是点击鼠标就是采用DataFrame按照坐标筛选数据的方式,获取股票代码,其中iloc[]
括号中的第一个参数代表着行,也就是v1
返回字典中的row
键对应的值,而股票代码是在表格的第1列,也就对应第二个参数0。
保存文件后,刷新网址,默认和点击单元格后,在右侧均可正常生成对应行的股票代码数据。
最后一步就是,基于股票代码获取股票的交易信息,绘制60天内交易日的k线图。 股票的交易信息可以通过pro.daily()
函数获取,回到api.ipyynb文件中,测试根据股票代码获取交易信息。比如获取上图中第一行记录对应的股票代码002726.SZ
的所有交易信息。
此外结合着交易时间的限制,指定交易时间结束于当前日期的最后一个交易日,开始于60天内的第一个交易日。tushare专门提供的有一个交易日判断的接口,借助trade_cal()
函数或者pro.query('trade_cal')
函数获取日期的是否交易信息,1代表当前日期为交易日,0代表非交易日。首先解决当前日期和相差60天的日期的获取,然后就是把日期的格式转化为tushare中可以直接用的时间格式,代码如下。当前测试的日期为2023年1月8号,往前推就是2022年11月9号(实际上应当减去59,这里减去60,函数调用后返回的内容包含了今天,因此就多了一天)。
然后把开始的日期和结束的日期传入到pro.query('trade_cal'
函数中,输出结果如下。
最后就可以获取60内的交易日信息。由于上图的输出结果中今天的日期数据在最后一条,所以获取时对应iloc[-1]
,而60天中的第一个交易日对应iloc[0]
。获取是在筛选is_open字段中的内容为1的基础上,也就是获取交易日的信息。
使用交易数据绘制k线图,官网示例如下。
首先需要把筛选交易日,以及目标股票代码信息的获取代码复制粘贴至api.py文件中,如下。
然后把需要使用到的方法和变量导入到layoutright.py文件中,并按照官网k线图的示例,修改字段的名称。使用pro.daily()
函数获取的数据中,对应字段分别为trade_date、open、high、low、close五个字段,如下。
layoutright.py文件修改的代码示例如下。
保存文件后刷新网址,此时页面中能够正常显示右侧栏中的文字和k线图。点击单元格或者调整左侧栏的筛选值,右侧的结果也会跟随变化。
至此整个项目的全部功能就实现了,最后就是对项目的样式进行修改,比如背景,对齐和一些小细节的地方。
4 样式修改
4.1 调整整体风格样式
在assets文件夹下新建一个setting.css文件,设置整体风格。最后一行的overflow-y设置是参照实战7中3.4 table.py文件完善部分防止全部全局撑开后网页抖动的设置,具体介绍可以参考实战7。
保存文件后,此时网页中信息如下。
中间的部分滑条显示当前的内容并没有全部撑开,未实现跟随浏览器的大小扩展全部,因此可以设置index.py文件中Col()中的属性值为vh-100,这里选择是左侧栏,也可以选择中侧栏或者右侧栏,代码如下。
此时界面中内容全部撑开,结果如下。
4.2 调整左侧栏的样式
首先在左侧栏中添加一个右侧的分割线,并设置颜色为暗色。只需要在className
属性中再添加border-right
和border-dak
两个属性。
此时的网页中出现分割线,如下。
然后调整组件的对齐和间距问题,首先所有的组件都是比较靠左,可以考虑设置居中,然后Dropdown组件中的“行业选择”与浏览器的顶端太近,Rangeslider组件中的“指数参数”与Dropdown组件的上端距离太近,都需要进行调整。
自定义新增一个siber
属性,在setting.css文件中修改padding
值,左侧为30px
,右侧为15px
,在index.py文件中添加此siber
属性,并在layoutleft.py文件中调整两个组件之间的距离,设置className
的值为py-2
,如下
保存三个文件后刷新网址,此时左侧栏的对齐和距离基本解决,结果如下。
最后解决下拉框中的样式,使之和主题颜色融合。网页右键进入检查界面,定位到下拉菜单的属性,如下
然后在setting.css文件中针对此属性进行调整。首先是对设定的dpd属性,也就是下拉菜单中所有的内容(*代表所有),统一设置一个样式,然后发现下拉框仍是白色,也刚好对应上面的Select-control属性,修改代码如下。
保存文件后刷新网址,网页界面如下。此时下拉菜单的问题基本上解决了,但是下拉条的样式这里需要调整一下。
在setting.css文件中添加如下代码,用于控制下拉滚动条的设置。
保存文件后刷新网址,网页界面如下。
最后还有一个外框线没有去掉,还是进行右键检查,找到对应的属性,修改的代码如下。
保存网页后,界面操作显示如下,完美解决问题。
也可以对Rangeslider组件进行调整,右键检查找到该组件的属性,然后在setting.css文件中进行修改,比如修改标签数值显示的颜色,代码如下。
保存网页后,界面操作显示如下。
4.3 调整中侧栏的样式
主要是调整首行的填充样式,表格与浏览器顶端的距离以及表格的边线设置。
保存网页后,界面操作显示如下。
4.4 调整右侧栏的样式
主要调整文字距离浏览器顶端的距离(仍然是指定className值为py-2
),以及绘制的k线图的样式。
为了方便日后对于k线图样式的调整,可以把这部分内容封装为plain_style()
函数,传入绘图对象,代码如下。
然后再添加绘制图形的数据,最后把fig
传入到dcc.Graph()
中即可,代码如下。
保存网页后,界面操作显示如下。
最后把k线图右上方的帮助栏给取消显示,右键检查后找到该组件的属性,并在setting.css文件中修改属性,如下。
最终项目的网页如下。完结撒花✿✿ヽ(°▽°)ノ✿