基于tushare股票数据实现股票行情展示

博主因毕设需要股票金融大数据,使用tushare股票金融API获取数据。介绍了相关技术,如用Python Flask封装接口,开发微信小程序展示;还提及工具,像PyCharm、Navicat等。详细说明了获取沪深股票列表和股票/指数k线数据的方法及注意事项。

前言

注:数据来源:tushare
       署名:406940
由于毕设题材是股票金融大数据方向的,需要大量的股票数据来实现项目,依靠个人的力量去解决不太现实,所以就使用tushare股票金融API来获取数据

技术与工具

技术

Python Flask Restful API封装数据API接口方便前端调用
微信小程序开发小程序前端展示界面

工具

PyCharm:python代码逻辑编程工具
Navicat:数据库可视化工具
Postman:接口测试工具
微信开发者工具:小程序代码逻辑编程工具

数据获取

新版tushare调用接口时需要验证用户token,将验证逻辑单独存储到一个文件或者__init__文件里方便后面调用

import tushare as ts

# 设置token
ts.set_token('your token')
# 初始化pro接口
pro = ts.pro_api()

接下来就开始我们的数据获取之旅~

获取沪深当前所有正常上市交易的股票列表
from app.spiders import pro

# 获取深沪所有上市股票列表
def take_stock_list():
    # 查询当前所有正常上市交易的股票列表,行业板块
    data = pro.stock_basic(exchange='', list_status='L',
                           fields='ts_code,symbol,name,area,industry,fullname,enname,market,exchange,list_date,is_hs')
    data_list = data.values.tolist()
    return data_list

你可以直接将获取到的数据导入到数据库生成数据表,注意直接生成的数据表搜索字段类型都是str,所以需要二次人为修改

from sqlalchemy import create_engine
# 格式:# engine = create_engine('mysql+cymysql://账号:密码@localhost:3303/数据表?charset=utf8')
engine = create_engine('mysql+cymysql://root:123456@localhost:3303/stock?charset=utf8')
# 存入数据库
data.to_sql('stock_list', engine)

但是flask有表关联,我的项目也需要表关联,所以自定义数据表循环导入数据

from datetime import datetime
from sqlalchemy import Column, Integer, String, SmallInteger
from app.models.base import Base, db


class Stock(Base):
    id = Column(Integer, primary_key=True)
    ts_code = Column(String(9), unique=True, nullable=False)
    symbol = Column(String(6), unique=True, nullable=False, index=True)
    name = Column(String(50), unique=True, nullable=False, index=True)
    area = Column(String(20), nullable=True)
    industry = Column(String(50), nullable=True)
    fullname = Column(String(200), unique=True, nullable=False)
    enname = Column(String(200), nullable=False)
    market = Column(String(20), nullable=False)
    exchange = Column(String(10), nullable=True)
    list_date = Column(String(8), nullable=False)
    is_hs = Column(String(2), nullable=True)

    @property
    def list_datetime(self):
        if self.list_date:
            return datetime.fromtimestamp(self.create_time)
        else:
            return None

    @staticmethod
    def save(data):
        with db.auto_commit():
            stock = Stock()
            stock.ts_code = data[0]
            stock.symbol = data[1]
            stock.name = data[2]
            stock.area = data[3]
            stock.industry = data[4]
            stock.fullname = data[5]
            stock.enname = data[6]
            stock.market = data[7]
            stock.exchange = data[8]
            stock.list_date = data[9]
            stock.is_hs = data[10]

            db.session.add(stock)
# 添加股票列表
@api.route('', methods=['GET'])
def stock_add():
    stock_list = take_stock_list()
    [Stock.save(data) for data in stock_list]
    return Success()
获取股票 / 指数的日 / 周 / 月 k线数据

股票和指数的k线数据接口很相似,因为不想多实现一个接口,就需要实现接口复用逻辑。这些数据不用保存数据库,数据量过多也没必要(当然如果你做回测啥的就绪需要保存了),直接调用tuahsre接口即可。
对比一下两种数据接口

# 股票
f = pro.daily(ts_code='000001.SZ', start_date='20180701', end_date='20180718')
# 指数
df = pro.index_daily(ts_code='399300.SZ', start_date='20180101', end_date='20181010')

发现就接口名称不一样而已,那我们可以通过传参来区别它们:
参数time表示请求的k线类型,第二个参数category表示请求的是股票还是指数

@api.route('/<string:time>/<string:category>', methods=['GET'])
def get_daily(time, category):
    if time and category:
        form = QuotationForm().validate_for_api()
        if form.validate():
            data = get_stock_for_time(time, category, form.ts_code.data, form.start_date.data, form.end_date.data)
            return jsonify(data), 201
        return NotFound()
    else:
        return ParameterException()

有了接口传递过来的参数数据,我们就可以来定义tushare请求,当然这其中还涉及到pandas和numpy科学计算库的使用

from app.libs.error_code import ParameterException
from app.spiders import pro
import pandas as pd
import numpy as np


def take_stock(df):
    """
    绘制k线数据一般只需'open', 'close', 'high', 'low',也就是开价、收价、最高、最低
    完整的话需要时间列表和拼接成交量列表
    """
    # 通过open 和 close的相减结果赋值给新增列
    df['vol_type'] = df['open'] - df['close']
    # 获取股票的open,close,high,low
    k_data = pd.DataFrame(df, columns=['open', 'close', 'high', 'low'])

    for i in range(len(df)):
        # 修改时间列格式
        df.iloc[i, 0] = f'{df.iloc[i, 0][0:4]}-{df.iloc[i, 0][4:6]}-{df.iloc[i, 0][6:]}'
        # 判断vol_type列每个值的大小,大于0修改为1,小于0的修改为-1
        df.iloc[i, 6] = 1 if float(df.iloc[i, 6]) >= 0 else -1
    # 提取时间列
    k_time = pd.Series(df['trade_date'])
    # 生成一个DataFrame,用来存储成交量列表数据
    k_vol = pd.DataFrame()
    k_vol['index'] = pd.Series(np.arange(len(df))[::-1])
    k_vol['vol'] = df['vol']
    k_vol['vol_type'] = df['vol_type']
    # 将dataFrame中某一列的属性类型转换成int
    k_vol[['index', 'vol', 'vol_type']] = k_vol[['index', 'vol', 'vol_type']].astype('int')
    # print(df)
    return {
        'k_time': k_time.to_list()[::-1],
        'k_vol': k_vol.values.tolist()[::-1],
        'k_data': k_data.values.tolist()[::-1]
    }


def get_stock_for_s(time, ts_code, start_date, end_date):
    if time == 'd':  # 日k
        df = pro.daily(ts_code=ts_code, start_date=start_date, end_date=end_date,
                       fields='trade_date,open,close,high,low,vol')
    elif time == 'w':  # 周k
        df = pro.weekly(ts_code=ts_code, start_date=start_date, end_date=end_date,
                        fields='trade_date,open,close,high,low,vol')
    elif time == 'm':  # 月k
        df = pro.monthly(ts_code=ts_code, start_date=start_date, end_date=end_date,
                         fields='trade_date,open,high,low,close,vol')
    else:
        raise ParameterException()

    result = take_stock(df)
    return result


def get_stock_for_i(time, ts_code, start_date, end_date):
    if time == 'd':  # 日k
        df = pro.index_daily(ts_code=ts_code, start_date=start_date, end_date=end_date,
                             fields='trade_date,open,close,high,low,vol')
    elif time == 'w':  # 周k
        df = pro.index_weekly(ts_code=ts_code, start_date=start_date, end_date=end_date,
                              fields='trade_date,open,close,high,low,vol')
    elif time == 'm':  # 月k
        df = pro.index_monthly(ts_code=ts_code, start_date=start_date, end_date=end_date,
                               fields='trade_date,open,high,low,close,vol')
    else:
        raise ParameterException()

    result = take_stock(df)
    return result


def get_stock_for_time(time, category, ts_code, start_date, end_date):
    if category == 's':  # 股票
        result = get_stock_for_s(time, ts_code, start_date, end_date)
    elif category == 'i':  # 指数
        result = get_stock_for_i(time, ts_code, start_date, end_date)
    else:
        raise ParameterException('Request category cannot be empty~')

    return result


if __name__ == '__main__':
    data = get_stock_for_time('d', 'i', '000001.SH', '20180101', '20210106')
    print(data)
    # get_stock_time_sharing('000568')

总结

好啦~分享就到这了,有什么问题欢迎大家在评论区留言。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九月镇灵将

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值