|
|
<template> <view style="width: 750rpx; height: 750rpx;"> <l-echart ref="chartRef" @finished="initChart"></l-echart> </view></template><script setup>import { ref, computed, onMounted } from 'vue';
const chartRef = ref(null)// 获取系统信息,替代 window.innerWidth
const systemInfo = uni.getSystemInfoSync()const screenWidth = ref(systemInfo.screenWidth || 375) // 默认值 375px
// 生成30天的交易信号数据
const generateAIGoldBullData = () => { const data = [] for (let i = 0; i < 30; i++) { // 模拟交易信号 [索引, 买入信号, 卖出信号, 持有信号, 强度, 成交量]
const buySignal = Math.random() > 0.7 ? 1 : 0 // 30%概率买入信号
const sellSignal = Math.random() > 0.8 ? 1 : 0 // 20%概率卖出信号
const holdSignal = Math.random() > 0.5 ? 1 : 0 // 50%概率持有信号
const strength = Math.floor(Math.random() * 3) + 1 // 信号强度1-3
const volume = Math.floor(Math.random() * 2000) + 500 // 成交量500-2500
data.push([i, buySignal, sellSignal, holdSignal, strength, volume]) } return data}
// 添加缺失的变量定义
var optionconst AIGoldBull = ref({ JN: generateAIGoldBullData()})
// 模拟多语言数据
const t = ref({ suoxie: 'zh', tianxian: '天线', feixian: '飞线', zhoongxian: '中线', liuxian: '流线', Klinetext_5: 'K线5', Klinetext_6: 'K线6', maipan: '买盘', maipan1: '卖盘'})
// 生成30天的模拟K线数据 [日期, 开盘, 最高, 最低, 收盘]
const generateKLineData = () => { const data = [] let basePrice = 2450 // 黄金基础价格
for (let i = 0; i < 30; i++) { const date = new Date(2024, 0, i + 1).toISOString().split('T')[0] // 模拟价格波动
const volatility = (Math.random() - 0.5) * 50 // ±25的波动
const open = basePrice + volatility const highVolatility = Math.random() * 30 + 10 // 10-40的向上波动
const lowVolatility = Math.random() * 30 + 10 // 10-40的向下波动
const high = Math.max(open, open + highVolatility) const low = Math.min(open, open - lowVolatility) const closeVolatility = (Math.random() - 0.5) * 20 const close = Math.max(low, Math.min(high, open + closeVolatility)) data.push([date, Math.round(open * 100) / 100, Math.round(high * 100) / 100, Math.round(low * 100) / 100, Math.round(close * 100) / 100 ]) basePrice = close // 下一天的基础价格
} return data}
// 生成30天的成交量和技术指标数据 [日期, 成交量1, 成交量2, 指标1, 指标2, 指标3]
const generateWaveVolData = () => { const data = [] for (let i = 0; i < 30; i++) { const date = new Date(2024, 0, i + 1).toISOString().split('T')[0] // 模拟成交量数据
const vol1 = Math.floor(Math.random() * 2000) + 800 // 800-2800
const vol2 = Math.floor(Math.random() * 1500) + 600 // 600-2100
// 模拟技术指标
const indicator1 = Math.floor(Math.random() * 30) + 40 // 40-70
const indicator2 = Math.floor(Math.random() * 40) + 50 // 50-90
const indicator3 = Math.floor(Math.random() * 35) + 60 // 60-95
data.push([date, vol1, vol2, indicator1, indicator2, indicator3]) } return data}
// 生成30天的移动平均线数据 [MA5, MA10, MA20, MA30]
const generateFTLineData = () => { const data = [] let ma5Base = 2450 let ma10Base = 2445 let ma20Base = 2440 let ma30Base = 2435 for (let i = 0; i < 30; i++) { // 模拟移动平均线的平滑变化
ma5Base += (Math.random() - 0.5) * 10 ma10Base += (Math.random() - 0.5) * 8 ma20Base += (Math.random() - 0.5) * 6 ma30Base += (Math.random() - 0.5) * 4 data.push([ Math.round(ma5Base * 100) / 100, Math.round(ma10Base * 100) / 100, Math.round(ma20Base * 100) / 100, Math.round(ma30Base * 100) / 100 ]) } return data}
// 生成模拟数据
const mockKLineData = generateKLineData()const mockWaveVolData = generateWaveVolData()const mockFTLineData = generateFTLineData()
// 生成RSI指标数据 (相对强弱指数)
const generateRSIData = () => { const data = [] for (let i = 0; i < 30; i++) { const rsi = Math.random() * 60 + 20 // RSI值在20-80之间
data.push(Math.round(rsi * 100) / 100) } return data}
// 生成MACD指标数据
const generateMACDData = () => { const data = [] for (let i = 0; i < 30; i++) { const macd = (Math.random() - 0.5) * 20 // MACD值在-10到10之间
const signal = (Math.random() - 0.5) * 15 // 信号线
const histogram = macd - signal // 柱状图
data.push([ Math.round(macd * 100) / 100, Math.round(signal * 100) / 100, Math.round(histogram * 100) / 100 ]) } return data}
// 生成布林带数据
const generateBollingerData = () => { const data = [] let middleLine = 2450 for (let i = 0; i < 30; i++) { middleLine += (Math.random() - 0.5) * 10 const upperBand = middleLine + Math.random() * 30 + 20 // 上轨
const lowerBand = middleLine - Math.random() * 30 - 20 // 下轨
data.push([ Math.round(upperBand * 100) / 100, Math.round(middleLine * 100) / 100, Math.round(lowerBand * 100) / 100 ]) } return data}
// 生成成交量分析数据
const generateVolumeAnalysisData = () => { const data = [] for (let i = 0; i < 30; i++) { const buyVolume = Math.floor(Math.random() * 1500) + 500 // 买入量
const sellVolume = Math.floor(Math.random() * 1500) + 500 // 卖出量
const netVolume = buyVolume - sellVolume // 净买入量
data.push([buyVolume, sellVolume, netVolume]) } return data}
// 生成市场情绪数据
const generateMarketSentimentData = () => { const sentiments = ['极度恐慌', '恐慌', '中性', '贪婪', '极度贪婪'] const data = [] for (let i = 0; i < 30; i++) { const sentimentIndex = Math.floor(Math.random() * 100) // 0-100的情绪指数
const sentimentLabel = sentiments[Math.floor(sentimentIndex / 20)] data.push({ date: new Date(2024, 0, i + 1).toISOString().split('T')[0], index: sentimentIndex, label: sentimentLabel, fearGreedRatio: Math.random() * 100 }) } return data}
// 生成重要新闻事件数据
const generateNewsEventsData = () => { const events = [ '美联储利率决议', '非农就业数据发布', '通胀数据公布', '地缘政治紧张', '央行政策变化', '经济数据超预期', '市场技术突破', '大宗商品价格波动' ] const data = [] for (let i = 0; i < 10; i++) { // 生成10个随机事件
const randomDay = Math.floor(Math.random() * 30) + 1 const event = events[Math.floor(Math.random() * events.length)] const impact = Math.floor(Math.random() * 5) + 1 // 影响力1-5
data.push({ date: new Date(2024, 0, randomDay).toISOString().split('T')[0], event: event, impact: impact, type: Math.random() > 0.5 ? 'positive' : 'negative' }) } return data.sort((a, b) => new Date(a.date) - new Date(b.date))}
// 生成价格预测数据
const generatePricePredictionData = () => { const data = [] let currentPrice = 2450 for (let i = 0; i < 7; i++) { // 未来7天预测
const date = new Date(2024, 1, i + 1).toISOString().split('T')[0] // 2月份
// 模拟AI预测的价格区间
const prediction = currentPrice + (Math.random() - 0.5) * 100 const confidence = Math.random() * 40 + 60 // 60-100%的置信度
const upperBound = prediction + Math.random() * 50 const lowerBound = prediction - Math.random() * 50 data.push({ date: date, predicted_price: Math.round(prediction * 100) / 100, confidence: Math.round(confidence), upper_bound: Math.round(upperBound * 100) / 100, lower_bound: Math.round(lowerBound * 100) / 100 }) currentPrice = prediction } return data}
// 模拟提取的绘图数据
const extractedDrawData = { KLine20: mockKLineData, WAVEVOL: mockWaveVolData, FTLINE: mockFTLineData, RSI: generateRSIData(), MACD: generateMACDData(), BOLLINGER: generateBollingerData(), VOLUME_ANALYSIS: generateVolumeAnalysisData(), MARKET_SENTIMENT: generateMarketSentimentData(), NEWS_EVENTS: generateNewsEventsData(), PRICE_PREDICTION: generatePricePredictionData()}
const fnShowEcharts4 = (extractedDrawData) => { const splitData = (b) => { const a = JSON.parse(JSON.stringify(b)) let categoryData = [] let values = [] for (let i = 0; i < a.length; i++) { categoryData.push(a[i].splice(0, 1)[0]) values.push(a[i]) } return { categoryData, values } } var bodongliang = splitData(extractedDrawData.WAVEVOL) function bodongliangData(values, i) { return values.map((subArray) => subArray[i]) } function calculateMA(index, data) { let result = [] if (data.FTLINE) { data.FTLINE.forEach((item) => { result.push(item[index]) }) } return result } function vwToPx(vw) { return (screenWidth.value * vw) / 100 } var dealData = splitData(extractedDrawData.KLine20) var dealGnBullData = AIGoldBull.value.JN const textEcharts = t.value const firstLegend = computed(() => { if (screenWidth.value < 768) { if (textEcharts.suoxie === 'en' || textEcharts.suoxie === 'th') { return '2%' } else if (textEcharts.suoxie === 'kr') { return '2%' } else { return '2%' } } else { return textEcharts.suoxie === 'en' || textEcharts.suoxie === 'th' || textEcharts.suoxie === 'kr' ? '9%' : '9%' } }) const processBarData = (data) => { const barData = [] data.forEach((item) => { let color switch (item[4]) { case 1: color = '#13E113' break case 2: color = '#FF0E00' break case 3: color = '#0000FE' break case 4: color = '#1397FF' break } barData.push({ value: item[5], itemStyle: { normal: { color: color } } }) }) return { barData } } const { barData } = processBarData(dealGnBullData) option = { tooltip: { trigger: 'axis', axisPointer: { type: 'cross' }, backgroundColor: 'rgba(119, 120, 125, 0.6)', borderWidth: 1, borderColor: '#77787D', padding: 10, textStyle: { color: '#fff' } }, axisPointer: { link: [ { xAxisIndex: 'all' } ], label: { backgroundColor: '#77787D' } }, toolbox: { show: false }, grid: [ { left: screenWidth.value > 768 ? '10%' : '12%', right: screenWidth.value > 768 ? '4%' : '6%', top: screenWidth.value > 768 ? '10%' : '12%', height: screenWidth.value > 768 ? '35%' : '34%', containLabel: false }, { left: screenWidth.value > 768 ? '10%' : '12%', right: screenWidth.value > 768 ? '4%' : '6%', top: screenWidth.value > 768 ? '48%' : '48%', height: screenWidth.value > 768 ? '19%' : '21%', containLabel: false }, { left: screenWidth.value > 768 ? '10%' : '12%', right: screenWidth.value > 768 ? '4%' : '6%', top: screenWidth.value > 768 ? '70%' : '71%', height: screenWidth.value > 768 ? '19%' : '21%', containLabel: false } ], xAxis: [ { type: 'category', data: dealData.categoryData, boundaryGap: true, axisLine: { onZero: false }, splitLine: { show: false }, min: 'dataMin', max: 'dataMax', axisPointer: { z: 100, label: { show: false // 不显示标签
} }, axisLine: { lineStyle: { color: 'black' } }, //
axisLabel: { show: false }, axisTick: { show: false } }, { type: 'category', gridIndex: 1, data: dealData.categoryData, boundaryGap: true, axisPointer: { z: 100, label: { show: false // 不显示标签
} }, axisLine: { lineStyle: { color: 'black' } }, axisLabel: { show: false, interval: 'auto' }, axisTick: { show: false } }, { type: 'category', gridIndex: 2, data: dealData.categoryData, boundaryGap: true, axisLine: { lineStyle: { color: 'black' } }, axisLabel: { show: true, interval: 'auto', fontSize: screenWidth.value > 768 ? 15 : 9 }, axisTick: { show: false } } ], yAxis: [ { scale: true, gridIndex: 0, position: 'left', axisLabel: { inside: false, align: 'right', fontSize: screenWidth.value > 768 ? 15 : 9 }, axisLine: { show: true, lineStyle: { fontSize: '', color: 'black' } }, axisTick: { show: false }, splitLine: { show: false } }, { scale: true, gridIndex: 1, splitNumber: 4, min: 0, minInterval: 1, axisLabel: { show: true, fontSize: screenWidth.value > 768 ? 15 : 9, margin: 8, }, axisLine: { show: true, lineStyle: { color: 'black' } }, axisTick: { show: false }, splitLine: { show: true, lineStyle: { type: 'dashed' } }, boundaryGap: ['20%', '20%'] }, { scale: true, gridIndex: 2, splitNumber: 2, axisLabel: { show: true, fontSize: screenWidth.value > 768 ? 15 : 9 }, axisLine: { show: true, lineStyle: { color: 'black' } }, axisTick: { show: false }, splitLine: { show: false } } ], dataZoom: [ { type: 'inside', xAxisIndex: [0, 1, 2], start: 50, end: 100 }, { show: true, xAxisIndex: [0, 1, 2], type: 'slider', start: 50, end: 100 } ], series: [ { type: 'candlestick', name: '日K', xAxisIndex: 0, yAxisIndex: 0, data: dealData.values, itemStyle: { normal: { color0: 'red', color: 'green', borderColor0: 'red', borderColor: 'green' } }, gridIndex: 1 }, { name: '成交量', type: 'bar', barWidth: '70%', xAxisIndex: 1, yAxisIndex: 1, data: barData, }, // {
// name: textEcharts.feixian,
// type: 'line',
// data: calculateMA(1, extractedDrawData),
// smooth: true,
// symbol: 'none',
// xAxisIndex: 2,
// yAxisIndex: 2,
// itemStyle: {
// normal: {
// color: '#00a32e',
// lineStyle: {
// color: '#00a32e',
// width: 2,
// type: 'solid'
// }
// }
// }
// },
// {
// name: textEcharts.zhoongxian,
// type: 'line',
// data: calculateMA(2, extractedDrawData),
// smooth: true,
// symbol: 'none',
// xAxisIndex: 2,
// yAxisIndex: 2,
// itemStyle: {
// normal: {
// color: '#de0000',
// lineStyle: {
// color: '#de0000',
// width: 2,
// type: 'solid'
// }
// }
// }
// },
// {
// name: textEcharts.tianxian,
// type: 'line',
// data: calculateMA(3, extractedDrawData),
// smooth: true,
// symbol: 'none',
// xAxisIndex: 2,
// yAxisIndex: 2,
// itemStyle: {
// normal: {
// color: '#ffb300',
// lineStyle: {
// color: '#ffb300',
// width: 2,
// type: 'solid'
// }
// }
// }
// },
// {
// name: textEcharts.liuxian,
// type: 'line',
// data: calculateMA(4, extractedDrawData),
// smooth: true,
// symbol: 'none',
// xAxisIndex: 2,
// yAxisIndex: 2,
// itemStyle: {
// normal: {
// color: '#00c8ff',
// lineStyle: {
// color: '#00c8ff',
// width: 2,
// type: 'solid'
// }
// }
// }
// },
] } initChart()}
// 组件挂载时初始化图表
onMounted(() => { // 调用图表初始化函数
fnShowEcharts4(extractedDrawData)})
// 初始化图表
const initChart = async () => { if (!chartRef.value) return
try { const chart = await chartRef.value.init(echarts) chart.setOption(option) } catch (error) { console.error('图表初始化失败:', error) }}</script>
|