Skip to main content
Glama
Xxx00xxX33
by Xxx00xxX33

csi_index_constituents

Retrieve CSI index constituents with weights and financial metrics like PE, PB, dividend yield, and profitability ratios for specified date ranges.

Instructions

获取中证指数公司(CSI)指数(含行业/主题)的区间行情、成分权重与估值/财务摘要(PE TTM、PB、股息率、ROE、ROA、净利率、每股经营现金流、资产负债率、营收同比、资产周转率、毛利率、三费比率、现金分红率)。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
index_codeYes指数代码(仅限CSI,含行业/主题)。请使用 .SH/.SZ 形式且能在 Tushare index_weight 查询到权重的代码,例如中证证券公司 '399975.SZ';也支持宽基 '000300.SH'、'000905.SH',以及 'sh000300'、'sz399006' 形式
start_dateYes开始日期,YYYYMMDD 或 YYYY-MM-DD
end_dateYes结束日期,YYYYMMDD 或 YYYY-MM-DD

Implementation Reference

  • The primary handler function that executes the tool: normalizes index code and dates, fetches index and constituent stock data from Tushare API, computes summaries, retrieves valuations and financial metrics, and formats a comprehensive Markdown table report.
    async run(args: { index_code: string; start_date: string; end_date: string; }) { try { const normIndex = normalizeIndexCode(args.index_code); const start = parseDateString(args.start_date); const end = parseDateString(args.end_date); if (!TUSHARE_CONFIG.API_TOKEN) { throw new Error('请配置TUSHARE_TOKEN环境变量'); } // 指数行情 const indexDaily = await getIndexDaily(normIndex, start, end); const indexSummary = summarizePrices(indexDaily); const indexRet = calcReturn(indexSummary.open_at_start, indexSummary.close_at_end); // 成分权重(以end为基准回退查找) const weights = await getIndexWeights(normIndex, end); if (weights.length === 0) { return { content: [ { type: 'text', text: `# ${normIndex} 指数区间与成分股摘要\n\n❌ 未能获取到指数成分权重(仅支持中证指数公司CSI),请检查指数代码或日期范围。` } ] }; } // 使用全部成分股(按权重降序) const allConstituents = weights; // 并发拉取全部成分股行情 const stockRows = await Promise.all(allConstituents.map(c => getStockDaily(normalizeIndexCode(c.ts_code), start, end).catch(() => []))); const stockSummaries = stockRows.map(rows => summarizePrices(rows)); // 估值:以结束日向前回退查找最近可用 daily_basic(最多回退10日) const { date: basicDate, map: basicMap } = await getNearestDailyBasicMap(end, 10); // 财务指标:为每只股票获取最近披露的 ROE/ROA/净利率/资产周转率/毛利率/三费比率/EPS(按公告日或报告期倒序取最近) const finaSnapshots = await Promise.all( allConstituents.map(c => getFinaIndicatorLatest(normalizeIndexCode(c.ts_code), end).catch(() => null)) ); // 现金分红率:获取最近每股分红,结合 EPS 估算 分红率 = 每股分红 / 每股收益 * 100% const latestDpsList = await Promise.all( allConstituents.map(c => getLatestCashDividendPerShare(normalizeIndexCode(c.ts_code), end).catch(() => null)) ); // 组装输出 const pct = (v: number | null) => v == null ? 'N/A' : (v * 100).toFixed(2) + '%'; const num = (v: number | null) => v == null ? 'N/A' : String(Number(v.toFixed(4))); let out = `# ${normIndex} 指数区间与成分股摘要\n\n` + `仅支持中证指数公司(CSI)指数。查询区间: ${start} - ${end}\n\n` + `## 指数价格摘要\n` + `- 起始开盘: ${num(indexSummary.open_at_start)}\n` + `- 区间最低: ${num(indexSummary.low_min)} (${indexSummary.low_min_date || 'N/A'})\n` + `- 区间最高: ${num(indexSummary.high_max)} (${indexSummary.high_max_date || 'N/A'})\n` + `- 结束收盘: ${num(indexSummary.close_at_end)}\n` + `- 区间涨跌幅: ${pct(indexRet)}\n\n` + `## 成分股列表(按权重降序)\n`; out += `| 代码 | 权重(%) | 起始开盘 | 区间最低 | 区间最高 | 结束收盘 | 区间涨跌幅 | PE(TTM) | PB | 股息率(%) | ROE(%) | ROA(%) | 净利率(%) | 每股经营现金流 | 资产负债率(%) | 营收同比(%) | 资产周转率 | 毛利率(%) | 三费比率(%) | 现金分红率(%) |\n`; out += `|-----|---------|-----------|-----------|-----------|-----------|-----------|---------|----|-----------|--------|--------|-----------|--------------|--------------|-----------|------------|-----------|------------|--------------|\n`; allConstituents.forEach((c, i) => { const s = stockSummaries[i]; const r = calcReturn(s.open_at_start, s.close_at_end); const code = normalizeIndexCode(c.ts_code); const val = basicMap[code] || basicMap[c.ts_code] || null; const fmt = (v: number | null | undefined, digits = 4) => v == null ? 'N/A' : String(Number(v.toFixed(digits))); const f = finaSnapshots[i]; const fmtPct = (v: number | null | undefined, digits = 2) => v == null ? 'N/A' : String(Number(v.toFixed(digits))); const dps = latestDpsList[i]; const payoutPct = (dps != null && f?.eps != null && f.eps !== 0) ? Number(((dps / f.eps) * 100).toFixed(2)) : null; out += `| ${code} | ${num(c.weight)} | ${num(s.open_at_start)} | ${num(s.low_min)} | ${num(s.high_max)} | ${num(s.close_at_end)} | ${pct(r)} | ${fmt(val?.pe_ttm)} | ${fmt(val?.pb)} | ${val?.dividend_yield_pct == null ? 'N/A' : Number(val.dividend_yield_pct.toFixed(2))} | ${fmtPct(f?.roe_pct)} | ${fmtPct(f?.roa_pct)} | ${fmtPct(f?.netprofit_margin_pct)} | ${fmt(f?.ocfps)} | ${fmtPct(f?.debt_to_assets_pct)} | ${fmtPct(f?.revenue_yoy_pct)} | ${fmt(f?.assets_turn, 3)} | ${fmtPct(f?.grossprofit_margin_pct)} | ${fmtPct(f?.three_expense_ratio_pct)} | ${payoutPct == null ? 'N/A' : payoutPct} |\n`; }); // 收集所有成分股代码并生成说明 const stockCodes = allConstituents.map(c => normalizeIndexCode(c.ts_code)); const stockExplanation = await resolveStockCodes(stockCodes); return { content: [ { type: 'text', text: out + stockExplanation } ] }; } catch (error) { return { content: [ { type: 'text', text: `❌ CSI指数成分摘要查询失败: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }
  • JSON Schema defining the input parameters for the tool: index_code (CSI index), start_date, and end_date.
    parameters: { type: 'object', properties: { index_code: { type: 'string', description: "指数代码(仅限CSI,含行业/主题)。请使用 .SH/.SZ 形式且能在 Tushare index_weight 查询到权重的代码,例如中证证券公司 '399975.SZ';也支持宽基 '000300.SH'、'000905.SH',以及 'sh000300'、'sz399006' 形式" }, start_date: { type: 'string', description: '开始日期,YYYYMMDD 或 YYYY-MM-DD' }, end_date: { type: 'string', description: '结束日期,YYYYMMDD 或 YYYY-MM-DD' } }, required: ['index_code', 'start_date', 'end_date'] },
  • src/index.ts:388-392 (registration)
    Tool dispatch/registration in the MCP stdio server's CallToolRequest handler switch statement.
    case "csi_index_constituents": { const index_code = String(request.params.arguments?.index_code); const start_date = String(request.params.arguments?.start_date); const end_date = String(request.params.arguments?.end_date); return normalizeResult(await csiIndexConstituents.run({ index_code, start_date, end_date }));
  • src/index.ts:246-248 (registration)
    Tool registration in the ListToolsRequest handler, exposing name, description, and inputSchema.
    name: csiIndexConstituents.name, description: csiIndexConstituents.description, inputSchema: csiIndexConstituents.parameters
  • Tool dispatch/registration in the HTTP MCP server's tools/call handler switch statement.
    case 'csi_index_constituents': return await csiIndexConstituents.run({ index_code: String(args?.index_code), start_date: String(args?.start_date), end_date: String(args?.end_date), });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Xxx00xxX33/FinanceMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server