《金融行业前端探索》三、实现Vue3+ECharts可定制化轻量金融图表

申明:本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!

前言

《金融行业前端探索》专题系列文章将构建现代化金融应用的技术与实践,提供理论知识和技术原理,还通过丰富的案例和实例,带大家一步步实现一个简易的金融终端系统,帮助读者将所学知识应用于实际项目中。此系列文章,适用于对金融行业前端感兴趣的同学,以及对前端跨端、可视化、AI技术、大数据等方面感兴趣的同学。需要提前了解技术:electron、vite、vue,Echart和其他前端基础知识等。

本文为《金融行业前端探索》第3篇文章 :实现Vue+Echart可定制化轻量金融图表,包含以下内容:
【1】 金融图表的特点和功能分析
【2】Vue+Echart图表组件封装,图表样式配置、换肤功能实现
【3】金融行情图原理和实现

注:本文数据均为MOCK/前端写死数据,无实质参考意义

上一篇 :《金融行业前端探索》二、使用electron-vite-vue 搭建一个金融终端框架

本项目完整代码地址:electron-vite-vue-ft(持续更新代码)

《金融行业前端探索》三、实现Vue3+ECharts可定制化轻量金融图表

一、金融图表的特点和功能分析

金融图表的特点和功能使其成为金融行业中不可或缺的工具,投资者和分析师可以通过图表来进行市场观察、技术分析和决策支持。股票K线图是金融领域中常用的图表类型,用于展示股票价格的走势和交易情况。K线图具有以下特点和功能:

  1. 反映价格波动:K线图通过纵轴表示价格,横轴表示时间,以矩形的形式展示每个时间周期内的开盘价、最高价、最低价和收盘价。通过连接相邻时间周期的收盘价,形成一条条连续的K线,反映股票价格的波动情况。
  2. 反映市场情绪和趋势:K线图通过不同颜色的矩形和影线来表示价格的涨跌情况。通常,涨价的K线用实心或上涨颜色(如红色)表示,跌价的K线用空心或下跌颜色(如绿色)表示。影线则表示价格的波动范围和极值点,上影线表示最高价,下影线表示最低价。通过观察K线的颜色、形态和影线,可以判断市场的情绪和趋势。
  3. 技术分析工具:K线图常与各种技术分析工具结合使用,如移动平均线、相对强弱指标(RSI)、MACD等。这些工具通过对K线图中价格数据的计算和统计,帮助分析师和投资者判断市场的趋势、价格走势和买卖信号。
  4. 时间周期选择:K线图可以显示不同的时间周期,如日K线、周K线、月K线等。不同时间周期的K线图可以展示不同时间范围内的价格走势和交易情况,帮助投资者观察长期和短期的市场趋势。
  5. 量能分析:K线图通常配合成交量柱状图一起展示,用于分析交易量和价格的关系。通过观察K线和成交量的变化,可以判断价格上涨或下跌的力量和趋势,辅助投资决策。
  6. 形态分析:K线图中的特定形态和组合模式具有一定的技术意义。例如,常见的形态包括双底、头肩顶等。分析师和投资者通过观察这些形态,来判断未来价格的走势和反转信号。
  7. 时间戳和事件标注:K线图上常标注重要的经济事件、公司财报公布等重要时间点,帮助投资者了解价格波动的原因和影响。

二、 Vue3+ECharts图表组件封装

通过 npm 安装 ECharts

npm install echarts --save

需引入ECharts的模块

大多数人在使用ECharts的时候直接 import * as echarts from 'echarts',直接一顿操作,其实我们在实际使用过程中并不会使用到ECharts的全部功能和组件,我们可以按需引入需要的模块,以减小打包体积和提高页面加载速度详细也可以关注echarts官网

《金融行业前端探索》三、实现Vue3+ECharts可定制化轻量金融图表

当然,图形也要监听着页面的变化,而重置宽高,做到图形实时变化宽高

onMounted(() => {
  initChart()
  window.addEventListener('resize', resizeTheChart, { passive: true })
})

const resizeTheChart = () => {
  if (chartInstance) {
    chartInstance.resize && chartInstance.resize()
  }
}

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeTheChart)
})

修改ECharts 主题

自定义 ECharts 的皮肤,您可以通过修改主题或自定义样式来实现

ECharts 提供了一些内置的主题,您可以选择适合您需求的主题进行修改。主题文件通常是一个 JSON 格式的配置文件,定义了图表的样式、颜色等信息。

  1. 在 ECharts 的官方主题库(echarts.apache.org/zh/theme-bu…)中选择一个基础主题,或者您可以自己创建一个新的主题。

《金融行业前端探索》三、实现Vue3+ECharts可定制化轻量金融图表

使用在线主题编辑器,您可以根据需要修改主题的各个部分,包括背景颜色、字体样式、系列颜色等。您可以在页面上实时预览主题的效果。修改后的主题时,点击 “生成主题” 按钮,下载生成的主题文件(通常是一个 JSON 文件)

  1. 在您的应用程序中引入该主题文件,并将其应用到 ECharts 实例中
import dark from "./theme/dark.json";
import light from "./theme/light.json";
registerTheme("dark", dark);
registerTheme("light", light);

这样你就可以自定义自己的主题了。

三、金融行情图原理和实现

金融行情图通常包含有K线图(蜡烛图)、移动平均线(MA)折线图、成交量(Volume)柱状图三种图形组合的技术指标展示,由历史价格按照一定的规则绘制出来,能帮助交易者清晰的看到价格走势。

K线图

《金融行业前端探索》三、实现Vue3+ECharts可定制化轻量金融图表
K线图的形成取决于股票或指数的四个数据,开盘价、收盘价以及盘中最高价和最低价。根据实体颜色的不同,一般可以分为阳线、阴线两种形态,为了方便理解,下面咱们就以日K线来说明

红色或空心体的柱状图是阳线,代表当天这只股票或指数的价格是上涨的,也就是收盘价高于开盘价。在阳线中,上影线上端代表的是当天最高价,下端是当天收盘价;下影线上端是当天开盘价、下端是当天最低价。

绿色或黑体的柱状图是阴线,代表当天这只股票或指数的价格是下跌的,即收盘价低于开盘价,所以阴线中开盘价在上而收盘价在下,即上影线上端代表的是当天最高价,下端是当天开盘价;下影线上端是当天收盘价、下端是当天最低价

实体部分,无论阳线阴线,代表的都是开盘价和收盘价之间的差距

阳线和阴线这两种普遍形态,K线图还有一种很少见的特殊形态叫做 “十字星”只有当股票或指数的收盘价等于开盘价、而且有新的最高价和最低价时,刚刚提到的“实体”就会消失了,出现这种新的“十字”形态,代表这个区间内的价格涨幅为0

ECharts 只要把图形属性设置为 type: 'candlestick'即可实现蜡烛图,蜡烛图的数据格式也是行业规范:

 ['2024-01-02', 10452.74, 10409.85, 10367.41, 10554.96, 168890000],

分别代表:”日期”, “开盘价”, “收盘价”, “最低价”, “最高价” , “成交量”

      series: [
        {
          name: 'Dow-Jones index',
          type: 'candlestick',
          data: data.values,
          itemStyle: {
            color: upColor,
            color0: downColor,
            borderColor: undefined,
            borderColor0: undefined
          }
        },]

移动平均线(MA)折线图

移动平均线英文名是Moving Average,简称MA,是由过去一定时间周期内的收盘价格的平均值连接绘制而成的。 外汇交易者可以利用它判断市场价格趋势,从而做出交易策略。通常会显示:

  1. MA5:代表5日移动平均线。它是通过计算过去5个交易日的收盘价的平均值来得出的移动平均线。
  2. MA10:代表10日移动平均线。它是通过计算过去10个交易日的收盘价的平均值来得出的移动平均线。
  3. MA20:代表20日移动平均线。它是通过计算过去20个交易日的收盘价的平均值来得出的移动平均线

对此我们封装一个calculateMA函数来计算移动平均线,接受两个参数:

  • dayCount:表示移动平均线的时间范围,即计算平均值所使用的天数。
  • data:包含了价格或指标的数据,其中 data.values 是一个二维数组,每一行表示一个时间点的数据,第一列是时间,第二列是对应的价格或指标值。
const 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;  
};

函数通过遍历数据数组,并根据给定的时间范围计算每个时间点的移动平均值。具体的计算过程如下:

  1. 如果当前索引小于移动平均的时间范围(dayCount),则将结果数组 result 中对应位置的值设置为 “-“,表示该时间点的移动平均值无法计算。

  2. 如果当前索引大于等于移动平均的时间范围,将计算该时间点的移动平均值。

    • 遍历最近的 dayCount 个时间点,从当前时间点往前数。
    • 将这些时间点对应的价格或指标值累加到 sum 变量中。
    • 计算累加值的平均值,保留三位小数,并将结果添加到 result 数组中。

最终,函数返回一个数组 result,其中包含了每个时间点的移动平均值。如果某个时间点的移动平均值无法计算(例如,时间点索引小于移动平均的时间范围),则用 “-” 表示

成交量(Volume)柱状图

成交量指标通常以柱状图的形式显示在价格图表下方或独立的图表中。它用于衡量市场的活跃程度和交易的强度,并提供了关于价格变动的重要信息。这个时候我们的成交量(Volume)柱状图放在第二个坐标轴上:

    grid: [
      {
        left: '2%',
        right: '2%',
        top: '15px',
        height: '52%'
      },
      {
        left: '2%',
        right: '2%',
        bottom: '20px',
        height: '22%'
      }
    ],
    ...
      {
        name: 'Volume',
        type: 'bar',
        xAxisIndex: 1,
        yAxisIndex: 1,
        data: data.volumes,
        barWidth: 'auto',
        itemStyle: {
          borderRadius: 0
        },
        emphasis: {}
      }
      ...

巧用tooltip实现鼠标经过实时显示行情信息

行情图通常在k线图、移动平均线(MA)折线图和成交量(Volume)柱状图中间,显示实时行情的数据,行业上有通过三个canvas 去展示的,这里介绍一种通过tooltip实现

《金融行业前端探索》三、实现Vue3+ECharts可定制化轻量金融图表


    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      },
      position: ['4%', '60%'],
      alwaysShowContent: true,
      extraCssText: 'box-shadow: none',
      formatter: function (params) {
        let obj = {
          open_px: '',
          close_px: '',
          high_px: '',
          low_px: '',
          business_amount: '',
          MA5: '',
          MA10: '',
          MA20: '',
          Volume: ''
        }
        params.forEach((item) => {
          if (item.seriesName == 'candlestick') {
            obj.open_px = item.data[1]
            obj.close_px = item.data[2]
            obj.low_px = item.data[3]
            obj.high_px = item.data[4]
            obj.business_amount = item.data[5]
          }
          if (item.seriesName == 'MA5') {
            obj.MA5 = item.data
          }
          if (item.seriesName == 'MA10') {
            obj.MA10 = item.data
          }
          if (item.seriesName == 'MA20') {
            obj.MA20 = item.data
          }
          if (item.seriesName == 'Volume') {
            obj.Volume = item.data[1]
          }
        })
        mycallback(obj)
        return (
          "<div style='height:24px;color: #fff; font-weight: normal;line-height:24px; padding-left:4px; width:500px; font-size:12px;background:#212529'; display: flex; alignItems: center;'>" +
          `<span style=' font-weight: normal;color: #fff; '>VOL成交量:${
            obj.Volume / 10000
          }万\xa0\xa0</span> ` +
          `<span> 开盘价:${obj.open_px} \xa0\xa0 </span> ` +
          `<span> 收盘价:${obj.close_px} \xa0\xa0 </span> ` +
          `<span> 最高价:${obj.high_px} \xa0\xa0 </span> ` +
          `<span> 最低价:${obj.low_px}</span> ` +
          '</div>'
        )
      },
      backgroundColor: '#F7F7F7', // 设置为透明背景颜色
      borderColor: 'transparent', // 设置为透明边框颜色
      padding: 0,
      borderWidth: 0,
      textStyle: {
        width: 10000,
        height: 24
      }
    },

在 formatter 函数中,根据传入的参数 params,根据各个系列的名称(item.seriesName),将对应的数据提取出来并赋值给一个对象 obj。然后,根据 obj 的属性值构建提示框的 HTML 内容,并返回该内容。最终的提示框内容包括了成交量、开盘价、收盘价、最高价和最低价等信息。值得一提的是这个方案,中formatter的DOM居然不能跟随最外层canvas的宽度,或许是ECharts的一个遗憾(您也可以在评论区留下你的方案)

最后

本文从开始介绍Vue3+ECharts封装组件,从原理了解到实现一个简易的K线行情图。希望大家对金融图表有一些新的认识。

注:本文数据均为MOCK/前端写死数据,无实质参考意义

本项目完整代码地址:electron-vite-vue-ft(持续更新代码)

上一篇 :《金融行业前端探索》二、使用electron-vite-vue 搭建一个金融终端框架

原文链接:https://juejin.cn/post/7353822048520880164 作者:codercao

(0)
上一篇 2024年4月7日 下午4:11
下一篇 2024年4月7日 下午4:21

相关推荐

发表回复

登录后才能评论