{"news_comment_list":{"headers":{},"original":{"list":{"current_page":1,"data":[],"first_page_url":"\/news?page=1","from":null,"last_page":1,"last_page_url":"\/news?page=1","links":[{"url":null,"label":"« Previous","active":false},{"url":"\/news?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"next_page_url":null,"path":"\/news","per_page":10,"prev_page_url":null,"to":null,"total":0}},"exception":null},"news_viewed_list":{"headers":{},"original":{"list":{"current_page":1,"data":[],"first_page_url":"\/news?page=1","from":null,"last_page":1,"last_page_url":"\/news?page=1","links":[{"url":null,"label":"« Previous","active":false},{"url":"\/news?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"next_page_url":null,"path":"\/news","per_page":20,"prev_page_url":null,"to":null,"total":0}},"exception":null},"news_tag_list":[],"news_list":{"current_page":1,"data":[],"first_page_url":"\/news?page=1","from":null,"last_page":1,"last_page_url":"\/news?page=1","links":[{"url":null,"label":"« Previous","active":false},{"url":"\/news?page=1","label":"1","active":true},{"url":null,"label":"Next »","active":false}],"next_page_url":null,"path":"\/news","per_page":20,"prev_page_url":null,"to":null,"total":0},"visiter_list":{"headers":{},"original":{"user_list":[]},"exception":null}}
测试
© 2026 ® All Rights Reserved.
{{item}}
我们使用 Cookie 来提升您的浏览体验、分析流量并展示个性化内容。继续浏览即表示您同意我们的
隐私政策
同意
setTimeout(()=>{ gubel.api.embedor(); }, 2000);
客服
打开我的小程序[谷堡微站]
creator ai
login
login
logout
login close
customer
关闭
{"avatar":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTKmTsdj2u3lHAN8TmbdrdjKcU663ot9Z2R6RcWE0XwIibzubtgy5TKDJn0szNnXuKPcYJRwlClGsSA\/132","nickname":"PatchTSMixer(TSMix)","bio":"简单好用的股票分析指标","description":"一个基于PatchTSMixer打造的股票分析指标","config":{"layout":"index_body_1,index_body_2,index_body_3,index_body_left_1,index_body_left_2,index_body_right_1,index_body_right_2,news_topbar,news_navbar,news_detail_topbar,news_detail_navbar,about_topbar,about_navbar"},"is_auto_login":1,"code_version":null,"content":"","contact":"","ui_version":"v2","aeo":null,"domain":"tsmixer.gubel.cn","tel":"","country":null,"province":null,"city":null,"address":"","lat":null,"lng":null,"chat_avatar_path":"\/\/www.gubel.cn\/imgs\/chat\/avatars\/avatar_1.png","navs":[],"banners":[],"templates":[{"position_name":"index_block","content":"<jinrong-home><\/jinrong-home>\r\n\r\n\r\n<script>\r\n gubel.api.createComponent('jinrongHome', {\r\n template: `\r\n <div>\r\n <div class=\"border-bottom position-fixed top-0 w-100 bg-body-secondary\">\r\n <div class=\"container py-2\" style=\"max-width:600px\">\r\n <div class=\"hstack gap-2\">\r\n <input class=\"form-control w-100\" v-model=\"kw\" maxlength=\"100\" placeholder=\"搜索您的股票...\">\r\n <a class=\"btn btn-info\" style=\"width:90px\" href=\"\/\/console.gubel.cn\">控制台<\/a>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <div style=\"height:60px\"><\/div>\r\n\r\n <div class=\"container\" style=\"max-width:600px\">\r\n <div class=\"py-4 text-center\" v-if=\"listLoading\"><loading><\/loading><\/div>\r\n <template\r\n v-for=\"(item, index) in gupiao_list\"\r\n :key=\"index\"\r\n >\r\n <div\r\n class=\"rounded-3 my-2 py-2 px-3 bg-body-tertiary\"\r\n style=\"font-size:14px\"\r\n v-if=\"item.symbol.substring(0, 2)!=='bj' && (!kw||(item.symbol+' '+item.sname).indexOf(kw)>-1)\"\r\n >\r\n <div class=\"hstack bg-body-tertiary gap-3\">\r\n <span>{{item.symbol}} {{item.sname}}<\/span>\r\n <a\r\n class=\"ms-auto btn btn-sm btn btn-outline-secondary rounded-3\"\r\n href=\"javascript:;\"\r\n @click=\"handlePrice(item.symbol)\"\r\n >\r\n 详情\r\n <\/a>\r\n <\/div>\r\n <div v-if=\"item.today_data\" class=\"bg-body rounded-3 p-3\">\r\n <div class=\"row row-cols-3\" style=\"font-size:12px\">\r\n <div class=\"col-12 text-end\">\r\n <div class=\"btn-group btn-group-sm\" role=\"group\" aria-label=\"Small button group\">\r\n <button type=\"button\" class=\"btn btn-secondary\" @click=\"handlwShowFunds(item)\">资金流向<\/button>\r\n <button type=\"button\" class=\"btn btn-secondary\" @click=\"handlwShowK(item)\">K线<\/button>\r\n <\/div>\r\n <\/div>\r\n <div class=\"col-6 py-1\">{{item.today_data[1]}}<\/div>\r\n <div class=\"col-6 py-1 text-end\">\r\n {{item.today_data[30].slice(8,10)}}:{{item.today_data[30].slice(10,12)}}:{{item.today_data[30].slice(12,14)}}\r\n <\/div>\r\n <div class=\"col\">现价:{{item.today_data[3]}}<\/div>\r\n <div class=\"col\">昨收:{{item.today_data[4]}}<\/div>\r\n <div class=\"col\">今开:{{item.today_data[5]}}<\/div>\r\n <div class=\"col-6\">今日最高:{{item.today_data[33]}}<\/div>\r\n <div class=\"col-6\">今日最低:{{item.today_data[34]}}<\/div>\r\n <div class=\"col-6\">成交量:{{(item.today_data[6]\/10000).toFixed(2)}}万手<\/div>\r\n <div class=\"col-6\">成交额:{{(item.today_data[35].split('\/')[2]\/100000000).toFixed(2)}}亿元<\/div>\r\n <div class=\"col-12\">涨跌:{{item.today_data[31]}} ({{item.today_data[32]}}%)<\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <\/template>\r\n <\/div>\r\n \r\n <div class=\"modal fade\" data-bs-backdrop=\"static\" data-bs-keyboard=\"false\" tabindex=\"-1\" id=\"found_detail_001\">\r\n <div class=\"modal-dialog modal-lg modal-dialog-centered\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h1 class=\"modal-title fs-5\">{{symbolDetail?.sname}} 资金流向<\/h1>\r\n <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"><\/button>\r\n <\/div>\r\n <div class=\"modal-body\">\r\n <div>\r\n <div class=\"mt-2 mb-2\">\r\n 主力净流入 {{getParsePrice(foundFieldValue?.data?.f137)}}\r\n <\/div>\r\n <div class=\"my-4\">\r\n <div class=\"fw-bold my-2\">今日资金流向<\/div>\r\n <div>\r\n 主力流入 \r\n <span class=\"text-danger fw-bold\">\r\n {{getParsePrice(foundFieldValue?.data?.f135)}}\r\n <\/span>,\r\n 占流通市值比例\r\n <span class=\"text-danger fw-bold\">\r\n {{(Number(foundFieldValue?.data?.f135)\/Number(foundFieldValue?.data?.f117)*100).toFixed(2)}}%\r\n <\/span>,\r\n 其中超大单流入\r\n <span class=\"text-danger fw-bold\">\r\n {{getParsePrice(foundFieldValue?.data?.f138)}}\r\n <\/span>,\r\n 大单流入\r\n <span class=\"text-danger fw-bold\">\r\n {{getParsePrice(foundFieldValue?.data?.f141)}}\r\n <\/span>。\r\n <\/div>\r\n <div style=\"height:200px\" id=\"detail-chart\" class=\"mt-3\"><\/div>\r\n <div class=\"my-4\">\r\n <table class=\"table table-bordered text-center\">\r\n <thead>\r\n <tr>\r\n <th colspan=\"2\" class=\"bg-body-secondary\"><\/th>\r\n <th class=\"bg-body-secondary fw-normal\">资金流出<\/th>\r\n <th class=\"bg-body-secondary fw-normal\">资金流入<\/th>\r\n <\/tr>\r\n <\/thead>\r\n <tbody>\r\n <tr>\r\n <td rowspan=\"2\" class=\"bg-body-secondary\">主力<\/td>\r\n <td>超大单<\/td>\r\n <td class=\"text-success fw-bold\">{{getParsePrice(foundFieldValue?.data?.f139)}}<\/td>\r\n <td class=\"text-danger fw-bold\">{{getParsePrice(foundFieldValue?.data?.f138)}}<\/td>\r\n <\/tr>\r\n <tr>\r\n <td>大单<\/td>\r\n <td class=\"text-success fw-bold\">{{getParsePrice(foundFieldValue?.data?.f142)}}<\/td>\r\n <td class=\"text-danger fw-bold\">{{getParsePrice(foundFieldValue?.data?.f141)}}<\/td>\r\n <\/tr>\r\n <tr>\r\n <td rowspan=\"2\" class=\"bg-body-secondary\">散户<\/td>\r\n <td>中单<\/td>\r\n <td class=\"text-success fw-bold\">{{getParsePrice(foundFieldValue?.data?.f145)}}<\/td>\r\n <td class=\"text-danger fw-bold\">{{getParsePrice(foundFieldValue?.data?.f144)}}<\/td>\r\n <\/tr>\r\n <tr>\r\n <td>小单<\/td>\r\n <td class=\"text-success fw-bold\">{{getParsePrice(foundFieldValue?.data?.f148)}}<\/td>\r\n <td class=\"text-danger fw-bold\">{{getParsePrice(foundFieldValue?.data?.f147)}}<\/td>\r\n <\/tr>\r\n <\/tbody>\r\n <\/table>\r\n <\/div>\r\n <\/div>\r\n <div class=\"my-4\">\r\n <div class=\"fw-bold my-2\"> 今日资金净流入构成<\/div>\r\n <div>\r\n 主力净流入\r\n <span class=\"text-success fw-bold\">\r\n {{getParsePrice(foundFieldValue?.data?.f137)}}\r\n <\/span>,占流通市值比例\r\n <span class=\"fw-bold\">\r\n {{(Number(foundFieldValue?.data?.f137)\/Number(foundFieldValue?.data?.f117)*100).toFixed(2)}}%\r\n <\/span>,\r\n 其中超大单净流入\r\n <span class=\"text-success fw-bold\">\r\n {{getParsePrice(foundFieldValue?.data?.f140)}}\r\n <\/span>,大单净流入\r\n <span class=\"text-success fw-bold\">\r\n {{getParsePrice(foundFieldValue?.data?.f143)}}\r\n <\/span>。\r\n <\/div>\r\n <div class=\"mt-3\" style=\"height:200px\" id=\"liuru-chart\"><\/div>\r\n <\/div>\r\n <div class=\"fw-bold my-4\">最近主力增仓趋势<\/div>\r\n <div v-if=\"oiRiseTrendNav.length\">\r\n <div class=\"row row-cols-4 g-1\">\r\n <div class=\"col\" v-for=\"(item, index) in oiRiseTrendNav\" :key=\"index\">\r\n <div\r\n class=\"py-2 text-center\"\r\n :class=\"foundNavActive===item.name?'bg-warning':'bg-body-secondary'\"\r\n @click=\"handleShowChart(item.name, item.dayData)\"\r\n style=\"cursor:pointer\"\r\n >\r\n <div>{{item.name}}<\/div>\r\n <div>{{item.count}}<\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <div class=\"mt-4\" style=\"height:300px\" id=\"found_chart\"><\/div>\r\n <\/div>\r\n <div v-if=\"foundsDetail?.daykline?.klines\">\r\n <div class=\"fw-bold my-2\">资金流向历史数据一览<\/div>\r\n <table class=\"table\">\r\n <thead>\r\n <tr>\r\n <th scope=\"col\" class=\"text-body-tertiary fw-normal\">日期<\/th>\r\n <th scope=\"col\" class=\"text-body-tertiary fw-normal\">收盘价<\/th>\r\n <th scope=\"col\" class=\"text-body-tertiary fw-normal\">涨跌幅<\/th>\r\n <th scope=\"col\" class=\"text-body-tertiary fw-normal\">净流入<\/th>\r\n <\/tr>\r\n <\/thead>\r\n <tbody>\r\n <tr \r\n v-for=\"(item, index) in [...(foundsDetail?.daykline?.klines || [])].reverse()\"\r\n :key=\"index\"\r\n class=\"fw-bold\"\r\n >\r\n <td class=\"fw-normal\">{{item.split(',')[0]}}<\/td>\r\n <td :class=\"item.split(',')[3]>0?'text-danger':'text-success'\">\r\n {{item.split(',')[2]}}\r\n <\/td>\r\n <td :class=\"item.split(',')[3]>0?'text-danger':'text-success'\">\r\n {{item.split(',')[3]}}%\r\n <\/td>\r\n <td :class=\"item.split(',')[1]>0?'text-danger':'text-success'\">\r\n {{getParsePrice(item.split(',')[1])}}\r\n <\/td>\r\n <\/tr>\r\n <\/tbody>\r\n <\/table>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <div class=\"modal fade\" data-bs-backdrop=\"static\" data-bs-keyboard=\"false\" tabindex=\"-1\" id=\"k_detail_001\">\r\n <div class=\"modal-dialog modal-lg modal-dialog-centered\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h1 class=\"modal-title fs-5\">{{symbolDetail?.sname}} [{{symbolDetail?.symbol}}]<\/h1>\r\n <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"><\/button>\r\n <\/div>\r\n <div class=\"modal-body\">\r\n <div>\r\n <div class=\"hstack\">\r\n <div>\r\n <div class=\"btn-group btn-group-sm\" role=\"group\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-outline-secondary\"\r\n :class=\"{'active':kChart.lineType==='time-share'}\"\r\n @click=\"kChart.lineType='time-share'\"\r\n >\r\n 分时\r\n <\/button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-outline-secondary\"\r\n :class=\"{'active':kChart.lineType==='k-share'}\"\r\n @click=\"kChart.lineType='k-share'\"\r\n >\r\n K线\r\n <\/button>\r\n <\/div>\r\n <\/div>\r\n <div \r\n class=\"ms-2\"\r\n v-if=\"kChart.lineType==='k-share'\"\r\n >\r\n <div class=\"btn-group btn-group-sm\" role=\"group\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-outline-secondary\"\r\n :class=\"{'active':kChart.time==='day'}\"\r\n @click=\"kChart.time='day'\"\r\n >\r\n 日\r\n <\/button>\r\n <button \r\n type=\"button\"\r\n class=\"btn btn-outline-secondary\"\r\n :class=\"{'active':kChart.time==='month'}\"\r\n @click=\"kChart.time='month'\"\r\n >\r\n 月\r\n <\/button>\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-outline-secondary\"\r\n :class=\"{'active':kChart.time==='year'}\"\r\n @click=\"kChart.time='year'\"\r\n \r\n >\r\n 年\r\n <\/button>\r\n <\/div>\r\n <\/div>\r\n <div class=\"ms-auto\" v-if=\"kChart.lineType==='k-share'\">\r\n <div class=\"btn-group btn-group-sm\">\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-secondary dropdown-toggle\"\r\n data-bs-toggle=\"dropdown\"\r\n data-bs-display=\"static\"\r\n aria-expanded=\"false\"\r\n >\r\n <span v-if=\"kChart.indicator===''\">指标<\/span>\r\n <span v-if=\"kChart.indicator==='ma'\">均线<\/span>\r\n <span v-if=\"kChart.indicator==='boll'\">布林线<\/span>\r\n <span v-if=\"kChart.indicator==='ai'\">Ai(tsmixer)<\/span>\r\n <\/button>\r\n <ul class=\"dropdown-menu dropdown-menu-lg-end\">\r\n <li>\r\n <button\r\n class=\"dropdown-item\"\r\n type=\"button\"\r\n :class=\"{'active':kChart.indicator==='ma'}\"\r\n @click=\"kChart.indicator='ma'\"\r\n >\r\n 均线\r\n <\/button>\r\n <\/li>\r\n <li>\r\n <button\r\n class=\"dropdown-item\"\r\n type=\"button\"\r\n :class=\"{'active':kChart.indicator==='boll'}\"\r\n @click=\"kChart.indicator='boll'\"\r\n >\r\n 布林线\r\n <\/button>\r\n <\/li>\r\n <li>\r\n <button\r\n class=\"dropdown-item\"\r\n type=\"button\"\r\n :class=\"{'active':kChart.indicator==='ai'}\"\r\n @click=\"kChart.indicator='ai'\"\r\n >\r\n Ai(tsmixer)\r\n <\/button>\r\n <\/li>\r\n <\/ul>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <div class=\"mt-3\" id=\"k_chart\" style=\"height:450px\"><\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n <\/div>\r\n `,\r\n data(){\r\n return {\r\n kw: '',\r\n gupiao_list: [],\r\n market: null,\r\n listLoading: false,\r\n btModal: null,\r\n symbolDetail: null,\r\n foundsDetail: {},\r\n oiRiseTrendData: null,\r\n oiRiseTrendNav: [],\r\n foundNavActive: '',\r\n foundFieldValue: null,\r\n secid: null,\r\n ut: 'f057cbcbce2a86e2866ab8877db1d059',\r\n kChart: {\r\n lineType: 'time-share',\r\n time: 'day',\r\n indicator: ''\r\n }\r\n };\r\n },\r\n mounted(){\r\n const me = this;\r\n me.getK780();\r\n me.btModal = new bootstrap.Modal('#k_detail_001');\r\n me.btFoundsModal = new bootstrap.Modal('#found_detail_001');\r\n },\r\n methods: {\r\n getK780(){\r\n const me = this;\r\n me.listLoading = true;\r\n gubel.api.cache('api-gupiao-list-26-06-07', feed=>{\r\n $.get('\/api\/getApiData.api', {\r\n url: 'http:\/\/api.k780.com\/?app=finance.stock_list&category=hs&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json'\r\n }, function(res){\r\n const data = $.parseJSON(res.data);\r\n feed(data);\r\n });\r\n }, 60*24*30).then(res=>{\r\n setTimeout(()=>{\r\n me.gupiao_list = res.result.lists;\r\n me.listLoading = false;\r\n }, 1000);\r\n });\r\n },\r\n handlePrice(symbolName){\r\n const me = this;\r\n gubel.api.cache('current_symbol_data_9_'+symbolName, feed=>{\r\n let cacheData = {};\r\n $.get('https:\/\/web.ifzq.gtimg.cn\/appstock\/app\/fqkline\/get', {\r\n param: symbolName+\",day,,,120,\"\r\n }, function(res){\r\n const data = $.parseJSON(res);\r\n const days = data.data[symbolName].day;\r\n\r\n params = data.data[symbolName].qt[symbolName];\r\n let currentSymbol = me.gupiao_list.find(item=>item.symbol==symbolName);\r\n\r\n cacheData.market = data.data[symbolName].qt.market;\r\n cacheData.days = days;\r\n cacheData.today_data = params;\r\n\r\n const now = new Date();\r\n const lastYear = now.getFullYear() - 1; \/\/ 去年年份\r\n const thisYear = now.getFullYear(); \/\/ 今年年份\r\n const month = String(now.getMonth() + 1).padStart(2, '0'); \/\/ 当前月份(自动补0)\r\n const monthIdx = now.getMonth();\r\n\r\n \/\/ 拼接起止日期\r\n const startDate = `${lastYear}-${month}-01`; \/\/ 去年当月1号\r\n const lastDay = new Date(thisYear, monthIdx + 1, 0).getDate();\r\n const endDate = `${thisYear}-${String(monthIdx+1).padStart(2,'0')}-${String(lastDay).padStart(2,'0')}`;\r\n const param_str = `${symbolName},month,${startDate},${endDate},500,qfq`;\r\n\r\n $.get('https:\/\/web.ifzq.gtimg.cn\/appstock\/app\/fqkline\/get', {\r\n param: param_str\r\n }, function(res){\r\n const monthData = $.parseJSON(res);\r\n cacheData.months = monthData.data[symbolName].qfqmonth;\r\n\r\n const now = new Date();\r\n const thisYear = now.getFullYear();\r\n const monthIdx = now.getMonth();\r\n const startYear = thisYear - 10;\r\n const startDate = `${startYear}-${String(monthIdx + 1).padStart(2, '0')}-01`;\r\n const lastDay = new Date(thisYear, monthIdx + 1, 0).getDate();\r\n const endDate = `${thisYear}-${String(monthIdx + 1).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`;\r\n const param_m = `${symbolName},month,${startDate},${endDate},500,qfq`;\r\n \r\n $.get('https:\/\/web.ifzq.gtimg.cn\/appstock\/app\/fqkline\/get', {\r\n param: param_m\r\n }, function(res){\r\n const mData = $.parseJSON(res);\r\n const monthsData = mData.data[symbolName].qfqmonth;\r\n const yearMap = {};\r\n monthsData.forEach(str => {\r\n \/\/ 切割字符串:日期,开盘,收盘,最高,最低,成交量,成交额\r\n const [date, open, close, high, low, vol] = str;\r\n const year = date.substring(0, 4); \/\/ 取出 2016、2017...\r\n\r\n if (!yearMap[year]) {\r\n \/\/ 第一年:初始化\r\n yearMap[year] = {\r\n open: +open,\r\n high: +high,\r\n low: +low,\r\n close: +close,\r\n vol: +vol,\r\n date: year + '-12-31'\r\n };\r\n } else {\r\n \/\/ 合并:更新最高、最低、累加成交量、更新收盘价\r\n yearMap[year].high = Math.max(yearMap[year].high, +high);\r\n yearMap[year].low = Math.min(yearMap[year].low, +low);\r\n yearMap[year].close = close;\r\n yearMap[year].vol += +vol;\r\n }\r\n });\r\n\r\n \/\/ 转成和月K一样的字符串数组格式\r\n const yearData = Object.keys(yearMap).sort().map(y => {\r\n const d = yearMap[y];\r\n return [d.date, d.open, d.close, d.high, d.low, d.vol];\r\n });\r\n\r\n cacheData.years = yearData;\r\n feed(cacheData);\r\n });\r\n });\r\n });\r\n }, 60).then(res=>{\r\n let currentSymbol = me.gupiao_list.find(item=>item.symbol==symbolName);\r\n currentSymbol.market = res.market;\r\n currentSymbol.days = res.days;\r\n currentSymbol.today_data = res.today_data;\r\n currentSymbol.months = res.months;\r\n currentSymbol.yearData = res.years;\r\n });\r\n },\r\n handleShowChart(activeIndex,dayData){\r\n const me = this;\r\n me.foundNavActive = activeIndex;\r\n let reversedata = [...dayData].reverse();\r\n require(['echarts'], function(echarts){\r\n const foundChart = echarts.init(document.getElementById('found_chart'));\r\n\r\n let xData = [];\r\n let moneyData = [];\r\n let priceData = [];\r\n let percentData = [];\r\n\r\n reversedata.forEach(item=>{\r\n const currentData = item.split(',');\r\n xData.push(currentData[0]);\r\n priceData.push(currentData[2]);\r\n moneyData.push(currentData[1]);\r\n percentData.push(currentData[3]);\r\n });\r\n\r\n const option = {\r\n tooltip: {\r\n trigger: 'axis',\r\n axisPointer: {type: 'cross'},\r\n formatter: function(params) {\r\n let idx = params[0].dataIndex;\r\n let moneyVal = moneyData[idx];\r\n let moneyText = \"\";\r\n\r\n if (Math.abs(moneyVal) >= 100000000) {\r\n moneyText = (moneyVal \/ 100000000).toFixed(2) + '亿';\r\n } else if (Math.abs(moneyVal) >= 10000) {\r\n moneyText = (moneyVal \/ 10000).toFixed(2) + '万';\r\n } else {\r\n moneyText = moneyVal.toFixed(2);\r\n }\r\n\r\n let res = params[0].axisValue + '<br\/>';\r\n res += `股价:${priceData[idx]}元<br\/>`;\r\n res += `涨跌幅:${percentData[idx]}%<br\/>`;\r\n res += `主力净流入:${moneyText}`;\r\n return res;\r\n }\r\n },\r\n legend: {\r\n top:5,\r\n left:0,\r\n icon:'rect',\r\n selectedMode:false,\r\n textStyle: {\r\n color: '#999',\r\n fontSize: 12\r\n },\r\n data:[\r\n {name:'主力净流入',itemStyle:{color:'#F26022'}},\r\n {name:'主力净流出',itemStyle:{color:'#23B947'}},\r\n {name:'股价',itemStyle:{color:'#ff9922'}}\r\n ]\r\n },\r\n grid: {right:30},\r\n xAxis: [{type:'category', data:xData}],\r\n yAxis: [\r\n {name:'', splitLine:{lineStyle:{type:'solid'}}},\r\n {name:'', position:'right', splitLine:{show:false}}\r\n ],\r\n series: [\r\n {\r\n name:'主力净流入',type:'bar',yAxisIndex:0,data:moneyData,barMaxWidth: 20,\r\n itemStyle:{\r\n color:p=> p.data>0 ? '#e63929' : '#34b853'\r\n }\r\n },{\r\n name:'主力净流出',type:'bar',data:[],itemStyle:{color:'#34b853'}\r\n },{\r\n name:'股价',type:'line',yAxisIndex:1,data:priceData,color:'#ff9922',symbol:'none'\r\n }\r\n ]\r\n };\r\n foundChart.setOption(option);\r\n });\r\n },\r\n setOiRiseTrend(day){\r\n const me = this;\r\n let reversedata = [...me.oiRiseTrendData].reverse().slice(0, day);\r\n let count = 0;\r\n reversedata.forEach((item, index)=>{\r\n const itemArr = item.split(',');\r\n count+=parseFloat(itemArr[1]);\r\n });\r\n me.oiRiseTrendNav.push({\r\n name: day+'日净流入',\r\n count: (count\/100000000).toFixed(2)+'亿',\r\n dayData: reversedata\r\n });\r\n },\r\n getUrlDataByDongfang(param, callback){\r\n $.get('https:\/\/push2his.eastmoney.com\/api\/qt\/stock\/fflow\/daykline\/get', param, function(res){\r\n if(callback){\r\n callback(res);\r\n }\r\n });\r\n },\r\n getSecid(symbolName){\r\n let res = symbolName.match(\/^([a-zA-Z]+)(\\d+)$\/);\r\n let letterStr = res[1];\r\n let numStr = res[2];\r\n let secid;\r\n\r\n let head = numStr.slice(0,2);\r\n if(['60','68'].includes(head)){\r\n secid = 1;\r\n }else{\r\n secid = 0;\r\n }\r\n return secid+'.'+numStr;\r\n },\r\n getParsePrice(value){\r\n const num = Number(value);\r\n const absNum = Math.abs(num);\r\n if (absNum >= 100000000) {\r\n return (num \/ 100000000).toFixed(2) + '亿';\r\n } else if (absNum >= 10000) {\r\n return (num \/ 10000).toFixed(2) + '万';\r\n } else {\r\n return num.toFixed(2);\r\n }\r\n },\r\n renderDetailChart(){\r\n const me = this;\r\n const field = me.foundFieldValue.data;\r\n\r\n const red_chaoda = (Number(field.f138) \/ (Number(field.f138)+Number(field.f141)+Number(field.f144)+Number(field.f147)) * 100).toFixed(2);\r\n const red_da = (Number(field.f141) \/ (Number(field.f138)+Number(field.f141)+Number(field.f144)+Number(field.f147)) * 100).toFixed(2);\r\n const red_zhong = (Number(field.f144) \/ (Number(field.f138)+Number(field.f141)+Number(field.f144)+Number(field.f147)) * 100).toFixed(2);\r\n const red_xiao = (Number(field.f147) \/ (Number(field.f138)+Number(field.f141)+Number(field.f144)+Number(field.f147)) * 100).toFixed(2);\r\n\r\n const green_xiao = (Number(field.f148) \/ (Number(field.f139)+Number(field.f142)+Number(field.f145)+Number(field.f148)) * 100).toFixed(2);\r\n const green_zhong = (Number(field.f145) \/ (Number(field.f139)+Number(field.f142)+Number(field.f145)+Number(field.f148)) * 100).toFixed(2);\r\n const green_da = (Number(field.f142) \/ (Number(field.f139)+Number(field.f142)+Number(field.f145)+Number(field.f148)) * 100).toFixed(2);\r\n const green_chaoda = (Number(field.f139) \/ (Number(field.f139)+Number(field.f142)+Number(field.f145)+Number(field.f148)) * 100).toFixed(2);\r\n\r\n require(['echarts'], function(echarts){\r\n const myChart = echarts.init(document.getElementById('detail-chart'));\r\n const option = {\r\n tooltip: { trigger: 'none' },\r\n series: [\r\n {\r\n name: '内层',\r\n type: 'pie',\r\n radius: ['0%', '45%'],\r\n center: ['50%', '50%'],\r\n startAngle: 90,\r\n clockwise: false,\r\n data: [\r\n { name:'主力', value:Number(red_chaoda)+Number(red_da), itemStyle:{color:'#d62828'} },\r\n { name:'散户', value:Number(red_zhong)+Number(red_xiao), itemStyle:{color:'#FA7878'} },\r\n\r\n { name:'散户', value:Number(green_zhong)+Number(green_xiao), itemStyle:{color:'#64c964'} },\r\n { name:'主力', value:Number(green_chaoda)+Number(green_da), itemStyle:{color:'#27a844'} },\r\n ],\r\n label: {\r\n show: true,\r\n position: 'inside',\r\n color:'#fff',\r\n fontSize: 9\r\n },\r\n itemStyle:{\r\n borderWidth:2,\r\n borderColor:'#ffffff'\r\n }\r\n },{\r\n name: '外层',\r\n type: 'pie',\r\n radius: ['55%', '70%'],\r\n center: ['50%', '50%'],\r\n startAngle: 90,\r\n clockwise: false,\r\n data: [\r\n { name: '超大单 '+red_chaoda+'%', value:red_chaoda, itemStyle:{color:'#d62828'}, label:{color:'#d62828'}},\r\n { name: '大单 '+red_da+'%', value:red_da, itemStyle:{color:'#FA7878'}, label:{color:'#d62828'} },\r\n { name: '中单 '+red_zhong+'%', value:red_zhong, itemStyle:{color:'#FFB9B9'}, label:{color:'#d62828'} },\r\n { name: '小单 '+red_xiao+'%', value:red_xiao, itemStyle:{color:'#FFE0E0'}, label:{color:'#d62828'} },\r\n\r\n { name: '小单 '+green_xiao+'%', value:green_xiao, itemStyle:{color:'#E6F7E6'}, label:{color:'#27a844'} },\r\n { name: '中单 '+green_zhong+'%', value:green_zhong, itemStyle:{color:'#99dd99'}, label:{color:'#27a844'} },\r\n { name: '大单 '+green_da+'%', value:green_da, itemStyle:{color:'#64c964'}, label:{color:'#27a844'} },\r\n { name: '超大单 '+green_chaoda+'%', value:green_chaoda, itemStyle:{color:'#27a844'}, label:{color:'#27a844'} },\r\n ],\r\n label: {\r\n show: true,\r\n position: 'outer',\r\n fontSize: 12,\r\n },\r\n itemStyle:{\r\n borderWidth:2,\r\n borderColor:'#ffffff'\r\n }\r\n }\r\n ]\r\n };\r\n myChart.setOption(option);\r\n });\r\n },\r\n renderLiuruChart(){\r\n const me = this;\r\n const field = me.foundFieldValue.data;\r\n require(['echarts'], function(echarts){\r\n const myChart = echarts.init(document.getElementById('liuru-chart'));\r\n const dataArr = [\r\n (Number(field.f140)\/10000).toFixed(2),\r\n (Number(field.f143)\/10000).toFixed(2),\r\n (Number(field.f146)\/10000).toFixed(2),\r\n (Number(field.f149)\/10000).toFixed(2)\r\n ];\r\n const option = {\r\n tooltip: { trigger: 'axis', formatter: '{b}<br\/>{c} 万元' },\r\n legend: {\r\n textStyle: {\r\n color: '#999',\r\n fontSize: 12\r\n },\r\n bottom: 0,\r\n data: ['资金净流入', '资金净流出 单位(万元)'],\r\n selectedMode: false\r\n },\r\n grid: { left: 30, right: '4%', bottom: '20%', top: '25%', containLabel: true },\r\n xAxis: { type: 'category', data: ['净超大', '净大单', '净中单', '净小单'] },\r\n yAxis: {\r\n type: 'value',\r\n splitLine: { lineStyle: { type: 'solid' } },\r\n axisLabel: { show: false },\r\n axisTick: { show: false },\r\n axisLine: { show: false }\r\n },\r\n series: [\r\n {\r\n name: '资金净流入',\r\n type: 'bar',\r\n data: [0, 0, 0, 0],\r\n itemStyle: { color: '#E64F22' },\r\n barGap: '-100%',\r\n barWidth: 0,\r\n silent: true\r\n },{\r\n name: '资金净流出 单位(万元)',\r\n type: 'bar',\r\n data: [0, 0, 0, 0],\r\n itemStyle: { color: '#28a745' },\r\n barGap: '-100%',\r\n barWidth: 0,\r\n silent: true\r\n },{\r\n name: 'real',\r\n type: 'bar',\r\n barGap: '-100%',\r\n barWidth: 18,\r\n data: dataArr,\r\n itemStyle: {\r\n color: p => p.value > 0 ? '#E64F22' : '#28a745',\r\n borderRadius: p => p.value > 0 ? [4, 4, 0, 0] : [0, 0, 4, 4]\r\n },\r\n label: { show: false }\r\n },{\r\n type: 'bar',\r\n barGap: '-100%',\r\n barWidth: 18,\r\n data: [0, 0, 0, 0],\r\n silent: true,\r\n itemStyle: { color: 'transparent' },\r\n label: {\r\n show: true,\r\n fontSize: 11,\r\n align: 'center',\r\n formatter: function (params) {\r\n var val = dataArr[params.dataIndex];\r\n return val < 0 ? val : '';\r\n },\r\n position: 'top',\r\n distance: 4,\r\n color: '#28a745'\r\n }\r\n },{\r\n type: 'bar',\r\n barGap: '-100%',\r\n barWidth: 18,\r\n data: [0, 0, 0, 0],\r\n silent: true,\r\n itemStyle: { color: 'transparent' },\r\n label: {\r\n show: true,\r\n fontSize: 11,\r\n align: 'center',\r\n formatter: function (params) {\r\n var val = dataArr[params.dataIndex];\r\n return val > 0 ? val : '';\r\n },\r\n position: 'bottom',\r\n distance: 9,\r\n color: '#E64F22'\r\n }\r\n }\r\n ]\r\n };\r\n myChart.setOption(option);\r\n });\r\n },\r\n handlwShowFunds(symbolDetail){\r\n const me = this;\r\n me.symbolDetail = symbolDetail;\r\n me.secid = me.getSecid(symbolDetail.symbol);\r\n me.oiRiseTrendNav = [];\r\n gubel.api.cache('founds-detail-26-06-06-'+me.secid, feed=>{\r\n $.get('https:\/\/push2.eastmoney.com\/api\/qt\/stock\/get', {\r\n secid: me.secid,\r\n fields: 'f110,f107,f111,f181,f135,f137,f140,f143,f117,f138,f139,f141,f142,f144,f145,f146,f149,f147,f148,f194,f195,f196,f197,f472,f439,f770',\r\n ut: me.ut,\r\n v: Date.now()\r\n }, function(res){\r\n feed(res);\r\n });\r\n }, 5).then(res=>{\r\n me.foundFieldValue = res;\r\n me.renderDetailChart();\r\n me.renderLiuruChart();\r\n });\r\n\r\n gubel.api.cache('api-dongfang-10-'+me.secid, feed=>{\r\n me.getUrlDataByDongfang({\r\n secid: me.secid,\r\n fields1: 'f1,f2,f3,f7',\r\n fields2: 'f51,f52,f62,f63',\r\n lmt: 10,\r\n ut: me.ut,\r\n pos: 0,\r\n num: -120,\r\n v: Date.now()\r\n }, function(res){\r\n feed(res.data);\r\n });\r\n }, 10).then(res=>{\r\n me.foundsDetail.daykline = res;\r\n });\r\n \r\n gubel.api.cache('api-dongfang-120-'+me.secid, feed=>{\r\n me.getUrlDataByDongfang({\r\n secid: me.secid,\r\n fields1: 'f1,f2,f3,f7',\r\n fields2: 'f51,f52,f62,f63',\r\n lmt: 120,\r\n ut: me.ut,\r\n v: Date.now()\r\n }, function(res){\r\n feed(res.data.klines);\r\n });\r\n }, 10).then(res=>{\r\n me.oiRiseTrendData = res;\r\n me.setOiRiseTrend(5);\r\n me.setOiRiseTrend(20);\r\n me.setOiRiseTrend(60);\r\n me.setOiRiseTrend(120);\r\n me.handleShowChart(me.oiRiseTrendNav[2].name, me.oiRiseTrendNav[2].dayData);\r\n });\r\n me.btFoundsModal.show();\r\n },\r\n handlwShowK(symbolDetail){\r\n const me = this;\r\n me.symbolDetail = symbolDetail;\r\n me.secid = me.getSecid(symbolDetail.symbol);\r\n me.btModal.show();\r\n me.getTimeline();\r\n },\r\n getTimeline(){\r\n const me = this;\r\n const symbolDetail = me.symbolDetail;\r\n gubel.api.tsmixer(async (mixer)=>{\r\n \r\n });\r\n gubel.api.cache('today-timeline-4-'+symbolDetail.symbol, feed=>{\r\n $.get('https:\/\/ifzq.gtimg.cn\/appstock\/app\/kline\/mkline', {\r\n param: symbolDetail.symbol+',m1'\r\n }, res=>{\r\n const data = $.parseJSON(res);\r\n const m1List = data.data[symbolDetail.symbol].m1;\r\n\r\n \/\/ 1. 生成今天日期:20260609\r\n let d = new Date();\r\n let todayStr = d.getFullYear() + String(d.getMonth()+1).padStart(2,0) + String(d.getDate()).padStart(2,0);\r\n \r\n \/\/ 2. 只保留今天\r\n let todayList = m1List.filter(item => item[0].startsWith(todayStr));\r\n\r\n \/\/ 3. 限制条数(可选)\r\n let final = todayList.slice(-240); \/\/ 今天全部\r\n feed(final);\r\n });\r\n }, 5).then(res=>{\r\n const tList = res;\r\n require(['echarts'], function(echarts){\r\n const tChart = echarts.init(document.getElementById('k_chart'));\r\n tChart.clear();\r\n let xData = [];\r\n let priceData = [];\r\n let volData = [];\r\n\r\n tList.forEach(item => {\r\n \/\/ 时间 202606090932 → 09:32\r\n const time = item[0].substr(8,2) + ':' + item[0].substr(10,2);\r\n xData.push(time);\r\n priceData.push(parseFloat(item[4]));\r\n volData.push(parseFloat(item[5]));\r\n });\r\n\r\n const option = {\r\n tooltip: {\r\n trigger: 'axis',\r\n formatter: function(params) {\r\n \/\/ 只显示 时间 + 价格,和截图悬浮框一致\r\n return `${params[0].axisValue}<br\/>${params[0].value}`;\r\n }\r\n },\r\n grid: [\r\n { top: '3%', height: '62%', left: 40, right: 10 },\r\n { top: '70%', height: '22%', left: 40, right: 10 }\r\n ],\r\n xAxis: [\r\n {\r\n type: 'category',\r\n data: xData,\r\n boundaryGap: false,\r\n axisLabel: {\r\n interval: 15, \/\/ 间隔展示,避免文字拥挤,和截图稀疏刻度匹配\r\n fontSize: 12\r\n }\r\n },{\r\n type: 'category',\r\n gridIndex: 1,\r\n data: xData,\r\n axisLabel: {interval: 15,fontSize: 12}\r\n }\r\n ],\r\n yAxis: [{ type: 'value', scale: true },{ type: 'value', gridIndex: 1 }],\r\n series: [\r\n {\r\n type: 'line',\r\n data: priceData,\r\n smooth: false, \/\/ 关闭平滑,变成阶梯直角线,匹配原图\r\n step: 'end', \/\/ 阶梯折线,和截图台阶走势一致\r\n symbol: 'none',\r\n lineStyle: { color: '#1989fa', width: 2 },\r\n areaStyle: {\r\n color: new echarts.graphic.LinearGradient(0,0,0,1,[\r\n {offset:0, color:'rgba(25,137,250,0.25)'},\r\n {offset:1, color:'rgba(25,137,250,0.02)'}\r\n ])\r\n }\r\n },{\r\n type: 'bar',\r\n xAxisIndex: 1,\r\n yAxisIndex: 1,\r\n data: volData,\r\n barWidth: '60%',\r\n itemStyle: { color: '#ee3333' }\r\n }\r\n ]\r\n };\r\n tChart.setOption(option);\r\n setTimeout(() => tChart.resize(), 20);\r\n window.addEventListener('resize', () => tChart.resize());\r\n });\r\n });\r\n },\r\n getMaDay(time, indicator){\r\n \/\/蜡烛图\r\n const me = this;\r\n const symbolDetail = me.symbolDetail;\r\n me.secid = me.getSecid(symbolDetail.symbol);\r\n \r\n let kData = [];\r\n switch(time){\r\n case 'day': \r\n kData = symbolDetail.days;\r\n break;\r\n case 'month':\r\n kData = symbolDetail.months;\r\n break;\r\n case 'year':\r\n kData = symbolDetail.yearData;\r\n break;\r\n default:\r\n kData = symbolDetail.days;\r\n break;\r\n }\r\n \r\n require(['echarts'], function(echarts){\r\n let kChart = echarts.getInstanceByDom(document.getElementById('k_chart'));\r\n kChart.clear();\r\n\r\n \/\/ ======================================\r\n \/\/ 你已经有真实的 kData 了!直接用!\r\n \/\/ ======================================\r\n \/\/ 格式:[日期, 开盘, 收盘, 最高, 最低, 成交量]\r\n const realKData = kData; \r\n\r\n \/\/ ======================================\r\n \/\/ 提取 ECharts K线需要的格式:[开盘, 收盘, 最低, 最高]\r\n \/\/ ======================================\r\n const formatKData = realKData.map(item => [\r\n Number(item[1]), \/\/ 开盘\r\n Number(item[2]), \/\/ 收盘\r\n Number(item[4]), \/\/ 最低\r\n Number(item[3]) \/\/ 最高\r\n ]);\r\n\r\n \/\/ ======================================\r\n \/\/ 提取 X轴日期(直接用你数据里的日期)\r\n \/\/ ======================================\r\n const dates = realKData.map(item => item[0]);\r\n\r\n \/\/ ======================================\r\n \/\/ 计算均线:5 \/ 15 \/ 30(不变)\r\n \/\/ ======================================\r\n function calculateMA(data, dayCount) {\r\n let result = [];\r\n for (let i = 0; i < data.length; i++) {\r\n if (i < dayCount - 1) {\r\n result.push('-');\r\n continue;\r\n }\r\n let sum = 0;\r\n for (let j = 0; j < dayCount; j++) {\r\n sum += data[i - j][1];\r\n }\r\n result.push(+(sum \/ dayCount).toFixed(2));\r\n }\r\n return result;\r\n }\r\n\r\n \/\/ ======================================\r\n \/\/ 新增:计算 BOLL 布林带(标准 20日)\r\n \/\/ ======================================\r\n function calculateBOLL(data, n = 20, p = 2) {\r\n const closes = data.map(item => Number(item[2]));\r\n const mid = []; \/\/ 中轨:MA20\r\n const stdDevList = []; \/\/ 标准差\r\n const upper = []; \/\/ 上轨\r\n const lower = []; \/\/ 下轨\r\n\r\n for (let i = 0; i < closes.length; i++) {\r\n if (i < n - 1) {\r\n mid.push('-');\r\n stdDevList.push('-');\r\n upper.push('-');\r\n lower.push('-');\r\n continue;\r\n }\r\n let sum = 0;\r\n for (let j = 0; j < n; j++) {\r\n sum += closes[i - j];\r\n }\r\n const ma = sum \/ n;\r\n mid.push(ma.toFixed(2));\r\n\r\n let devSum = 0;\r\n for (let j = 0; j < n; j++) {\r\n devSum += Math.pow(closes[i - j] - ma, 2);\r\n }\r\n const stdDev = Math.sqrt(devSum \/ n);\r\n stdDevList.push(stdDev.toFixed(2));\r\n\r\n upper.push((ma + p * stdDev).toFixed(2));\r\n lower.push((ma - p * stdDev).toFixed(2));\r\n }\r\n return { mid, upper, lower };\r\n }\r\n\r\n const ma5 = calculateMA(formatKData, 5);\r\n const ma15 = calculateMA(formatKData, 15);\r\n const ma30 = calculateMA(formatKData, 30);\r\n\r\n let seriesList = [];\r\n let tooltipExtra = function(){};\r\n\r\n if(indicator==='ma'){\r\n \/\/ MA 均线\r\n seriesList = [\r\n {\r\n name: 'K线',\r\n type: 'candlestick',\r\n data: formatKData,\r\n itemStyle: {\r\n color: '#ef4444',\r\n color0: '#22c55e',\r\n borderColor: '#ef4444',\r\n borderColor0: '#22c55e'\r\n }\r\n },{\r\n name: '5均线',\r\n type: 'line',\r\n data: ma5,\r\n smooth: true,\r\n lineStyle: { width: 1.5, color: '#FFB90F' },\r\n symbol: 'none'\r\n },{\r\n name: '15均线',\r\n type: 'line',\r\n data: ma15,\r\n smooth: true,\r\n lineStyle: { width: 1.5, color: '#9333EA' },\r\n symbol: 'none'\r\n },{\r\n name: '30均线',\r\n type: 'line',\r\n data: ma30,\r\n smooth: true,\r\n lineStyle: { width: 1.5, color: '#FF0000' },\r\n symbol: 'none'\r\n }\r\n ];\r\n tooltipExtra = function(index){\r\n const ma5Val = ma5[index];\r\n const ma15Val = ma15[index];\r\n const ma30Val = ma30[index];\r\n return `\r\n <div style=\"margin-top:5px;\"><span style=\"color:#FFB90F;\">●<\/span> 5均线:${ma5Val}<\/div>\r\n <div><span style=\"color:#9333EA;\">●<\/span> 15均线:${ma15Val}<\/div>\r\n <div><span style=\"color:#FF0000;\">●<\/span> 30均线:${ma30Val}<\/div>\r\n `;\r\n };\r\n chartInit();\r\n }else if(indicator==='boll'){\r\n \/\/ BOLL 布林带\r\n const { mid, upper, lower } = calculateBOLL(realKData);\r\n seriesList = [\r\n {\r\n name: 'K线',\r\n type: 'candlestick',\r\n data: formatKData,\r\n itemStyle: {\r\n color: '#ef4444',\r\n color0: '#22c55e',\r\n borderColor: '#ef4444',\r\n borderColor0: '#22c55e'\r\n }\r\n },\r\n { name: '中轨(MA20)', type: 'line', data: mid, lineStyle: { width:1.5, color:'#FFB90F' }, symbol:'none' },\r\n { name: '上轨', type: 'line', data: upper, lineStyle: { width:1.5, color:'#FF00FF' }, symbol:'none' },\r\n { name: '下轨', type: 'line', data: lower, lineStyle: { width:1.5, color:'#00BFFF' }, symbol:'none' }\r\n ];\r\n tooltipExtra = function(index){\r\n const midVal = mid[index];\r\n const upperVal = upper[index];\r\n const lowerVal = lower[index];\r\n return `\r\n <div style=\"margin-top:5px;\"><span style=\"color:#FFB90F;\">●<\/span> 中轨(20):${midVal}<\/div>\r\n <div><span style=\"color:#FF00FF;\">●<\/span> 上轨:${upperVal}<\/div>\r\n <div><span style=\"color:#00BFFF;\">●<\/span> 下轨:${lowerVal}<\/div>\r\n `;\r\n };\r\n chartInit();\r\n }else if(indicator==='ai'){\r\n gubel.api.tsmixer(async (mixer)=>{\r\n const closeList = kData.map(i=>Number(i[2]));\r\n const indexNumber = 3; \/\/默认印象数3个,越大精确度越模糊\r\n const targetList = kData.map(item => {\r\n const open = Number(item[1]); \/\/ 开盘\r\n const close = Number(item[2]); \/\/ 收盘\r\n const high = Number(item[3]); \/\/ 最高\r\n const low = Number(item[4]); \/\/ 最低\r\n \/\/return close;\r\n if (close > open) {\r\n return high;\r\n } else if (close < open) {\r\n return low;\r\n } else {\r\n return close;\r\n }\r\n });\r\n let aiList = [];\r\n await (function () {\r\n const tasks = [];\r\n closeList.forEach((item, index) => {\r\n let indexValue = targetList.slice(Math.max(0, index-indexNumber), index + 1);\r\n const p = new Promise((resolve) => {\r\n mixer.predict(indexValue, (res) => {\r\n aiList[index] = res.next_value;\r\n resolve();\r\n });\r\n });\r\n tasks.push(p);\r\n });\r\n return Promise.all(tasks);\r\n })();\r\n aiList.forEach((item, index)=>{\r\n kData[index].push(item);\r\n });\r\n seriesList = [\r\n {\r\n name: 'K线',\r\n type: 'candlestick',\r\n data: formatKData,\r\n itemStyle: {\r\n color: '#ef4444',\r\n color0: '#22c55e',\r\n borderColor: '#ef4444',\r\n borderColor0: '#22c55e'\r\n }\r\n },{\r\n name: '收盘价',\r\n type: 'line',\r\n data: kData.map(item => Number(item[2])),\r\n smooth: true,\r\n lineStyle: { width: 2, color: '#FF8C00' },\r\n showSymbol: true,\r\n symbol: 'circle',\r\n symbolSize: 6,\r\n itemStyle: {\r\n color: '#FF8C00'\r\n }\r\n },{\r\n name: '止损',\r\n type: 'line',\r\n data: [...kData.map(item => item[6])],\r\n smooth: true,\r\n lineStyle: { width: 2, color: '#003366' }, \/\/ 深蓝色\r\n showSymbol: true,\r\n symbol: 'circle',\r\n symbolSize: 6,\r\n itemStyle: {\r\n color: '#003366' \/\/ 圆点同步深蓝色\r\n }\r\n }\r\n ];\r\n\r\n tooltipExtra = function(index){\r\n const closeVal = kData[index] ? Number(kData[index][2]) : '--';\r\n const aiPredVal = kData[index - 1] ? kData[index - 1][6] : '--';\r\n const diff = aiPredVal !== '--' ? (Number(aiPredVal) - Number(closeVal)).toFixed(2) : '--';\r\n return `\r\n <div style=\"margin-top:5px;\"><span style=\"color:#FF8C00;\">●<\/span> 收盘价:${closeVal}<\/div>\r\n <div><span style=\"color:#003366;\">●<\/span> 止损:${aiPredVal}<\/div>\r\n <div>预测差值:${diff}<\/div>\r\n `;\r\n };\r\n chartInit();\r\n });\r\n }else{\r\n \/\/ 默认 MA\r\n seriesList = [\r\n {\r\n name: 'K线',\r\n type: 'candlestick',\r\n data: formatKData,\r\n itemStyle: {\r\n color: '#ef4444',\r\n color0: '#22c55e',\r\n borderColor: '#ef4444',\r\n borderColor0: '#22c55e'\r\n }\r\n },\r\n { name: '5均线', type: 'line', data: ma5, smooth:true, lineStyle:{width:1.5, color:'#FFB90F'}, symbol:'none' },\r\n { name: '15均线', type: 'line', data: ma15, smooth:true, lineStyle:{width:1.5, color:'#9333EA'}, symbol:'none' },\r\n { name: '30均线', type: 'line', data: ma30, smooth:true, lineStyle:{width:1.5, color:'#FF0000'}, symbol:'none' }\r\n ];\r\n tooltipExtra = function(index){\r\n const ma5Val = ma5[index];\r\n const ma15Val = ma15[index];\r\n const ma30Val = ma30[index];\r\n return `\r\n <div style=\"margin-top:5px;\"><span style=\"color:#FFB90F;\">●<\/span> 5均线:${ma5Val}<\/div>\r\n <div><span style=\"color:#9333EA;\">●<\/span> 15均线:${ma15Val}<\/div>\r\n <div><span style=\"color:#FF0000;\">●<\/span> 30均线:${ma30Val}<\/div>\r\n `;\r\n };\r\n chartInit();\r\n }\r\n\r\n function chartInit(){\r\n const option = {\r\n tooltip: {\r\n trigger: 'axis',\r\n axisPointer: { type: 'cross' },\r\n formatter: function (params) {\r\n const index = params[0].dataIndex;\r\n const item = realKData[index];\r\n const date = item[0];\r\n const open = item[1];\r\n const close = item[2];\r\n const high = item[3];\r\n const low = item[4];\r\n\r\n let html = `<div style=\"font-size:12px;line-height:1.8;\">`;\r\n html += `<div style=\"margin-bottom:5px;\">${date}<\/div>`;\r\n html += `<div><span style=\"color:#ef4444;\">●<\/span> 开盘:${open}<\/div>`;\r\n html += `<div><span style=\"color:#ef4444;\">●<\/span> 收盘:${close}<\/div>`;\r\n html += `<div><span style=\"color:#ef4444;\">●<\/span> 最低:${low}<\/div>`;\r\n html += `<div><span style=\"color:#ef4444;\">●<\/span> 最高:${high}<\/div>`;\r\n html += tooltipExtra(index);\r\n html += `<\/div>`;\r\n return html;\r\n }\r\n },\r\n legend: { show: false },\r\n grid: { left: '5%', right: '5%', top: '5%', bottom: '5%' },\r\n dataZoom: [\r\n { type: 'inside', start: 0, end: 100 },\r\n { show: true, height: 12, bottom: '0%', start: 0, end: 100 }\r\n ],\r\n xAxis: { type: 'category', data: dates },\r\n yAxis: { scale: true },\r\n series: seriesList\r\n };\r\n\r\n kChart.setOption(option);\r\n setTimeout(() => kChart.resize(), 20);\r\n window.addEventListener('resize', () => kChart.resize());\r\n }\r\n });\r\n },\r\n },\r\n watch: {\r\n kChart: {\r\n handler(newVal) {\r\n const me = this;\r\n const { lineType, time, indicator } = newVal;\r\n\r\n \/\/分时线\r\n if(lineType==='time-share'){\r\n me.getTimeline();\r\n \/\/k线\r\n }else if(lineType==='k-share'){\r\n me.getMaDay(time, indicator);\r\n }\r\n },\r\n deep: true\r\n }\r\n },\r\n });\r\n\r\n<\/script>"}],"alias":[],"role_permissions":"article_ai,money","news_tags":[]}