使用echars绘制股票图

3 篇文章 0 订阅

股票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 {
    @Override
    public 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:\Users\sixteenccc\AppData\Roaming\Typora\typora-user-images\image-20211211130116718.png)]

    • 成功如下:

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZNFGt3s-1639205681873)(C:\Users\sixteenccc\AppData\Roaming\Typora\typora-user-images\image-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 -S
	b) 在main.js中引入
       import * as echarts from 'echarts'
 // 注意:这里要 * as echarts 而不是 import echarts from xxx
和Vue.prototype.$echarts = echarts
	c) div设置宽高,使用ref调用,将document.getElementById(‘myChart’)换成$refs(不然会造成 Error Initialize failed invalid dom错误)

绘制日K图

访问网址得到数据类型为

在这里插入图片描述

echars的K线图需要的数据类型为
在这里插入图片描述

对传回的数据进行处理

  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
                   }
                 }
               ]
             });
           })
         }

绘制如图

在这里插入图片描述

使用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() {
              //进行数据处理,腾讯返回的是一堆字符串而不是json
            var 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 = _arr
            const 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-stat
                echarts.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)

ECharts 可以通过使用自定义系列(Custom Series)的方式来绘制 K 线。下面是一个简单的示例代码: ```javascript // K 线数据示例 var data = [ [2320.26, 2320.26, 2287.3, 2362.94], [2300, 2291.3, 2288.26, 2308.38], [2295.35, 2346.5, 2295.35, 2346.92], [2347.22, 2358.98, 2337.35, 2363.8], // ... ]; // 自定义系列 echarts.registerCustomSeries('candlestick', { type: 'candlestick', itemStyle: { color: '#ef232a', color0: '#14b143', borderColor: '#ef232a', borderColor0: '#14b143' }, encode: { x: 0, y: [1, 4, 3, 2] } }); // 配置项 var option = { xAxis: { type: 'category' }, yAxis: {}, series: [{ type: 'candlestick', name: 'K 线', data: data }] }; // 绘制表 var chart = echarts.init(document.getElementById('chart')); chart.setOption(option); ``` 上面的代码中,我们通过 `registerCustomSeries` 方法注册了一个名为 `candlestick` 的自定义系列。该系列的 `type` 属性设置为 `candlestick`,表示绘制 K 线。`itemStyle` 属性用于设置 K 线的样式,`encode` 属性用于指定数据中每个元素对应的字段。在配置项中,我们将系列的 `type` 属性设置为 `candlestick`,并将数据传入 `data` 属性中即可。 需要注意的是,K 线的数据格式与曲线有所不同,需要按照一定的规则进行处理。在上面的示例中,我们将每个数据元素转换为一个包含四个值的数组,分别表示开盘价、收盘价、最低价、最高价。如果你的数据格式不同,需要对 `encode` 属性进行相应的调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值