Flask 掃盲系列-在線股票走勢圖

今天咱們來分享一個 Flask 小應用,如何動手實現一個簡易的在線股票 K 線圖表。咱們須要用到的知識包括 PyEcharts 的使用,tushare 庫獲取股票數據的方法以及 Flask 的基本用法。html

獲取股票數據

咱們先來看下 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')
複製代碼

這樣就成功保存了一份股票名稱和股票代碼的對應數據ajax

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 線圖了json

下面咱們就能夠着手完成 Flask 的代碼啦flask

構建 Web 框架

首先咱們先來完成 Web 框架的總體編寫,爲了頁面的美觀與編碼的方便,直接使用 bootstrap 來構建前端頁面bootstrap

視圖函數編寫

首先完成初始化工做,在項目目錄下建立一個 app.py 文件canvas

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 的初始化工做。bash

接下來在寫一個 404 的視圖函數,統一處理全部的 Not Found 頁面app

@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("錯誤的股票代碼!");
                }
            });
        }
複製代碼

最後咱們看下總體的效果

是否是效果還不錯呢,後面還能夠繼續添加功能來完善咱們的小小網站!

相關文章
相關標籤/搜索