数据源修改

This commit is contained in:
cheney
2026-08-06 15:24:55 +08:00
parent b10b1c44db
commit ec15f40323
24 changed files with 2289 additions and 131 deletions
+95 -2
View File
@@ -50,6 +50,59 @@ const INDICATORS = [
sheets.find((s) => s.items?.[0]?.[0]?.includes('GDP') && s.items[0][0].includes('同比'))
|| sheets[0],
},
{
// 国债收益率: MCP 返回日频, 用月末降采样成月频点
name: 'china-bond-10y',
groupName: 'china-macro',
title: '中国国债 10 年期收益率',
unit: '%',
frequency: 'month',
tool: 'mx_macro_data',
query: '查询中国10年期国债到期收益率 2024年至今 每日数据',
pickSheet: (sheets) =>
sheets.find((s) => s.items?.some?.((row) => String(row[0] || '').includes('国债到期收益率:10年')))
|| sheets[0],
parseSheet: (sheet) => monthEndSample(sheet, '国债到期收益率:10年'),
},
{
name: 'china-bond-1y',
groupName: 'china-macro',
title: '中国国债 1 年期收益率',
unit: '%',
frequency: 'month',
tool: 'mx_macro_data',
query: '查询中国1年期国债到期收益率 2024年至今 每日数据',
pickSheet: (sheets) =>
sheets.find((s) => s.items?.some?.((row) => String(row[0] || '').includes('国债到期收益率:1年')))
|| sheets[0],
parseSheet: (sheet) => monthEndSample(sheet, '国债到期收益率:1年'),
},
{
name: 'china-lpr-1y',
groupName: 'china-macro',
title: '中国 LPR 1 年期',
unit: '%',
frequency: 'month',
tool: 'mx_macro_data',
query: '查询中国LPR 1年期贷款市场报价利率 2024年至今 月度数据,每一个月的数值',
pickSheet: (sheets) =>
sheets.find((s) => s.sheetName?.includes('宏观数据(月)'))
|| sheets[0],
parseSheet: (sheet) => pickRowByKeyword(sheet, '(LPR):1年'),
},
{
name: 'china-lpr-5y',
groupName: 'china-macro',
title: '中国 LPR 5 年期',
unit: '%',
frequency: 'month',
tool: 'mx_macro_data',
query: '查询中国LPR 5年期以上贷款市场报价利率 2024年至今 月度数据,每一个月的数值',
pickSheet: (sheets) =>
sheets.find((s) => s.sheetName?.includes('宏观数据(月)'))
|| sheets[0],
parseSheet: (sheet) => pickRowByKeyword(sheet, '(LPR):5年'),
},
]
export const META = {
@@ -139,6 +192,44 @@ function defaultParseSheet(sheet) {
return out.reverse() // 从老到新
}
// 宽表 → 长表, 指定 item 行 (按指标全名前缀匹配), 日频列降采样为月末值
// 例: columns=["指标","来源","2026-08-05","2026-08-04",...] → [{period:"2024-01",value},...]
function monthEndSample(sheet, keyword) {
if (!sheet || !sheet.columns || !sheet.items) return []
const row = sheet.items.find((r) => String(r[0] || '').includes(keyword))
if (!row) return []
const cols = sheet.columns
const dates = cols.slice(2) // 新 → 老
const values = row.slice(2)
const out = []
const seen = new Set()
for (let i = 0; i < dates.length; i++) {
const v = parseFloat(values[i])
const m = String(dates[i] || '').slice(0, 7) // "2024-01-02" → "2024-01"
if (!/^\d{4}-\d{2}$/.test(m) || Number.isNaN(v)) continue
if (seen.has(m)) continue // 列是降序, 第一次遇到的即当月最后一个交易日
seen.add(m)
out.push({ period: m, value: v })
}
return out.reverse() // 从老到新
}
// 宽表 → 长表, 指定 item 行 (按指标全名前缀匹配), 保留原频率 (月/季/年)
function pickRowByKeyword(sheet, keyword) {
if (!sheet || !sheet.columns || !sheet.items) return []
const row = sheet.items.find((r) => String(r[0] || '').includes(keyword))
if (!row) return []
const cols = sheet.columns
const dates = cols.slice(2)
const values = row.slice(2)
const out = []
for (let i = 0; i < dates.length; i++) {
const v = parseFloat(values[i])
if (!Number.isNaN(v)) out.push({ period: String(dates[i]), value: v })
}
return out.reverse() // 从老到新
}
// ====== fetcher 入口 ======
export async function listAvailableTools() {
@@ -156,6 +247,7 @@ export async function fetchAll(opts = {}) {
throw new Error('eastmoney-mcp: INDICATORS 数组为空, 加新指标见文件顶部注释')
}
const skip = opts.skipNames || new Set()
const force = opts.forceNames || new Set()
const only = opts.onlyNames || null
const key = process.env.EM_API_KEY
@@ -165,7 +257,7 @@ export async function fetchAll(opts = {}) {
const results = []
for (const cfg of INDICATORS) {
if (skip.has(cfg.name)) {
if (skip.has(cfg.name) && !force.has(cfg.name)) {
console.log(`[MCP] ${cfg.name} 跳过 (DB 已存在)`)
continue
}
@@ -199,7 +291,7 @@ export async function fetchAll(opts = {}) {
}
}
// 全部被 DB 优先跳过时, 返回显式标记而不是空数组 (避免被误判为失败)
if (results.length === 0 && INDICATORS.every((cfg) => skip.has(cfg.name))) {
if (results.length === 0 && INDICATORS.every((cfg) => skip.has(cfg.name) && !force.has(cfg.name))) {
return { skipped: true, reason: 'DB 已存在全部指标' }
}
return results
@@ -208,3 +300,4 @@ export async function fetchAll(opts = {}) {