var myChart; var app = new Vue({ el: '#app', data: { MA5: '', MA10: '', MA30: '', volMA5: '', volMA10: '', current: "15m", tabs: [{ 'label': '1分钟', 'value': "1m" }, { 'label': '15分钟', 'value': "15m" }, { 'label': '30分钟', 'value': "30m" }, { 'label': '1小时', 'value': "1H" }, { 'label': '4小时', 'value': "4H" }, { 'label': '1天', 'value': "1D" }, ], category: 2, categoryList: [{ 'label': '深度', 'value': 1 }, { 'label': '成交', 'value': 2 }, { 'label': '简介', 'value': 3 }, ], txData: {}, //交易数据统计 buyList: [], sellList: [], dealHis: [], tokenInfo: {}, page: 1, // 保存商品id typeId: '', // 保存socket对象 webSocket: '', // 保存当前k线数据 dataKLine: { data: [], dates: [], volumes: [], } }, created() { this.getTxData() // this.getDepth() // 保存商品id this.typeId = getQueryString('type'); // 简历长连接 this.scoketInit() }, mounted() { myChart = echarts.init(document.getElementById('main')); this.draw() this.getKline(); // 获取成交记录 this.getDealHis(); }, methods: { // 返回上一页 back() { console.log('cf'); uni.postMessage({ data: { action: 'message' } }); }, scoketInit() { const that = this; // 初始化websocket that.webSocket = new WebSocket("wss://wsaws.okx.com:8443/ws/v5/public"); that.webSocket.onopen = function(event) { console.log('打开链接成功'); const requestKData = JSON.stringify({ "op": "subscribe", "args": [{ "channel": "candle" + that.current, "instId": that.typeId }] }) const requestNewData = JSON.stringify({ "op": "subscribe", "args": [{ "channel": "tickers", "instId": that.typeId }] }) // 获取k线数据 that.webSocket.send(requestKData) // 获取当前行情数据 that.webSocket.send(requestNewData) } // 监听socket回复事件 that.webSocket.addEventListener('message', function(event) { const item = JSON.parse(event.data); try { // 判断是否为 if (item.arg.channel == ("candle" + that.current) && item.data) { const daytime = new Date(+item.data[0][0]); item.data[0][0] = that.initDay(daytime, "YYYY-mm-dd HH:MM:SS") if (item.data[0][0] != that.dataKLine.dates[that.dataKLine.dates.length-1]) { console.log(item.data[0][0],'jiange',that.dataKLine.dates[that.dataKLine.dates.length-1]); const itemi = item.data[0] that.dataKLine.dates.push(itemi[0]) that.dataKLine.data.push([+itemi[1], +itemi[2], +itemi[3], +itemi[4], + itemi[5] ]) that.dataKLine.volumes.push([that.dataKLine.volumes.length, +itemi[5], + itemi[1] > +itemi[2] ? 1 : -1 ]) that.setKline() } // that.txData.lastPrice = data.data[0][] } // if (item.arg.channel == ("tickers") &&item.data[0]) { const data = item.data[0] that.txData.lastPrice = +data.last that.txData.high = +data.high24h that.txData.volume = +data.open24h that.txData.low = +data.low24h that.txData.upRate = ((that.txData.lastPrice - that.txData.volume) / that.txData .volume * 100).toFixed(2) txData.upFlag = +that.txData.upRate > 0 ? 1 : 2; } } catch (e) { console.log("item: " + JSON.stringify(item)); } }); that.webSocket.onclose = function(event) { console.log("WebSocket is closed now."); }; }, // 获取24小时交易数据统计 getTxData() { this.txData = txData; }, // 初始化数据结构 dataInit(data, type) { let items; if (type == 1) { items = data.map(function(item) { return item[0]; }); } if (type == 2) { items = data.map(function(item) { return [+item[1], +item[2], +item[3], +item[4], +item[5]]; }); } if (type == 3) { items = data.map(function(item, index) { return [index, +item[5], +item[1] > +item[2] ? 1 : -1]; }); } return items }, // 初始化时间 initDay(time, fmt) { let ret; const opt = { "Y+": time.getFullYear().toString(), //年 "m+": (time.getMonth() + 1).toString(), //月 "d+": time.getDate().toString(), //日 "H+": time.getHours().toString(), //小时 "M+": time.getMinutes().toString(), //分 "S+": time.getSeconds().toString() //秒 }; for (let k in opt) { ret = new RegExp("(" + k + ")").exec(fmt) if (ret) { fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))); } } return fmt; }, // 获取k线数据,生成k线 getKline() { console.log('qq'); const that = this; axiosGet('/index/history', { instId: that.typeId, bar: that.current, limit: 300 }).then((res) => { const ar = res.map((e) => { let dateTime = new Date(+e[0]); e[0] = that.initDay(dateTime, "YYYY-mm-dd HH:MM:SS"); return e }).reverse() that.dataKLine = { dates: that.dataInit(ar, 1), data: that.dataInit(ar, 2), volumes: that.dataInit(ar, 3), } that.setKline() }).catch((e) => { console.log(e, '2222'); }) }, // 设置线条数据 setKline() { const that = this; var dataMA5 = that.calculateMA(5, that.dataKLine.data); var dataMA10 = that.calculateMA(10, that.dataKLine.data); var dataMA30 = that.calculateMA(30, that.dataKLine.data); var volumeMA5 = that.calculateMA(5, that.dataKLine.volumes); var volumeMA10 = that.calculateMA(10, that.dataKLine.volumes); myChart.setOption({ xAxis: [{ data: that.dataKLine.dates }, { data: that.dataKLine.dates }, ], series: [{ name: '日K', data: that.dataKLine.data }, { name: 'MA5', data: dataMA5 }, { name: 'MA10', data: dataMA10 }, { name: 'MA30', data: dataMA30 }, { name: 'Volume', data: that.dataKLine.volumes }, { name: 'VolumeMA5', data: volumeMA5 }, { name: 'VolumeMA10', data: volumeMA10 }, ] }) }, // 列表条数不足补全 addItem(list, type) { // type: 1开头加,2末尾加 list = list || []; let len = 20 - list.length; if (len > 0) { for (let i = 0; i < len; i++) { if (type == 1) { list.unshift({}) } else { list.push({}) } } } return list; }, // 获取深度数据 // getDepth() { // this.buyList = this.addItem(depthList().buyList || []); // this.sellList = this.addItem(depthList().sellList || []); // }, // 获取成交记录 getDealHis() { const that = this; axiosGet('/index/deal', { instId: that.typeId, limit: 100 }).then((res) => { // 处理返回数据 this.dealHis = res.map((e) => { const dateTime = new Date(+e.ts) return { "date": that.initDay(dateTime, "mm-dd HH:MM:SS"), // 1买入 2卖出 "takerFlag": e.side == 'buy' ? "1" : '2', "price": e.px, "amount": e.sz } }) }).catch((e) => { console.log("e: " + JSON.stringify(e)); console.log(e); }) }, // 获取项目简介信息 getTokenInfo() { this.tokenInfo = tokenInfo; }, // 切换tab switchTab(val) { const that = this; if (that.current == val) { return }; that.current = val; that.webSocket.close() that.$nextTick(() => { that.scoketInit() }) that.getKline() }, // 切换类目 switchCategory(val) { if (this.category == val) return; this.category = val; if (this.category == 1) { this.getDepth() } else if (this.category == 2) { this.getDealHis() } else { this.getTokenInfo() } }, // 截取数字字符串 保留precision小数 formatterNum(value, precision) { // console.log(value) let reg = new RegExp('^\\d+(?:\\.\\d{0,' + precision + '})?') return value.toString().match(reg) }, // 计算MA calculateMA(dayCount, data) { var result = []; for (var i = 0, len = data.length; i < len; i++) { if (i < dayCount) { result.push('-'); continue; } var sum = 0; for (var j = 0; j < dayCount; j++) { sum += data[i - j][1]; } // console.log(sum, dayCount) result.push((sum / dayCount).toFixed(2)); } return result; }, // 绘制(配置项) draw() { let that = this; var upColor = '#03ad91'; var downColor = '#dd345b'; var colorList = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3' ]; var labelFont = 'bold 12px Sans-serif'; var option = { backgroundColor: '#0d1723', title: { show: false }, legend: { show: false }, visualMap: { show: false, seriesIndex: 4, dimension: 2, pieces: [{ value: 1, color: downColor }, { value: -1, color: upColor }] }, grid: [{ top: '5%', left: 20, right: 20, height: '70%' }, { top: '80%', left: 20, right: 20, height: '16%' }, ], axisPointer: { //坐标轴指示器配置项 link: { xAxisIndex: 'all' }, label: { backgroundColor: '#0d1723', color: '#fff', borderColor: 'rgb(99, 117, 139)', borderWidth: 1, borderRadius: 2, fontSize: 10 } }, xAxis: [{ type: 'category', //坐标轴类型。(value:数值轴,适用于连续数据。,category:类目轴,适用于离散的类目数据,time: 时间轴,适用于连续的时序数据,log:对数轴。适用于对数数据) data: [], //类目数据,在类目轴(type: 'category')中有效。 scale: true, boundaryGap: false, //坐标轴两边留白策略,类目轴和非类目轴的设置和表现不一样。 axisLine: { show: false }, //坐标轴轴线相关设置 axisTick: { show: false }, //坐标轴刻度相关设置。 axisLabel: { show: false, }, //坐标轴刻度标签的相关设置。 splitLine: { show: false, lineStyle: { color: 'rgba(255,255,255, 0.1)' } }, //坐标轴在 grid 区域中的分隔线。 min: 'dataMin', //坐标轴刻度最小值。可以设置成特殊值 'dataMin',此时取数据在该轴上的最小值作为最小刻度。 max: 'dataMax', //坐标轴刻度最大值。可以设置成特殊值 'dataMax',此时取数据在该轴上的最大值作为最大刻度。 axisPointer: { label: { margin: 200 } }, }, { type: 'category', gridIndex: 1, //x 轴所在的 grid 的索引,默认位于第一个 grid。 data: [], //类目数据,在类目轴(type: 'category')中有效。 scale: true, boundaryGap: false, //坐标轴两边留白策略,类目轴和非类目轴的设置和表现不一样。 axisLine: { show: false, lineStyle: { color: 'rgba(255,255,255,1)', width: 1 } }, //坐标轴轴线相关设置 axisTick: { show: false }, //坐标轴刻度相关设置。 axisLabel: { //坐标轴刻度标签的相关设置。 show: true, margin: 6, fontSize: 10, color: 'rgba(99, 117, 139, 1.0)', formatter: function(value) { return echarts.format.formatTime('MM-dd', value); } }, splitNumber: 20, splitLine: { show: false, lineStyle: { color: 'rgba(255,255,255, 0.1)' } }, //坐标轴在 grid 区域中的分隔线。 min: 'dataMin', //坐标轴刻度最小值。可以设置成特殊值 'dataMin',此时取数据在该轴上的最小值作为最小刻度。 max: 'dataMax', //坐标轴刻度最大值。可以设置成特殊值 'dataMax',此时取数据在该轴上的最大值作为最大刻度。 // axisPointer: { show: true, type: 'none', label: { show: false }}, }], yAxis: [{ type: 'value', //坐标轴类型。(value:数值轴,适用于连续数据。,category:类目轴,适用于离散的类目数据,time: 时间轴,适用于连续的时序数据,log:对数轴。适用于对数数据) position: 'right', //y 轴的位置。'left','right' scale: true, //是否是脱离 0 值比例。设置成 true 后坐标刻度不会强制包含零刻度。在双数值轴的散点图中比较有用。(在设置 min 和 max 之后该配置项无效。) axisLine: { show: true }, //坐标轴轴线相关设置。 axisTick: { show: true, inside: true }, //坐标轴刻度相关设置。 axisLabel: { //坐标轴刻度标签的相关设置。 show: true, color: 'rgba(99, 117, 139, 1.0)', inside: true, fontSize: 10, formatter: function(value) { return Number(value).toFixed(2) } }, splitLine: { show: false, lineStyle: { color: 'rgba(255,255,255, 0.1)' } }, //坐标轴在 grid 区域中的分隔线。 }, { type: 'value', position: 'right', scale: true, gridIndex: 1, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: false }, splitLine: { show: false } }], animation: false, //是否开启动画。 color: colorList, tooltip: { show: true, //是否显示提示框组件,包括提示框浮层和 axisPointer。 trigger: 'axis', //触发类型。item,axis,none formatter(params) { let tooltip = ''; let time = '', open = 0, high = 0, low = 0, close = 0, amount = 0; for (var i = 0; i < params.length; i++) { if (params[i].seriesName === '日K') { time = params[i].name; open = params[i].data.length > 1 ? Number(that.formatterNum(params[i].data[ 1], 2)) : 0; close = params[i].data.length > 1 ? Number(that.formatterNum(params[i].data[ 2], 2)) : 0; low = params[i].data.length > 1 ? Number(that.formatterNum(params[i].data[ 3], 2)) : 0; high = params[i].data.length > 1 ? Number(that.formatterNum(params[i].data[ 4], 2)) : 0; amount = params[i].data.length > 1 ? Number(that.formatterNum(params[i] .data[5], 2)) : 0; // console.log(time,open,close,low,high,amount) tooltip = '