| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- import { ref, computed } from 'vue'
- //import { timerInterceptor } from '@/utils/timer'
- import { ChartCycleType } from '@/constants/chart'
- import { queryHistoryDatas } from '@/services/api/quote'
- import { useFuturesStore } from '@/stores'
- import { useDataset } from './dataset'
- import { useOptions } from './options'
- import moment from 'moment'
- export function useCandlestickChart(goodscode: string) {
- const { quoteWatch } = useFuturesStore()
- const { dataset, handleData, clearData, calcIndicator } = useDataset();
- const { options, initOptions, updateOptions } = useOptions(dataset);
- const loading = ref(false);
- const isEmpty = ref(true);
- const dataIndex = ref(-1); // 当前数据索引值
- // 当前选中的数据项
- const selectedItem = computed(() => {
- let result: { [key: string]: number | string } = {
- open: '--',
- close: '--',
- highest: '--',
- lowest: '--',
- ma5: '--',
- ma10: '--',
- ma15: '--',
- macd: '--',
- dif: '--',
- dea: '--',
- vol: '--',
- k: '--',
- d: '--',
- j: '--',
- cci: '--'
- }
- if (dataIndex.value > -1 && dataset.candlestick.source.length > dataIndex.value) {
- const { open, close, highest, lowest, ma5, ma10, ma15 } = dataset.candlestick.source[dataIndex.value];
- const { macd, dif, dea } = dataset.macd.source[dataIndex.value];
- const { vol } = dataset.vol.source[dataIndex.value];
- const { k, d, j } = dataset.kdj.source[dataIndex.value];
- const { cci } = dataset.cci.source[dataIndex.value];
- result = { open, close, highest, lowest, ma5, ma10, ma15, macd, dif, dea, vol, k, d, j, cci }
- }
- return result;
- })
- /**
- * 初始化数据
- * @param cycletype 周期类型
- */
- const initData = (cycletype: ChartCycleType) => {
- if (goodscode) {
- clearData();
- dataIndex.value = -1;
- options.cycleType = cycletype;
- loading.value = true;
- isEmpty.value = true;
- // 获取历史行情
- queryHistoryDatas({
- data: {
- cycleType: cycletype,
- goodsCode: goodscode,
- count: 1440,
- }
- }).then((res) => {
- // 日期升序排序
- const data = res.data.sort((a, b) => moment(a.ts).valueOf() - moment(b.ts).valueOf());
- if (data.length) {
- dataIndex.value = data.length - 1;
- isEmpty.value = false;
- handleData(data);
- }
- }).finally(() => {
- loading.value = false;
- })
- }
- }
- /**
- * 获取周期毫秒数
- * @returns
- */
- const getCycleMilliseconds = () => {
- const milliseconds = 60 * 1000; // 一分钟毫秒数
- switch (options.cycleType) {
- case ChartCycleType.Minutes5: {
- return milliseconds * 5;
- }
- case ChartCycleType.Minutes30: {
- return milliseconds * 30;
- }
- case ChartCycleType.Minutes60: {
- return milliseconds * 60;
- }
- case ChartCycleType.Hours2: {
- return milliseconds * 2 * 60;
- }
- case ChartCycleType.Hours4: {
- return milliseconds * 4 * 60;
- }
- case ChartCycleType.Day: {
- return milliseconds * 24 * 60;
- }
- default: {
- return milliseconds;
- }
- }
- }
- /**
- * 格式化日期
- * @param value
- * @returns
- */
- const formatDate = (value: string) => {
- switch (options.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')
- }
- }
- }
- /**
- * 更新图表数据
- */
- const updateChart = (quote: Partial<Model.QuoteDayRsp>) => {
- const { last, lasttime } = quote
- if (last && lasttime) {
- const { candlestick, macd, vol, kdj, cci } = dataset
- const lastIndex = candlestick.source.length - 1 // 历史数据最后索引位置
- const cycleMilliseconds = getCycleMilliseconds()
- const oldTime = lastIndex === -1 ? moment(lasttime) : moment(candlestick.source[lastIndex].date) // 历史行情最后时间
- const diffTime = moment(lasttime).valueOf() - oldTime.valueOf() // 计算时间差
- // if (diffTime > cycleMilliseconds * 2) {
- // // 时间间隔超过两个周期,重新请求历史数据,待优化
- // timerInterceptor.debounce(() => {
- // queryHistoryDatas({
- // data: {
- // cycleType: options.cycleType,
- // goodsCode: goodscode,
- // count: 1440,
- // }
- // }).then((res) => {
- // // 日期升序排序
- // const data = res.data.sort((a, b) => moment(a.ts).valueOf() - moment(b.ts).valueOf());
- // if (data.length) {
- // dataIndex.value = data.length - 1
- // clearData()
- // handleData(data, updateOptions)
- // }
- // })
- // }, 1000, 'updateChart')
- // } else {
- // 判断时间差是否大于周期时间
- if (lastIndex === -1 || diffTime > cycleMilliseconds) {
- 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 // 更新收盘价
- }
- // 计算各项指标
- calcIndicator(lastIndex === -1 ? 0 : lastIndex)
- updateOptions()
- // }
- }
- }
- // 监听行情推送
- quoteWatch(goodscode, (val) => {
- if (!loading.value && !isEmpty.value) {
- updateChart(val)
- }
- })
- return {
- loading,
- isEmpty,
- dataIndex,
- options,
- selectedItem,
- initData,
- initOptions,
- }
- }
|