Skip to main content
Glama
Xxx00xxX33

FinanceMCP

by Xxx00xxX33

block_trade

Retrieve detailed block trade data including transaction prices, volumes, and counterparty information for stocks. Specify date ranges and stock codes to analyze large-volume institutional transactions.

Instructions

获取大宗交易数据,包括成交价格、成交量、买卖双方营业部等详细信息

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeNo股票代码(可选),如'000001.SZ'表示平安银行。不填写则查询全市场大宗交易
start_dateYes起始日期,格式为YYYYMMDD,如'20230101'
end_dateYes结束日期,格式为YYYYMMDD,如'20231231'

Implementation Reference

  • Primary handler for the 'block_trade' tool: defines name, description, input schema, and the async run() function that handles API requests to Tushare's block_trade endpoint, processes response data, and formats output.
    export const blockTrade = {
        name: "block_trade",
        description: "获取大宗交易数据,包括成交价格、成交量、买卖双方营业部等详细信息",
        parameters: {
            type: "object",
            properties: {
                code: {
                    type: "string",
                    description: "股票代码(可选),如'000001.SZ'表示平安银行。不填写则查询全市场大宗交易"
                },
                start_date: {
                    type: "string",
                    description: "起始日期,格式为YYYYMMDD,如'20230101'"
                },
                end_date: {
                    type: "string",
                    description: "结束日期,格式为YYYYMMDD,如'20231231'"
                }
            },
            required: ["start_date", "end_date"]
        },
        async run(args) {
            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 requestParams = {
                    start_date: args.start_date,
                    end_date: args.end_date
                };
                // 只有提供了code时才添加ts_code参数
                if (args.code) {
                    requestParams.ts_code = args.code;
                }
                const params = {
                    api_name: "block_trade",
                    token: TUSHARE_API_KEY,
                    params: requestParams
                    // 不设置fields参数,返回所有字段
                };
                console.log(`请求大宗交易数据,API: block_trade,参数:`, params.params);
                // 设置请求超时
                const controller = new AbortController();
                const timeoutId = setTimeout(() => controller.abort(), TUSHARE_CONFIG.TIMEOUT);
                try {
                    const response = await fetch(TUSHARE_API_URL, {
                        method: "POST",
                        headers: {
                            "Content-Type": "application/json"
                        },
                        body: JSON.stringify(params),
                        signal: controller.signal
                    });
                    clearTimeout(timeoutId);
                    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}`);
                    }
                    if (!data.data || !data.data.items || data.data.items.length === 0) {
                        return {
                            content: [{
                                    type: "text",
                                    text: `# 📊 ${args.code || '全市场'} 大宗交易数据\n\n查询期间: ${args.start_date} - ${args.end_date}\n\n❌ 暂无大宗交易记录\n\n在指定时间范围内,${args.code ? '该股票' : '全市场'}没有大宗交易数据。`
                                }]
                        };
                    }
                    // 获取字段名
                    const fieldsArray = data.data.fields;
                    // 将数据转换为对象数组
                    const tradeData = data.data.items.map((item) => {
                        const result = {};
                        fieldsArray.forEach((field, index) => {
                            result[field] = item[index];
                        });
                        return result;
                    });
                    console.log(`成功获取到${tradeData.length}条大宗交易记录`);
                    // 格式化输出
                    const formattedOutput = await formatBlockTradeData(tradeData, args.code || '全市场', args.start_date, args.end_date);
                    return {
                        content: [{ type: "text", text: formattedOutput }]
                    };
                }
                catch (error) {
                    clearTimeout(timeoutId);
                    throw error;
                }
            }
            catch (error) {
                console.error('大宗交易查询错误:', error);
                return {
                    content: [{
                            type: "text",
                            text: `查询大宗交易数据时发生错误: ${error instanceof Error ? error.message : '未知错误'}`
                        }]
                };
            }
        }
    };
  • Input schema (parameters) for the block_trade tool, defining optional code and required date range.
    type: "object",
    properties: {
        code: {
            type: "string",
            description: "股票代码(可选),如'000001.SZ'表示平安银行。不填写则查询全市场大宗交易"
        },
        start_date: {
            type: "string",
            description: "起始日期,格式为YYYYMMDD,如'20230101'"
        },
        end_date: {
            type: "string",
            description: "结束日期,格式为YYYYMMDD,如'20231231'"
        }
    },
    required: ["start_date", "end_date"]
  • Registration of block_trade tool in the toolList array used for tools/list endpoint in HTTP server.
    { name: blockTrade.name, description: blockTrade.description, inputSchema: blockTrade.parameters },
  • Dispatcher case in tools/call switch statement that invokes the blockTrade.run() handler.
    case 'block_trade':
        return await blockTrade.run({
            code: args?.code ? String(args.code) : undefined,
            start_date: String(args?.start_date),
            end_date: String(args?.end_date),
        });
  • Helper function to format raw block trade data into comprehensive Markdown report with summaries, tables, and rankings.
    async function formatBlockTradeData(data, code, startDate, endDate) {
        let output = `# 📊 ${code} 大宗交易数据\n\n`;
        output += `查询期间: ${startDate} - ${endDate}\n`;
        output += `交易记录: 共 ${data.length} 条\n\n`;
        // 统计信息
        const totalVolume = data.reduce((sum, item) => sum + (parseFloat(item.vol) || 0), 0);
        const totalAmount = data.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
        const avgPrice = totalAmount > 0 && totalVolume > 0 ? totalAmount / totalVolume : 0;
        output += `## 📈 统计摘要\n\n`;
        output += `- 累计成交量: ${formatNumber(totalVolume)} 万股\n`;
        output += `- 累计成交金额: ${formatNumber(totalAmount)} 万元\n`;
        output += `- 平均成交价: ${avgPrice > 0 ? avgPrice.toFixed(2) : 'N/A'} 元/股\n`;
        output += `- 交易天数: ${new Set(data.map(item => item.trade_date)).size} 天\n`;
        output += `- 涉及股票: ${new Set(data.map(item => item.ts_code)).size} 只\n\n`;
        // 按交易日期分组
        const groupedData = {};
        for (const item of data) {
            const date = item.trade_date || 'unknown';
            if (!groupedData[date]) {
                groupedData[date] = [];
            }
            groupedData[date].push(item);
        }
        // 按日期排序(最新的在前)
        const sortedDates = Object.keys(groupedData).sort((a, b) => b.localeCompare(a));
        output += `## 📋 交易明细\n\n`;
        for (const date of sortedDates) {
            const dayTrades = groupedData[date];
            const dayVolume = dayTrades.reduce((sum, item) => sum + (parseFloat(item.vol) || 0), 0);
            const dayAmount = dayTrades.reduce((sum, item) => sum + (parseFloat(item.amount) || 0), 0);
            output += `### 📅 ${date}\n\n`;
            output += `当日汇总: ${dayTrades.length} 笔交易,成交量 ${formatNumber(dayVolume)} 万股,成交额 ${formatNumber(dayAmount)} 万元\n\n`;
            // 创建表格
            output += `| 股票代码 | 成交价(元) | 成交量(万股) | 成交金额(万元) | 买方营业部 | 卖方营业部 |\n`;
            output += `|---------|-----------|------------|-------------|-----------|----------|\n`;
            for (const trade of dayTrades) {
                const tsCode = trade.ts_code || 'N/A';
                const price = trade.price ? parseFloat(trade.price).toFixed(2) : 'N/A';
                const volume = trade.vol ? formatNumber(trade.vol) : 'N/A';
                const amount = trade.amount ? formatNumber(trade.amount) : 'N/A';
                const buyer = trade.buyer || 'N/A';
                const seller = trade.seller || 'N/A';
                // 截断过长的营业部名称
                const buyerShort = buyer.length > 20 ? buyer.substring(0, 17) + '...' : buyer;
                const sellerShort = seller.length > 20 ? seller.substring(0, 17) + '...' : seller;
                output += `| ${tsCode} | ${price} | ${volume} | ${amount} | ${buyerShort} | ${sellerShort} |\n`;
            }
            output += '\n';
        }
        // 股票活跃度统计(仅在查询全市场时显示)
        if (!code || code === '全市场') {
            const stockCount = {};
            const stockVolume = {};
            for (const trade of data) {
                if (trade.ts_code) {
                    stockCount[trade.ts_code] = (stockCount[trade.ts_code] || 0) + 1;
                    stockVolume[trade.ts_code] = (stockVolume[trade.ts_code] || 0) + (parseFloat(trade.vol) || 0);
                }
            }
            // 按交易次数排序的TOP5股票
            const topStocksByCount = Object.entries(stockCount)
                .sort(([, a], [, b]) => b - a)
                .slice(0, 5);
            if (topStocksByCount.length > 0) {
                output += `## 📈 最活跃股票统计\n\n`;
                output += `### 🔥 大宗交易次数 TOP5\n\n`;
                output += `| 排名 | 股票代码 | 交易次数 | 累计成交量(万股) |\n`;
                output += `|-----|---------|--------|--------------|\n`;
                topStocksByCount.forEach(([tsCode, count], index) => {
                    const volume = stockVolume[tsCode] || 0;
                    output += `| ${index + 1} | ${tsCode} | ${count} 次 | ${formatNumber(volume)} |\n`;
                });
                output += '\n';
            }
        }
        // 买卖营业部统计
        const buyerCount = {};
        const sellerCount = {};
        for (const trade of data) {
            if (trade.buyer && trade.buyer !== 'N/A') {
                buyerCount[trade.buyer] = (buyerCount[trade.buyer] || 0) + 1;
            }
            if (trade.seller && trade.seller !== 'N/A') {
                sellerCount[trade.seller] = (sellerCount[trade.seller] || 0) + 1;
            }
        }
        // 买方营业部TOP5
        const topBuyers = Object.entries(buyerCount)
            .sort(([, a], [, b]) => b - a)
            .slice(0, 5);
        if (topBuyers.length > 0) {
            output += `## 🏆 活跃营业部统计\n\n`;
            output += `### 🟢 买方营业部 TOP5\n\n`;
            output += `| 排名 | 营业部名称 | 交易次数 |\n`;
            output += `|-----|-----------|--------|\n`;
            topBuyers.forEach(([name, count], index) => {
                const nameShort = name.length > 30 ? name.substring(0, 27) + '...' : name;
                output += `| ${index + 1} | ${nameShort} | ${count} 次 |\n`;
            });
            output += '\n';
        }
        // 卖方营业部TOP5
        const topSellers = Object.entries(sellerCount)
            .sort(([, a], [, b]) => b - a)
            .slice(0, 5);
        if (topSellers.length > 0) {
            output += `### 🔴 卖方营业部 TOP5\n\n`;
            output += `| 排名 | 营业部名称 | 交易次数 |\n`;
            output += `|-----|-----------|--------|\n`;
            topSellers.forEach(([name, count], index) => {
                const nameShort = name.length > 30 ? name.substring(0, 27) + '...' : name;
                output += `| ${index + 1} | ${nameShort} | ${count} 次 |\n`;
            });
            output += '\n';
        }
        output += `---\n\n*数据来源: Tushare Pro*`;
        // 收集所有股票代码并生成说明
        const stockCodes = [];
        for (const trade of data) {
            if (trade.ts_code) {
                stockCodes.push(String(trade.ts_code));
            }
        }
        const stockExplanation = await resolveStockCodes(stockCodes);
        output += stockExplanation;
        return output;
    }

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