文章目录

  • 股票shares后端
    • 网址链接
    • 股票接口
      • Sina股票实时数据接口
      • 历史数据接口
    • 跨域配置
  • 股票前端
    • vue的搭建
    • 股票数据处理
      • 绘制日K图
    • 使用ecStat插件完成线性回归

股票shares后端

网址链接

使用新浪股票接口来接收股票信息绘制日K

String rs= UrlContent.getContent("http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?" +"symbol=sz000001&schttp://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=sz002095&scale=60&ma=no&datalen=400http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=sz002095&scale=60&ma=no&datalen=400ale=60&ma=no&datalen=400","gbk");return rs;
package com.fjr.shares.util;import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;public class UrlContent {public static String getContent(String path, String charset) {InputStream in = null;StringBuilder result = new StringBuilder();try {URL url = new URL(path);URLConnection uc = url.openConnection();in = uc.getInputStream();// 获取读入流InputStream raw = new BufferedInputStream(in);// 放入缓冲流Reader r = new InputStreamReader(raw,charset); // 用Reader接收BufferedReader br= new BufferedReader(r);  //这样便于可以按行读String s = br.readLine();while(s!= null) {result.append(s);s = br.readLine();}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if (in != null) {in.close();}} catch (IOException e) {e.printStackTrace();}}return result.toString();}
}

股票接口

Sina股票实时数据接口

以大秦铁路(股票代码:601006)为例,如果要获取它的最新行情,只需访问新浪的股票数据接口:
http://hq.sinajs.cn/list=sh601006
这个url会返回一串文本,例如:
var hq_str_sh601006=“大秦铁路, 27.55, 27.25, 26.91, 27.55, 26.20,26.91, 26.92,
22114263, 589824680, 4695, 26.91, 57590, 26.90, 14700, 26.89,14300,
26.88, 15100, 26.87, 3100, 26.92, 8900, 26.93, 14230, 26.94, 25150,26.95, 15220, 26.96, 2008-01-11, 15:05:32”;
这个字符串由许多数据拼接在一起,不同含义的数据用逗号隔开了,按照程序员的思路,顺序号从0开始。
0:”大秦铁路”,股票名字;
1:”27.55″,今日开盘价;
2:”27.25″,昨日收盘价;
3:”26.91″,当前价格;
4:”27.55″,今日最高价;
5:”26.20″,今日最低价;
6:”26.91″,竞买价,即“买一”报价;
7:”26.92″,竞卖价,即“卖一”报价;
8:”22114263″,成交的股票数,由于股票交易以一百股为基本单位,所以在使用时,通常把该值除以一百;
9:”589824680″,成交金额,单位为“元”,为了一目了然,通常以“万元”为成交金额的单位,所以通常把该值除以一万;
10:”4695″,“买一”申请4695股,即47手;
11:”26.91″,“买一”报价;
12:”57590″,“买二”
13:”26.90″,“买二”
14:”14700″,“买三”
15:”26.89″,“买三”
16:”14300″,“买四”
17:”26.88″,“买四”
18:”15100″,“买五”
19:”26.87″,“买五”
20:”3100″,“卖一”申报3100股,即31手;
21:”26.92″,“卖一”报价
(22, 23), (24, 25), (26,27), (28, 29)分别为“卖二”至“卖四的情况”
30:”2008-01-11″,日期;
31:”15:05:32″,时间;

历史数据接口

http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=sz002095&scale=60&ma=no&datalen=400
获取深圳市场002095股票的以60分钟为间隔的数据,获取了最近的1023个节点。(但是目前通过实验发现,只能获取到最多488条记录)

参数说明:
参数写法 说明
symbol=[市场][股票代码] sz深市、sh沪市
scale=[周期] 单位是分钟,
由于A股每天交易4小时,共240分钟。若scale=30,则每天的数据是8条,若scale=60,则每天数据4条。
必须是5的倍数。
ma=no 是否需要取向前的加权平均值(分别是5分钟、10分钟、30分钟的数据)
datalen=[长度] 如果只获取最近的一条数据,则datalen=1

返回结果说明:
day日期和时间、open开盘价、high最高价、low最低价、close收盘价、volume成交量;向前复权的数据。

返回结果示例:
请求:
http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=sz002095&scale=60&ma=no&datalen=10
结果:
[
{“day”:“2020-07-30 11:30:00”,“open”:“20.650”,“high”:“20.660”,“low”:“20.510”,“close”:“20.590”,“volume”:“426501”},
{“day”:“2020-07-30 14:00:00”,“open”:“20.590”,“high”:“20.600”,“low”:“20.480”,“close”:“20.550”,“volume”:“460330”},
{“day”:“2020-07-30 15:00:00”,“open”:“20.550”,“high”:“20.550”,“low”:“20.340”,“close”:“20.370”,“volume”:“750885”},
{“day”:“2020-07-31 10:30:00”,“open”:“20.490”,“high”:“20.740”,“low”:“20.350”,“close”:“20.620”,“volume”:“1225035”},
{“day”:“2020-07-31 11:30:00”,“open”:“20.620”,“high”:“20.650”,“low”:“20.400”,“close”:“20.450”,“volume”:“584424”},
{“day”:“2020-07-31 14:00:00”,“open”:“20.470”,“high”:“20.600”,“low”:“20.450”,“close”:“20.550”,“volume”:“298512”},
{“day”:“2020-07-31 15:00:00”,“open”:“20.550”,“high”:“20.650”,“low”:“20.500”,“close”:“20.630”,“volume”:“878311”},
{“day”:“2020-08-03 10:30:00”,“open”:“20.900”,“high”:“21.030”,“low”:“20.710”,“close”:“20.840”,“volume”:“1285384”},
{“day”:“2020-08-03 11:30:00”,“open”:“20.840”,“high”:“21.270”,“low”:“20.820”,“close”:“21.040”,“volume”:“1501880”},
{“day”:“2020-08-03 14:00:00”,“open”:“21.060”,“high”:“21.120”,“low”:“20.980”,“close”:“21.080”,“volume”:“269644”}
]

跨域配置

因为前端访问需要跨域,后端需要进行跨域配置

package com.fjr.shares.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CrossConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")/*所有的当前站点的请求地址,都支持跨域访问*/.allowedOriginPatterns("*")/*所有的外部域都可跨域访问*/.allowedMethods("GET","HEAD","POST","PUT","DELETE","OPTIONS")/*哪些请求 需要跨域配置*/.allowCredentials(true) /*是否支持跨域用户凭证*/.maxAge(300)/*超时时长设置为5分钟。 时间单位是秒。*/.allowedHeaders("*");/*请求体的头部*/}
}

股票前端

vue的搭建

  • 项目初始化(搭建环境略)

    • 在当前目录下输入“vue init webpack项目名称(使用英文)”
      vue init webpack mytest

    • 注意几项选NO[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M8OtS8gb-1639205681872)(C:UserssixteencccAppDataRoamingTyporatypora-user-imagesimage-20211211130116718.png)]

    • 成功如下:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZNFGt3s-1639205681873)(C:UserssixteencccAppDataRoamingTyporatypora-user-imagesimage-20211211130139127.png)]

      cnpm install xxxx来下载项目中用到的依赖
      

股票数据处理

npm下载echars,在main.js引入echars,详情见官网

import * as echarts from 'echarts'//引入echarts Vue.prototype.$echarts = echarts //引入组件

可能会出现的问题:

vue导入echars问题:可能会造成init初始化问题,检查版本以及下述操作a) 导入依赖:cnpm install echarts -Sb) 在main.js中引入import * as echarts from 'echarts'// 注意:这里要 * as echarts 而不是 import echarts from xxx
和Vue.prototype.$echarts = echartsc) div设置宽高,使用ref调用,将document.getElementById(‘myChart’)换成$refs(不然会造成 Error Initialize failed invalid dom错误)

绘制日K图

访问网址得到数据类型为

使用echars绘制股票图-编程之家

echars的K线图需要的数据类型为
使用echars绘制股票图-编程之家

对传回的数据进行处理

  initData(data,day,open,high,low,close) {let barValue = [];data.forEach(item => {let outValue = [];outValue[0]= item.day;outValue[1] = item.open;outValue[2]= item.close;outValue[3] = item.low;outValue[4] = item.high;barValue.push(outValue);});this.valueBar = barValue;return barValue},

进行画图

drawSharesUrl(){var mythis = this;//在ajax方法里写$(this)指向的是最近调用它的jquery对象,所以这里的$(this)指的是ajax对象,而不是DOM对象console.log(rs)if(rs.data==1){axios({method: 'get',dataTypr:'json',url: 'http://localhost:8080/user/sz000001',//访问后端接口,得到数据}).then(function(rs) {console.log(rs.data);let myChart = mythis.$echarts.init(mythis.$refs.xxx);//需要提供一个div 给他宽高框框才可以画图,const upColor = '#ec0000';const upBorderColor = '#8A0000';const downColor = '#00da3c';const downBorderColor = '#008F28';// Each item: open,close,lowest,highest//对传来的数据进行格式处理,参考const data0 = splitData(mythis.initData(rs.data, 'day','open','high','low','close'));//除了data其他可以照抄官网的数据处理initData()方法function splitData(rawData) {const categoryData = [];const values = [];for (var i = 0; i < rawData.length; i++) {categoryData.push(rawData[i].splice(0, 1)[0]);values.push(rawData[i]);}return {categoryData: categoryData,values: values};}function calculateMA(dayCount) {var result = [];for (var i = 0, len = data0.values.length; i < len; i++) {if (i < dayCount) {result.push('-');continue;}var sum = 0;for (var j = 0; j < dayCount; j++) {sum += +data0.values[i - j][1];}result.push(sum / dayCount);}return result;}myChart.setOption({//这里需要使用myChart.setOption(option);title: {text: '平安银行(sz000001)',left: 0},tooltip: {trigger: 'axis',axisPointer: {type: 'cross'}},legend: {data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30']},grid: {left: '10%',right: '10%',bottom: '15%'},xAxis: {type: 'category',data: data0.categoryData,scale: true,boundaryGap: false,axisLine: { onZero: false },splitLine: { show: false },min: 'dataMin',max: 'dataMax'},yAxis: {scale: true,splitArea: {show: true}},dataZoom: [{type: 'inside',start: 50,end: 100},{show: true,type: 'slider',top: '90%',start: 50,end: 100}],series: [{name: '日K',type: 'candlestick',data: data0.values,itemStyle: {color: upColor,color0: downColor,borderColor: upBorderColor,borderColor0: downBorderColor},markPoint: {label: {formatter: function (param) {return param != null ? Math.round(param.value) + '' : '';}},data: [{name: 'Mark',coord: ['2013/5/31', 2300],value: 2300,itemStyle: {color: 'rgb(41,60,85)'}},{name: 'highest value',type: 'max',valueDim: 'highest'},{name: 'lowest value',type: 'min',valueDim: 'lowest'},{name: 'average value on close',type: 'average',valueDim: 'close'}],tooltip: {formatter: function (param) {return param.name + '<br>' + (param.data.coord || '');}}},markLine: {symbol: ['none', 'none'],data: [[{name: 'from lowest to highest',type: 'min',valueDim: 'lowest',symbol: 'circle',symbolSize: 10,label: {show: false},emphasis: {label: {show: false}}},{type: 'max',valueDim: 'highest',symbol: 'circle',symbolSize: 10,label: {show: false},emphasis: {label: {show: false}}}],{name: 'min line on close',type: 'min',valueDim: 'close'},{name: 'max line on close',type: 'max',valueDim: 'close'}]}},{name: 'MA5',type: 'line',data: calculateMA(5),smooth: true,lineStyle: {opacity: 0.5}},{name: 'MA10',type: 'line',data: calculateMA(10),smooth: true,lineStyle: {opacity: 0.5}},{name: 'MA20',type: 'line',data: calculateMA(20),smooth: true,lineStyle: {opacity: 0.5}},{name: 'MA30',type: 'line',data: calculateMA(30),smooth: true,lineStyle: {opacity: 0.5}}]});})}

绘制如图

使用echars绘制股票图-编程之家

使用ecStat插件完成线性回归

安装ecStat详见官网

//使用的是腾讯股票接口绘制散点图进行线性回归穿线。X值为自然数,Y值为每分钟单价 
var mdata=[]$(document).ready(function() {var myChart = echarts.init(document.getElementById('main'));var option;var mythis = this;$.ajax({url: "http://data.gtimg.cn/flashdata/hushen/minute/sz000001.js?maxage=110&0.28163905744440854",dataType: "script",cache: "false",type: "GET",success: function() {//进行数据处理,腾讯返回的是一堆字符串而不是jsonvar msg = min_data;var result = msg.replace(/n/g, ",").split(',')var arr = result.slice(2, result.length - 1), //开头结尾各一个空数组要去掉_arr = [];for (var i = 0; i < arr.length; i++) {var _a = arr[i].split(" "),_b = arr[i].split(" "),_c = [];if (i > 0) {_c = arr[i - 1].split(" ");}// 腾讯股票接口传的数值0930(日期) 5.55(成交价) 37673(累计成交量,初始成交量为9:30的)// 因此每分钟的 成交量 = 当前累计成交量 - 前一分钟的累计成交量_b[2] = _c.length > 0 ? _a[2] - _c[2] : _a[2];_arr.push(_b)}mdata = _arrconst barPrice=[]for(var i=0;i<50;i++){var price=[]price.push(i)price.push(Number(mdata[i][1]))// console.log("price="+price)barPrice[i]=price}//数据格式为下:// const data=[//   [1, 3.176513],// console.log(data)// See https://github.com/ecomfe/echarts-statecharts.registerTransform(ecStat.transform.regression);option = {dataset: [{source: barPrice},{transform: {type: 'ecStat:regression'// 'linear' by default.// config: { method: 'linear', formulaOn: 'end'}}}],title: {text: '平安银行(价格线性回归图)',left: 'center'},legend: {bottom: 5},tooltip: {trigger: 'axis',axisPointer: {type: 'cross'}},xAxis: {splitLine: {lineStyle: {type: 'dashed'}}},yAxis: {splitLine: {lineStyle: {type: 'dashed'}}},series: [{name: 'scatter',type: 'scatter'},{name: 'line',type: 'line',datasetIndex: 1,symbolSize: 0.1,symbol: 'circle',label: {show: true,fontSize: 16},labelLayout: {dx: -20},encode: {label: 2,tooltip: 1}}]};myChart.setOption(option);}})})

绘制如图

                 symbolSize: 0.1,symbol: 'circle',label: {show: true,fontSize: 16},labelLayout: {dx: -20},encode: {label: 2,tooltip: 1}}]};myChart.setOption(option);}})

})


**绘制如图**
![在这里插入图片描述](https://img-blog.csdnimg.cn/d34667fd73c04e789d71b8835ea447b7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rC45LiN5aS056eD55qE5YWt5YWt,size_20,color_FFFFFF,t_70,g_se,x_16)