Skip to main content
Glama
Xxx00xxX33

FinanceMCP

by Xxx00xxX33

convertible_bond

Query convertible bond non-market data including issuance details by date range or specific bond information by code.

Instructions

获取可转债非行情数据,支持两种查询方式:1)使用issue类型按时间范围查询可转债发行数据;2)使用info类型按代码查询可转债详细信息

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ts_codeNo可转债代码,如'110001.SH'表示国电转债,'128001.SZ'表示平安转债。配合info类型使用可查询详细信息
data_typeYes数据类型,可选值:issue(可转债发行数据)、info(可转债详细信息,通过代码查询)
start_dateNo起始日期,格式为YYYYMMDD,如'20230101'。用于查询发行数据的公告日期范围
end_dateNo结束日期,格式为YYYYMMDD,如'20230131'。用于查询发行数据的公告日期范围

Implementation Reference

  • Core tool definition including handler (run function), schema (parameters), name, and description. The run method fetches convertible bond data (basic/issue/info) from Tushare API, handles errors, and formats output as formatted text.
    export const convertibleBond = {
      name: "convertible_bond",
      description: "获取可转债非行情数据,支持两种查询方式:1)使用issue类型按时间范围查询可转债发行数据;2)使用info类型按代码查询可转债详细信息",
      parameters: {
        type: "object",
        properties: {
          ts_code: {
            type: "string",
            description: "可转债代码,如'110001.SH'表示国电转债,'128001.SZ'表示平安转债。配合info类型使用可查询详细信息"
          },
          data_type: {
            type: "string",
            description: "数据类型,可选值:issue(可转债发行数据)、info(可转债详细信息,通过代码查询)",
            enum: ["issue", "info"]
          },
          start_date: {
            type: "string",
            description: "起始日期,格式为YYYYMMDD,如'20230101'。用于查询发行数据的公告日期范围"
          },
          end_date: {
            type: "string",
            description: "结束日期,格式为YYYYMMDD,如'20230131'。用于查询发行数据的公告日期范围"
          }
        },
        required: ["data_type"]
      },
      async run(args: { 
        ts_code?: string; 
        data_type: string; 
        start_date?: string; 
        end_date?: string;
      }) {
        try {
          console.log('可转债数据查询参数:', args);
          
          const TUSHARE_API_KEY = TUSHARE_CONFIG.API_TOKEN;
          const TUSHARE_API_URL = TUSHARE_CONFIG.API_URL;
          
          if (!TUSHARE_API_KEY) {
            throw new Error('请配置TUSHARE_TOKEN环境变量');
          }
    
          // 默认日期设置
          const today = new Date();
          const currentYear = today.getFullYear();
          const defaultEndDate = `${currentYear}1231`;
          const defaultStartDate = `${currentYear - 1}0101`;
    
          const results: any[] = [];
    
          // 根据data_type决定要查询的API
          const dataTypes = args.data_type === 'info' 
            ? ['basic', 'issue']  // info类型查询所有可用数据
            : [args.data_type];
    
          for (const dataType of dataTypes) {
            try {
              const result = await fetchConvertibleBondData(
                dataType,
                args.ts_code,
                args.start_date || defaultStartDate,
                args.end_date || defaultEndDate,
                TUSHARE_API_KEY,
                TUSHARE_API_URL
              );
              
              if (result.data && result.data.length > 0) {
                results.push({
                  type: dataType,
                  data: result.data,
                  fields: result.fields
                });
              }
            } catch (error) {
              console.warn(`获取${dataType}数据失败:`, error);
              results.push({
                type: dataType,
                error: error instanceof Error ? error.message : '未知错误'
              });
            }
          }
    
          if (results.length === 0) {
            throw new Error(`未找到相关可转债数据`);
          }
    
          // 格式化输出
          const formattedOutput = formatConvertibleBondData(results, args.ts_code);
          
          return {
            content: [{ type: "text", text: formattedOutput }]
          };
    
        } catch (error) {
          console.error('可转债数据查询错误:', error);
          return {
            content: [{ 
              type: "text", 
              text: `查询可转债数据时发生错误: ${error instanceof Error ? error.message : '未知错误'}` 
            }]
          };
        }
      }
  • Helper function to fetch raw data from Tushare API for specific data types (cb_basic, cb_issue), handling parameters mapping and response parsing.
    async function fetchConvertibleBondData(
      dataType: string,
      tsCode?: string,
      startDate?: string,
      endDate?: string,
      apiKey?: string,
      apiUrl?: string
    ) {
      const apiConfigs: Record<string, any> = {
        basic: {
          api_name: "cb_basic",
          default_fields: "ts_code,bond_short_name,stk_code,stk_short_name,maturity,par_value,issue_price,issue_size,remain_size,value_date,maturity_date,list_date,delist_date,exchange,conv_start_date,conv_end_date,first_conv_price,conv_price,rate_clause,put_clause,force_redeem_clause,resale_clause,cross_default_clause"
        },
        issue: {
          api_name: "cb_issue",
          default_fields: "ts_code,ann_date,res_ann_date,plan_issue_size,issue_size,issue_price,issue_type,issue_cost,onl_code,onl_name,onl_date,onl_size,onl_pch_vol,onl_pch_num,onl_pch_excess,onl_winning_rate,shd_ration_code,shd_ration_name,shd_ration_date,shd_ration_record_date,shd_ration_pay_date,shd_ration_price,shd_ration_ratio,shd_ration_size,shd_ration_vol,shd_ration_num,shd_ration_excess,offl_size,offl_deposit,offl_pch_vol,offl_pch_num,offl_pch_excess,offl_winning_rate,lead_underwriter,lead_underwriter_vol"
        }
      };
    
      const config = apiConfigs[dataType];
      if (!config) {
        throw new Error(`不支持的数据类型: ${dataType}`);
      }
    
      // 构建请求参数
      const params: any = {
        api_name: config.api_name,
        token: apiKey,
        params: {},
        fields: config.default_fields
      };
    
      // 根据Tushare文档严格映射参数
      if (dataType === 'basic') {
        // cb_basic接口参数:ts_code, list_date, exchange
        if (tsCode) params.params.ts_code = tsCode;
        // 对于basic查询,如果提供了start_date,映射到list_date(上市日期)
        if (startDate) params.params.list_date = startDate;
        
      } else if (dataType === 'issue') {
        // cb_issue接口参数:ts_code, ann_date, start_date, end_date
        if (tsCode) params.params.ts_code = tsCode;
        // 对于issue查询,直接使用start_date和end_date作为公告日期范围
        if (startDate) params.params.start_date = startDate;
        if (endDate) params.params.end_date = endDate;
      }
    
      // 设置请求超时
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), TUSHARE_CONFIG.TIMEOUT);
    
      try {
        console.log(`请求Tushare API: ${params.api_name},参数:`, params.params);
        
        // 发送请求
        const response = await fetch(apiUrl!, {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify(params),
          signal: controller.signal
        });
        
        if (!response.ok) {
          throw new Error(`Tushare API请求失败: ${response.status}`);
        }
        
        const data = await response.json();
        
        // 处理响应数据
        if (data.code !== 0) {
          throw new Error(`Tushare API错误: ${data.msg}`);
        }
        
        // 确保data.data和data.data.items存在
        if (!data.data || !data.data.items) {
          throw new Error(`未找到${dataType}数据`);
        }
        
        // 获取字段名
        const fields = data.data.fields;
        
        // 将数据转换为对象数组
        const convertedData = data.data.items.map((item: any) => {
          const result: Record<string, any> = {};
          fields.forEach((field: string, index: number) => {
            result[field] = item[index];
          });
          return result;
        });
        
        return {
          data: convertedData,
          fields: fields
        };
    
      } finally {
        clearTimeout(timeoutId);
      }
    }
  • Helper function to format fetched results into user-friendly markdown text report, with specialized formatters for basic and issue data.
    function formatConvertibleBondData(results: any[], tsCode?: string): string {
      let output = ` 🪙 可转债数据报告${tsCode ? ` - ${tsCode}` : ''}\n\n`;
      output += `📅 查询时间: ${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}\n\n`;
    
      results.forEach((result, index) => {
        if (result.error) {
          output += ` ❌ ${getDataTypeName(result.type)}查询失败\n\n`;
          output += `错误信息: ${result.error}\n\n`;
          return;
        }
    
        const dataTypeName = getDataTypeName(result.type);
        output += ` 📊 ${dataTypeName} (${result.data.length}条记录)\n\n`;
    
        switch (result.type) {
          case 'basic':
            output += formatBasicInfo(result.data);
            break;
          case 'issue':
            output += formatIssueInfo(result.data);
            break;
          default:
            output += formatGenericCBData(result.data, result.fields);
            break;
        }
    
        if (index < results.length - 1) {
          output += "\n---\n\n";
        }
      });
    
      return output;
    }
  • src/index.ts:215-217 (registration)
    Tool registration in listTools handler, exposing name, description, and input schema.
    name: convertibleBond.name,
    description: convertibleBond.description,
    inputSchema: convertibleBond.parameters
  • src/index.ts:335-341 (registration)
    Tool execution handler in callToolRequestSchema switch case, extracting arguments and calling convertibleBond.run.
    case "convertible_bond": {
      const ts_code = request.params.arguments?.ts_code ? String(request.params.arguments.ts_code) : undefined;
      const data_type = String(request.params.arguments?.data_type);
      const start_date = request.params.arguments?.start_date ? String(request.params.arguments.start_date) : undefined;
      const end_date = request.params.arguments?.end_date ? String(request.params.arguments.end_date) : undefined;
      return normalizeResult(await convertibleBond.run({ ts_code, data_type, start_date, 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