如何使用Tushare和Echarts来画股票K线图

news/2024/11/29 0:42:47/

如何使用Tushare和Echarts来画股票K线图

技术支持

Tushare大数据社区官网

​ 首先介绍一下这次要使用的两个工具,Tushare是一个基于Python的金融数据接口,拥有丰富的数据内容,如股票、基金、期货、数字货币等行情数据,公司财务、基金经理等基本面数据等(详细介绍进官网)。如果你之前没有注册过Tushare,而且恰好对金融量化、金融数据分析感兴趣,不妨注册一个Tushare账号,可以获取想要的数据,点击注册。

ECharts官网

常见的数据可视化库:

  • D3.js 目前 Web 端评价最高的 Javascript 可视化工具库(入手难)
  • ECharts.js 百度出品的一个开源 Javascript 数据可视化库
  • Highcharts.js 国外的前端数据可视化库,非商用免费,被许多国外大公司所使用
  • AntV 蚂蚁金服全新一代数据可视化解决方案 等等
  • Highcharts 和 Echarts 就像是 Office 和 WPS 的关系

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表,详细介绍可进官网查看.

大白话:

  • 是一个JS插件
  • 性能好可流畅运行PC与移动设备
  • 兼容主流浏览器
  • 提供很多常用图表,且可定制(折线图、柱状图、散点图、饼图、K线图)

实现结果

先展示一下最终的结果,下面第一张图是利用Tushare和Echarts做出而来的贵州茅台的日K图,第二张图是同花顺网页版的贵州茅台的日K图。除了数据的展示不一样之外,数据的内容是一样的。

Echarts制作的贵州茅台日K
同花顺贵州茅台日K

实现步骤

1.搭建运行环境

我这里的运行环境是Python 3.8.0,Tushare的版本是1.2.62的,因为Tushare是Python的第三方包,所以需要导入,详细步骤见:说明。

# 导入tushare
import tushare as ts
# 设置token
ts.set_token('your token here')
# 初始化pro接口
pro = ts.pro_api( )

至此数据获取的环境已经搭建好了,我们来试一下获取的数据是什么样子的。

daily_data=pro.daily(ts_code='600519.SH', start_date='20210101', end_date='20210220')
print(daily_data)
printtype(daily_data)

输出的结果是下面的图中所显示的,你会发现有交易日期,开盘价,收盘价,最高价,最低价,成交量等数据。数据的形式是DataFrame类型的,也就是说daily_data具备DataFrame的一般方法和属性,因此数据的显示是从最新数据显示在最前面,但是K线需要的是最近成交的数据显示在最后面,待会我们在来处理数据的问题,这一步说明我们数据接口已经可以使用了。
在这里插入图片描述

现在开始要引入数据可视化的JavaScript文件,点击进入下载地址,会弹出下面的图片,需要下载的内容是echarts.js或者echarts.min.js都可以,下载完后要记得放到对应的工作环境中,方便后面的引入。

2.先画图

在画图之前,我们有必要对Echarts有个基本的了解,建议先去Echarts官网浏览5 分钟上手 ECharts,可以对Echarts有个基本的了解.

使用步骤:

  1. 引入 ECharts:通过标签方式直接引入构建好的 echarts 文件。

    <!DOCTYPE html>
    <html>
    <head><meta charset="utf-8"><!-- 引入 ECharts 文件 --><script src="echarts.min.js"></script>
    </head>
    </html>
    
  2. 准备一个具备大小的DOM容器,用来放图。

    <div id="main" style="width: 600px;height:400px;"></div>
    
  3. 初始化echarts实例对象

    var myChart = echarts.init(document.getElementById('main'));
    
  4. 指定配置项和数据(option)

    var option = {xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']},yAxis: {type: 'value'},series: [{data: [820, 932, 901, 934, 1290, 1330, 1320],type: 'line'}]
    };
    
  5. 将配置项设置给echarts实例对象

    myChart.setOption(option);
    

需要了解的主要配置:series xAxis yAxis grid tooltip title legend color

  • series:系列列表。每个系列通过 type 决定自己的图表类型;大白话:图标数据,指定什么类型的图标,可以多个图表重叠。
  • xAxis:直角坐标系 grid 中的 x 轴
  • boundaryGap: 坐标轴两边留白策略 true,这时候刻度只是作为分隔线,标签和数据点都会在两个刻度之间的带(band)中间。
  • yAxis:直角坐标系 grid 中的 y 轴
  • grid:直角坐标系内绘图网格。
  • title:标题组件
  • tooltip:提示框组件
  • legend:图例组件
  • color:调色盘颜色列表[]

OK,对上面的知识点有了一定的了解之后,我们可以开始来画我们需要的K线图了。我先把Echarts的全部代码先贴出来,后面在分别解释没块代码的作用。

 <!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>debug</title><style>#k-box{height: 100%;width: 50%;background: white;display: inline-block;}</style><script src="echarts.min.js"></script>
</head>
<body><div id="k-box"></div>
<script>const chartDom = document.getElementById('k-box');const myChart = echarts.init(chartDom);var option;const upColor = '#008000';const downColor = '#c00c00';// 对数据进行处理的函数,将交易日期,成交量,价格信息分别放置在不同的数组function splitData(rawData) {var categoryData = [];var values = [];var volumes = [];for (var i = 0; i < rawData.length; i++) {categoryData.push(rawData[i].splice(0, 1)[0]);values.push(rawData[i]);volumes.push([i, rawData[i][4], rawData[i][0] > rawData[i][1] ? 1 : -1]);}return {categoryData: categoryData,values: values,volumes: volumes};}// 用于计算均线的函数function calculateMA(dayCount, data) {var result = [];for (var i = 0, len = data.values.length; i < len; i++) {if (i < dayCount) {result.push('-');continue;}var sum = 0;for (var j = 0; j < dayCount; j++) {sum += data.values[i - j][1];}result.push(+(sum / dayCount).toFixed(3));}return result;}//  data的数据格式是[['交易日期',开盘价,收盘价,最高价,最低价,成交量][][]....]var data = splitData(data);myChart.setOption(option = {animation: false,legend: {bottom: 10,left: 'center',data: ['Dow-Jones index', 'MA5', 'MA10', 'MA20', 'MA30']},tooltip: {trigger: 'axis',axisPointer: {type: 'cross'},borderWidth: 1,borderColor: '#ccc',padding: 10,textStyle: {color: '#000'},position: function (pos, params, el, elRect, size) {var obj = {top: 10};obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;return obj;}// extraCssText: 'width: 170px'},axisPointer: {link: {xAxisIndex: 'all'},label: {backgroundColor: '#777'}},toolbox: {feature: {dataZoom: {yAxisIndex: false},brush: {type: ['lineX', 'clear']}}},brush: {xAxisIndex: 'all',brushLink: 'all',outOfBrush: {colorAlpha: 0.1}},visualMap: {show: false,seriesIndex: 5,dimension: 2,pieces: [{value: 1,color: downColor}, {value: -1,color: upColor}]},grid: [{left: '10%',right: '8%',height: '50%'},{left: '10%',right: '8%',top: '63%',height: '16%'}],xAxis: [{type: 'category',data: data.categoryData,scale: true,boundaryGap: false,axisLine: {onZero: false},splitLine: {show: false},splitNumber: 20,min: 'dataMin',max: 'dataMax',axisPointer: {z: 100}},{type: 'category',gridIndex: 1,data: data.categoryData,scale: true,boundaryGap: false,axisLine: {onZero: false},axisTick: {show: false},splitLine: {show: false},axisLabel: {show: false},splitNumber: 20,min: 'dataMin',max: 'dataMax'}],yAxis: [{scale: true,splitArea: {show: true}},{scale: true,gridIndex: 1,splitNumber: 2,axisLabel: {show: false},axisLine: {show: false},axisTick: {show: false},splitLine: {show: false}}],dataZoom: [{type: 'inside',xAxisIndex: [0, 1],start: 98,end: 100},{show: true,xAxisIndex: [0, 1],type: 'slider',top: '85%',start: 98,end: 100}],series: [{name: 'Dow-Jones index',type: 'candlestick',data: data.values,itemStyle: {color: upColor,color0: downColor,//改动过borderColor: upColor,borderColor0: downColor},tooltip: {formatter: function (param) {param = param[0];return ['Date: ' + param.name + '<hr size=1 style="margin: 3px 0">','Open: ' + param.data[0] + '<br/>','Close: ' + param.data[1] + '<br/>','Lowest: ' + param.data[2] + '<br/>','Highest: ' + param.data[3] + '<br/>'].join('');}}},{name: 'MA5',type: 'line',data: calculateMA(5, data),smooth: true,lineStyle: {opacity: 0.5}},{name: 'MA10',type: 'line',data: calculateMA(10, data),smooth: true,lineStyle: {opacity: 0.5}},{name: 'MA20',type: 'line',data: calculateMA(20, data),smooth: true,lineStyle: {opacity: 0.5}},{name: 'MA30',type: 'line',data: calculateMA(30, data),smooth: true,lineStyle: {opacity: 0.5}},{name: 'Volume',type: 'bar',xAxisIndex: 1,yAxisIndex: 1,data: data.volumes}]}, true);option && myChart.setOption(option);
</script>
</body>
</html>

初始化echarts实例对象,前面的DOM容器已经放好。


var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;
// 设置股票上涨和下跌的颜色
var upColor = '#008000';
var downColor = '#c00c00';

开始将图片画在网页上,我们先设置标题,即图片展示后显示的名称。

myChart.setOption(option = {// 图片的名称,字体等样式.title: {text: '股票日K',left: 0,// 设置字体样式textStyle: {fontSize:28,}},// 是否开启动画效果.animation: true,
},true);

legend图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。

在这里插入图片描述

legend: {// 距离top 9个像数.的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的			百分比,也可以是 'top', 'middle', 'bottom'。top: 9,left: '45%',data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30']},

tooltip是否显示提示框组件,包括提示框浮层和 axisPointer。

在这里插入图片描述

tooltip: {trigger: 'axis',backgroundColor: 'rgba(255,255,255,0.6)',// 坐标轴指示器是指示坐标轴当前刻度的工具。axisPointer: {type: 'cross'},borderWidth: 1,borderColor: '#ccc',padding: 10,textStyle: {color: '#000'},position: function (pos, params, el, elRect, size) {var obj = {top: 10};obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;return obj;}
},

axisPointer鼠标移动到一定位置后Y轴和X轴上显示的文字说明.

在这里插入图片描述

axisPointer: {link: {xAxisIndex: 'all'},label: {// {# 鼠标移到那里x轴和y轴显示的数字#}backgroundColor: '#777'}
},

toolbox 工具栏。内置有导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具,具体需要什么功能看个人需要。

在这里插入图片描述

toolbox: {feature: {dataZoom: {yAxisIndex: false},brush: {type: ['lineX', 'clear']}}
},

brush 是区域选择组件,用户可以选择图中一部分数据,从而便于向用户展示被选中数据,或者他们的一些统计计算结果,隐藏K线数据和5日均线数据。

在这里插入图片描述

brush: {xAxisIndex: 'all',brushLink: 'all',outOfBrush: {colorAlpha: 0.1}
},

visualMap 是视觉映射组件,用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)。

在这里插入图片描述

visualMap: {show: false,seriesIndex: 5,dimension: 2,pieces: [{value: 1,color: downColor}, {value: -1,color: upColor}]
},

grid直角坐标系内绘图网格,单个 grid 内最多可以放置上下两个 X 轴,左右两个 Y 轴。可以在网格上绘制折线图,柱状图,散点图(气泡图)。

grid: [{  // 用于控制图像与左边的边距left: '5%',right: '8%',height: '50%'},{left: '10%',right: '8%',top: '63%',height: '16%'}
],

xAxis设置X轴等相关的数据,样式,字体样式,宽高等。

在这里插入图片描述

xAxis: [{type: 'category',// 日期,格式是['2016-03-01','2016-03-02','2016-03-03'.......]data: data.categoryData,scale: true,boundaryGap: false,axisLine: {onZero: false},splitLine: {show: false},splitNumber: 20,min: 'dataMin',max: 'dataMax',axisPointer: {z: 100}},{   type: 'category',gridIndex: 1,data: data.categoryData,scale: true,boundaryGap: false,axisLine: {onZero: false},axisTick: {show: false},splitLine: {show: false},axisLabel: {show: false},splitNumber: 20,min: 'dataMin',max: 'dataMax'}
],

yAxis设置Y轴等相关的数据,样式,字体样式,宽高等。

yAxis: [{scale: true,splitArea: {show: true}},{scale: true,gridIndex: 1,splitNumber: 2,axisLabel: {show: false},axisLine: {show: false},axisTick: {show: false},splitLine: {show: false}}
],

dataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。

在这里插入图片描述

dataZoom: [{type: 'inside',xAxisIndex: [0, 1],start: 98,end: 100},{show: true,xAxisIndex: [0, 1],type: 'slider',top: '85%',start: 98,end: 100}
],

series-candlestickCandlestick 即我们常说的 K线图

在这里插入图片描述

series: [{name: '日K',type: 'candlestick',// 股票价格,格式是[['开盘价','收盘价','最低价',最高价,成交量],['开盘价','收盘价','最低价',最高价,成交量]....]data: data.values,itemStyle: {color: upColor,color0: downColor,borderColor: null,borderColor0: null},tooltip: {formatter: function (param) {param = param[0];return ['Date: ' + param.name + '<hr size=1 style="margin: 3px 0">','Open: ' + param.data[0] + '<br/>','Close: ' + param.data[1] + '<br/>','Lowest: ' + param.data[2] + '<br/>','Highest: ' + param.data[3] + '<br/>'].join('');}},{name: 'Volume',type: 'bar',xAxisIndex: 1,yAxisIndex: 1,// [0, 168890000, 1]data: data.volumes}},

MA5:5日均线线的样式二设置,下面的代码只展示了5日均线,其他均线的原理其实是一样的,这里的data: calculateMA(5, data)借助了函数calculateMA( )

function calculateMA(dayCount, data) {var result = [];for (var i = 0, len = data.values.length; i < len; i++) {if (i < dayCount) {result.push('-');continue;}var sum = 0;for (var j = 0; j < dayCount; j++) {sum += data.values[i - j][1];}result.push(+(sum / dayCount).toFixed(3));}return result;
}

在这里插入图片描述

{name: 'MA5',type: 'line',data: calculateMA(5, data),smooth: true,showSymbol: false,lineStyle: {opacity: 0.8}

在这里插入图片描述

最后不要忘记将刚才指定的配置项和数据显示图表

option && myChart.setOption(option);

到现在,数据展示方面的图已经出做来了,但是如果没有数据的提供,K线图还是画不出来的,接下来,我们要处理数据了,注意数据的格式是[[内容1],[内容2],[内容3]...],二维数组的形式展现.

3.后填数据

​ 在搭建运行环境中,我们已经知道从Tushare中提取的数据是DataFrame形式的,但是提供给JavaScript的数据是二维数组,一般来说,数据的处理应该在后端处理,前端就负责实现数据的展现,所以我建议在后端就把数据处理好,后面直接传给前端。

​ 股票的K线图,从上市那天就会有,因此,一般来说我们要获取的是股票上市那天到今天的交易数据。

    import tushare as tsimport timepro = ts.pro_api( )# 实际应用用这里用的是参数传递,不会定死。ts_code = '600519.SH'# 我们需要的是公司的上市日期,是否退市,退市日期data = pro.stock_basic(ts_code=ts_code,fields='list_status,list_date,delist_date')data=data.iloc[0]		# 输出结果:   0	  L	 20010827	None#  L:上市 D:退市 P:暂停上市# 如果不是退市,那么结束日期(YYYYMMDD)定为今天.start_date =data['list_date']if data['list_status'] !='D':end_date = time.strftime("%Y %m %d").replace(' ','')else:# 如果是退市,,那么结束日期(YYYYMMDD)定为退市日期end_date=data['delist_date']# 获取股票从上市到现在(退市)的所有信息,all_daily_info = pro.daily(ts_code=ts_code, start_date=start_date, end_date=end_date)daily_info_list=[]# ['交易日期','开盘价','收盘价','最低价',最高价,成交量]
sele_daily_info=all_daily_info[['trade_date','open','close','low','high','vol']].sort_index(ascending=False)for num in range(len(sele_daily_info)):# 将DataFrame格式的数据转换成列表,再转换成二维数组daily_info_list.append(list(sele_daily_info.iloc[num]))

OK,数据也处理好了,现在就需要将数据传递到前端了,如果该方法我就不涉及了,方法也挺多的,我用的是Django前端框架,也可以用Ajax传递。好了,至此,数据方面和可视化方面已经全部做好了,最终的效果就是上面第一张图。如果有什么疑问,欢迎咨询。

在这里插入图片描述


http://www.ppmy.cn/news/551108.html

相关文章

股票数据网络接口的一些信息

一直想找一个免费的股票数据接口&#xff0c;开发自己的股票分析软件&#xff0c;找了一天也没有头绪&#xff0c;只找到了一篇这个&#xff0c;不知道会不会有用&#xff0c;先记下来吧。 转&#xff1a; 一、软件安装&#xff1a; ■安装最方便■使用最稳定的益盟操盘手2.72…

IE11使用 ActiveX 控件

为什么80%的码农都做不了架构师&#xff1f;>>> 解决方案: ActiveX 控件 ActiveX 控件是一些小应用&#xff0c;网站可以使用这类小应用提供视频和游戏等内容。 浏览 Web 时&#xff0c;你也可以使用这些小应用与工具栏和股票行情等内容进行交互。 但是&#xff…

迷你股票行情,时刻给你最新行情。

迷你股票行情&#xff0c;时刻给你最新行情。自己开发的程序&#xff0c;方便自己查看股票行情&#xff0c;与大家分享。可以免费使用、传播&#xff0c;不得用于商业目的,转载请保留作者信息。 1、桌面最顶层滚动显示&#xff0c;工作、行情两不误。 2、自由定制&#xff0c;设…

一个简单案例理解为什么在多线程的应用中要使用互斥锁

需求:使用10个线程,同时对一个值count进行加一操作,每个线程对count加100000次,最终使得count1000000 第一版代码:不加锁 ​​​lock.c #include<stdio.h> #include<pthread.h>#define THREAD_COUNT 10void *thread_callback(void *arg){int *pcount(int*)arg;in…

文件系统概述

目录 概述用户空间层面1.应用程序可以直接使用内核提供的系统调用访问文件&#xff1a;2.应用程序也可以使用 glibc 库封装的标准 I/O 流函数访问文件&#xff1a; 硬件层面1.块设备2.闪存3.NVDIMM 内核空间层面 概述 在 Linux 系统中&#xff0c;一切皆文件&#xff0c;除了通…

【MySQL数据库】存储过程

目录 一、存储过程1.1概述1.2优点 二、存储过程实战2.1创建存储过程2.2存储过程的参数2.3条件语句 if-then-else end if2.4循环语句while end while 一、存储过程 1.1概述 存储过程是一组为了完成特定功能的SQL语句集合。存储过程在使用过程中是将常用或者复杂的工作预先使…

笔记本电量图表显示

step1&#xff1a;打开设置》设备管理器 step2&#xff1a;展开电池&#xff0c;对电池内的项目全部禁用后再启用

笔记本电脑上电量图标显示方法

记录一下笔记本电量小图标显示不出问题的解决方法&#xff1a; 1、打开设备管理器 找到“电池”下的两个子项 2、右键每个子项&#xff0c;选择“禁用设备”后再选择“启用设备”即可显示电池图标