| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- import { reactive, toRefs, computed } from 'vue'
- import { queryHistoryDatas } from '@/services/api/quote'
- import { ChartCycleType } from '@/constants/chart'
- import { echarts, ECOption } from '@/components/base/echarts/core'
- import { useFuturesStore } from '@/stores'
- import { useDataset } from '@/hooks/echarts/candlestick/dataset'
- import moment from 'moment'
- export function useCandlestick(goodsCode: string) {
- const { dataset, handleData, clearData } = useDataset()
- const { quoteWatch } = useFuturesStore()
- const state = reactive({
- loading: false,
- dataIndex: -1,
- cycleType: ChartCycleType.Minutes
- })
- // 当前选中的数据项
- const selectedItem = computed(() => {
- if (state.dataIndex > -1 && dataset.candlestick.source.length > state.dataIndex) {
- const { open, close, highest, lowest, ma5, ma10, ma15 } = dataset.candlestick.source[state.dataIndex]
- const { macd, dif, dea } = dataset.macd.source[state.dataIndex]
- const { vol } = dataset.vol.source[state.dataIndex]
- const { k, d, j } = dataset.kdj.source[state.dataIndex]
- const { cci } = dataset.cci.source[state.dataIndex]
- return { open, close, highest, lowest, ma5, ma10, ma15, macd, dif, dea, vol, k, d, j, cci }
- } else {
- return { open: '--', close: '--', highest: '--', lowest: '--', ma5: '--', ma10: '--', ma15: '--', macd: '--', dif: '--', dea: '--', vol: '--', k: '--', d: '--', j: '--', cci: '--' }
- }
- })
- // 获取历史行情
- const getHistoryData = async () => {
- try {
- clearData()
- state.dataIndex = -1
- state.loading = true
- const res = await queryHistoryDatas({
- data: {
- goodsCode,
- cycleType: state.cycleType,
- count: 1440,
- }
- })
- // 日期升序排序
- const data = res.data.sort((a, b) => moment(a.ts).valueOf() - moment(b.ts).valueOf())
- state.dataIndex = data.length - 1
- handleData(data)
- } finally {
- state.loading = false
- }
- }
- let chartInstance: echarts.ECharts
- let asyncHistoryData = getHistoryData()
- const createCandlestick = (chart: echarts.ECharts) => {
- chartInstance = chart
- asyncHistoryData.then(() => {
- const { source, dimensions } = dataset.candlestick
- const opt: ECOption = {
- grid: [
- {
- top: '0',
- height: "70%"
- },
- {
- top: '70%',
- height: "18%"
- }
- ],
- xAxis: [
- {
- type: 'category',
- axisLabel: {
- formatter: (val: string) => {
- if (val) {
- switch (state.cycleType) {
- case ChartCycleType.Day: {
- return moment(val).format('YYYY-MM-DD')
- }
- default: {
- return moment(val).format('HH:mm')
- }
- }
- }
- return ''
- }
- }
- },
- {
- type: 'category',
- gridIndex: 1
- }
- ],
- yAxis: [
- {
- type: 'value',
- scale: true,
- },
- {
- type: 'value',
- scale: true,
- gridIndex: 1
- }
- ],
- dataZoom: {
- type: 'inside',
- startValue: source.length - 60, // 起始显示K线条数(最新60条)
- end: 100,
- minValueSpan: 30, // 限制窗口缩放显示最少数据条数
- maxValueSpan: 200, // 限制窗口缩放显示最大数据条数
- xAxisIndex: [0, 1]
- },
- dataset: {
- dimensions,
- source,
- },
- series: [
- {
- name: 'KLine',
- type: 'candlestick'
- },
- {
- name: 'MACD',
- type: 'bar',
- xAxisIndex: 1,
- yAxisIndex: 1,
- }
- ]
- }
- chart.setOption(opt)
- })
- }
- const initChart = (cycleType: ChartCycleType) => {
- state.cycleType = cycleType
- asyncHistoryData = getHistoryData()
- }
- /**
- * 格式化日期
- * @param value
- * @returns
- */
- const formatDate = (value: string) => {
- switch (state.cycleType) {
- case ChartCycleType.Day: {
- return moment(value).format('YYYY-MM-DD')
- }
- case ChartCycleType.Hours2:
- case ChartCycleType.Hours4: {
- return moment(value).format('YYYY-MM-DD HH:00:00')
- }
- default: {
- return moment(value).format('YYYY-MM-DD HH:mm:00')
- }
- }
- }
- quoteWatch(goodsCode, (q) => {
- if (chartInstance) {
- asyncHistoryData.then(() => {
- const { last, lasttime } = q
- if (last && lasttime) {
- const { candlestick, macd, vol, kdj, cci } = dataset
- const lastIndex = candlestick.source.length - 1 // 历史数据最后索引位置
- const oldTime = lastIndex === -1 ? moment(lasttime) : moment(candlestick.source[lastIndex].date) // 历史行情最后时间
- const diffTime = moment(lasttime).valueOf() - oldTime.valueOf() // 计算时间差
- // 判断时间差是否大于周期时间
- if (lastIndex === -1 || diffTime > 60 * 1000) {
- const newtime = formatDate(lasttime)
- // 新增K线数据
- candlestick.source.push({
- date: newtime,
- open: last,
- close: last,
- lowest: last,
- highest: last,
- ma5: '-',
- ma10: '-',
- ma15: '-',
- })
- // 新增MACD数据
- macd.source.push({
- date: newtime,
- ema12: 0,
- ema26: 0,
- dif: 0,
- dea: 0,
- macd: 0,
- })
- // 新增VOL数据
- vol.source.push({
- date: newtime,
- vol: 0,
- })
- // 新增KDJ数据
- kdj.source.push({
- date: newtime,
- k: '-',
- d: '-',
- j: '-',
- })
- // 新增CCI数据
- cci.source.push({
- date: newtime,
- cci: '-',
- })
- } else {
- // 更新列表中最后一条记录的数据
- const record = candlestick.source[lastIndex]
- if (record.lowest > last) {
- record.lowest = last // 更新最低价
- }
- if (record.highest < last) {
- record.highest = last // 更新最高价
- }
- record.close = last // 更新收盘价
- }
- // chartInstance.setOption({
- // dataset: {
- // source: candlestick.source
- // }
- // })
- }
- })
- }
- })
- return {
- ...toRefs(state),
- selectedItem,
- createCandlestick,
- initChart
- }
- }
|