/** * 探针脚本:验证「建行定投评估」所需数据源 * 目标: * - 沪深300 / 中证500:PE-TTM + 近10年PE历史(算分位) * - 标普500 / 纳指100:实时 PE-TTM(尽力找10年历史) * 用法:node dev_test_scripts/debug/debug_dip_eval_sources.js */ const axios = require('axios') const UA = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Referer': 'https://quote.eastmoney.com/' } const cut = (s, n = 500) => String(s == null ? '' : s).replace(/\s+/g, ' ').slice(0, n) // ---------- 1. 东方财富数据中心「估值分析」(A股指数每日 PE_TTM 历史) ---------- const probeEmValuation = async (code, pageSize = 3) => { const url = `https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPT_VALUEANALYSIS_DET&columns=ALL&filter=(SECURITY_CODE%3D%22${code}%22)&pageNumber=1&pageSize=${pageSize}&sortTypes=-1&sortColumns=TRADE_DATE&source=WEB&client=WEB` try { const res = await axios.get(url, { timeout: 10000, headers: UA, validateStatus: () => true }) const rows = res.data && res.data.result && res.data.result.data if (!Array.isArray(rows) || !rows.length) return console.log(` [东财估值分析 ${code}] 无数据 status=${res.status} body=${cut(JSON.stringify(res.data), 300)}`) const r = rows[0] console.log(` [东财估值分析 ${code}] OK 最新=${r.TRADE_DATE} PE_TTM=${r.PE_TTM} PE静态=${r.PE_LAR} PE动=${r.PE_TTM_RATIO || r.DYNAMIC_PE} 字段=${Object.keys(r).join(',')}`) } catch (e) { console.log(` [东财估值分析 ${code}] 异常: ${e.message}`) } } // ---------- 2. 东方财富 push2 实时字段(f162/f163/f164/f167) ---------- const probePush2 = async (secid) => { const url = `https://push2.eastmoney.com/api/qt/stock/get?secid=${secid}&fields=f43,f57,f58,f162,f163,f164,f167&invt=2&fltt=2` try { const res = await axios.get(url, { timeout: 10000, headers: UA, validateStatus: () => true }) const d = res.data && res.data.data if (!d) return console.log(` [push2 ${secid}] 无数据 body=${cut(JSON.stringify(res.data), 300)}`) console.log(` [push2 ${secid}] OK 名称=${d.f58} 点位=${d.f43} f162=${d.f162} f163=${d.f163} f164=${d.f164} f167=${d.f167}`) } catch (e) { console.log(` [push2 ${secid}] 异常: ${e.message}`) } } // ---------- 3. 腾讯美股指数 ---------- const probeTencent = async (symbols) => { const iconv = require('iconv-lite') const url = `http://qt.gtimg.cn/q=${symbols.join(',')}` try { const res = await axios.get(url, { timeout: 10000, responseType: 'arraybuffer', validateStatus: () => true }) const text = iconv.decode(Buffer.from(res.data), 'gb18030') for (const line of String(text).split(/;\s*/).filter(Boolean)) { console.log(` [腾讯] ${cut(line, 600)}`) } } catch (e) { console.log(` [腾讯 ${symbols}] 异常: ${e.message}`) } } // ---------- 4. 新浪美股指数 ---------- const probeSina = async (symbols) => { const iconv = require('iconv-lite') const url = `https://hq.sinajs.cn/list=${symbols.join(',')}` try { const res = await axios.get(url, { timeout: 10000, responseType: 'arraybuffer', headers: { 'User-Agent': 'Mozilla/5.0', 'Referer': 'https://finance.sina.com.cn' }, validateStatus: () => true }) const text = iconv.decode(Buffer.from(res.data), 'gb18030') for (const line of String(text).split(/\r?\n/).filter(Boolean)) { console.log(` [新浪] ${cut(line, 600)}`) } } catch (e) { console.log(` [新浪 ${symbols}] 异常: ${e.message}`) } } // ---------- 5. multpl.com 标普500 PE(当前 + 月度历史) ---------- const probeMultpl = async () => { try { const res = await axios.get('https://www.multpl.com/s-p-500-pe-ratio', { timeout: 15000, headers: { 'User-Agent': UA['User-Agent'] }, validateStatus: () => true }) const m = String(res.data).match(/Current S&P 500 PE Ratio[\s\S]{0,400}?([0-9]+\.[0-9]+)/i) console.log(` [multpl 当前PE] status=${res.status} 匹配=${m ? m[1] : '未匹配'} 片段=${cut(res.data.match(/Current S&P 500 PE Ratio[\s\S]{0,200}/i), 260)}`) } catch (e) { console.log(` [multpl 当前PE] 异常: ${e.message}`) } try { const res = await axios.get('https://www.multpl.com/s-p-500-pe-ratio/table/by-month', { timeout: 15000, headers: { 'User-Agent': UA['User-Agent'] }, validateStatus: () => true }) const html = String(res.data) const rows = html.match(/