今天我们来分享一个 Flask 小应用,如何动手实现一个简易的在线股票 K 线图表。我们需要用到的知识包括 PyEcharts 的使用,tushare 库获取股票数据的方法以及 Flask 的基本用法。
获取股票数据
我们先来看下 tushare 的使用,这个应该时当前最为流行的股票数据库了吧,一行代码,就能轻松获取某支股票的历史数据
import tushare as ts df = ts.get_hist_data('000001') print(df)
现在股票的历史数据有了,我们还需要一份股票名称和股票代码的对应表,同样通过 tushare 来获取
stock_list = ts.get_stock_basics() stock_list.reset_index(inplace=True) stock_list[['code', 'name']].to_csv('stock_code_name.csv')
这样就成功保存了一份股票名称和股票代码的对应数据
PyEcharts 作图
下面再来看看如何通过 PyEcharts 来制作 K 线图,其实官网上的例子已经非常具体了,我们只需要把拿到的历史股票数据做些简单处理即可,我这里直接给我的数据处理过程
mydate = df[:30].index.tolist() mydata = df[:30][['open', 'close', 'low', 'high']].values.tolist() def kline_base(mydate, data) -> Kline: c = ( Kline() .add_xaxis(mydate) .add_yaxis("kline", data) .set_global_opts( yaxis_opts=opts.AxisOpts(is_scale=True, splitarea_opts=opts.SplitAreaOpts( is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=1) ), ), xaxis_opts=opts.AxisOpts(is_scale=True, axislabel_opts=opts.LabelOpts(rotate=-30)), title_opts=opts.TitleOpts(title="Kline-基本示例"), datazoom_opts=[opts.DataZoomOpts()], ) ) return c kline_base(mydate, mydata).render_notebook()
这样就可以得到一个不错的 K 线图了
下面我们就可以着手完成 Flask 的代码啦
构建 Web 框架
首先我们先来完成 Web 框架的整体编写,为了页面的美观与编码的方便,直接使用 bootstrap 来构建前端页面
视图函数编写
首先完成初始化工作,在项目目录下创建一个 app.py 文件
from flask import Flask, render_template, request from pyecharts import options as opts from pyecharts.charts import Kline import tushare as ts import pandas as pd from flask_bootstrap import Bootstrap app = Flask(__name__) bootstrap = Bootstrap(app)
导入需要用到的库,并完成 flask app 的初始化工作。
接下来在写一个 404 的视图函数,统一处理所有的 Not Found 页面
@app.errorhandler(404) def page_not_found(e): return render_template("404.html"), 404
接着我们绑定根地址到 index 视图函数上,返回到 index.html 模板文件上
@app.route("/") def index(): return render_template("index.html")
模板编写
在同级目录创建一个 templates 文件夹,创建三个 HTML 文件,分别为 404.html,base.html 和 index.html
base.html 时所有其他页面 HTML 模板的母模板
{% extends "bootstrap/base.html" %} {% block title %}我的股票走势网站{% endblock %} {% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Stock-Data</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">Home</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> {% block page_content %} {% endblock %} </div> {% endblock %}
创建一个导航栏,并定义相关的 block 内容
接下来编写 404.html 文件,展示非法 url 请求地址时的页面
{% extends "base.html" %} {% block title %}Page Not Found{% endblock %} {% block page_content %} <div class="page-header"> <h1>Not Found</h1> </div> {% endblock %}
对于 index.html 文件,就是我们需要展示 K 线图的页面,我们后面再处理。
编辑主逻辑
首先编写一个检查股票正确性的函数
def check_stock(code): n = 0 l = [] stock_code = pd.read_csv("stock_code_name.csv", dtype=object) stock_code.drop('Unnamed: 0', axis=1, inplace=True) stock_list = stock_code.values.tolist() for i in stock_list: if code in i: n += 1 l = i else: continue return n, l
如果股票正确,则返回 n=1,否则返回 n=0
接下来再编写获取股票数据的函数
def get_stock_data(code, ctime): df = ts.get_hist_data(code) mydate = df[:ctime].index.tolist() mydata = df[:ctime][['open', 'close', 'low', 'high']].values.tolist() return [mydate, mydata]
下面就是把 PyEcharts 集成到 Flask 应用了,可以按照官方的教程走,把 PyEcharts 的样式文件等拷贝到自己的 templates 目录下,再编写一个用于调用 kline_base() 函数的视图函数
@app.route("/Kline", methods=['GET', 'POST']) def get_kline_chart(): stock_name = request.form.get('stockName') query_time = request.form.get('queryTime') if not stock_name: stock_name = '平安银行' if not query_time: query_time = 30 status, stock_code = check_stock(stock_name) if status == 0: return 'error stock code or name' mydate, mydata = get_stock_data(stock_code[0], int(query_time)) c = kline_base(mydate, mydata, stock_code[1]) return c.dump_options()
首先通过 request 变量获取到前端传递过来的数据,分别为 stockName 和 queryTime,如果这两个参数是空值时,则赋予它们一个默认值。
接着判断股票代码的正确性并获取股票历史数据。
最后调用 kline_base 函数画出 K 线图,并渲染到前端页面上。
前端页面编写
最后我们来完成前端页面的工作
首先定义一个表单,用于传递股票名称,查询时间
<form id="form1" onsubmit="return false" action="#" method="post"> <p id="p1">股票名称: <input name="stockName" type="text" id="stockName" tabindex="1" size="16" value="" placeholder="股票名称"/> </p> <p id="p2">查询时间: <input name="queryTime" type="text" id="queryTime" tabindex="2" size="16" value="" placeholder="输入30查询近30天数据"/> </p> <p><input type="submit" value="查询" onclick="getData()"></p> </form>
然后就是通过 JQuery 来动态获取数据
function getData() { var chart = echarts.init(document.getElementById('kline'), 'white', {renderer: 'canvas'}); $.ajax({ type: "POST", dataType: "json", url: "/Kline" , data: $('#form1').serialize(), success: function (result) { chart.setOption(result); }, error: function() { alert("错误的股票代码!"); } }); }
最后我们看下整体的效果
是不是效果还不错呢,后面还可以继续添加功能来完善我们的小小网站!