generate_candlestick_chart
Generate candlestick charts for financial data like stock or cryptocurrency prices using OHLC (Open-High-Low-Close) data. Customize chart dimensions, themes, and include volume data for detailed analysis.
Instructions
Generate a candlestick chart for financial data visualization, such as, stock prices, cryptocurrency prices, or other OHLC (Open-High-Low-Close) data.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Data for candlestick chart, such as, [{ date: '2023-01-01', open: 100, high: 110, low: 95, close: 105, volume: 10000 }]. | |
| height | No | Set the height of the chart, default is 600px. | |
| outputType | No | The output type of the diagram. Can be 'png', 'svg' or 'option'. Default is 'png', 'png' will return the rendered PNG image, 'svg' will return the rendered SVG string, and 'option' will return the valid ECharts option. | png |
| showVolume | No | Whether to show volume chart below candlestick. Default is false. | |
| theme | No | Set the theme for the chart, optional, default is 'default'. | default |
| title | No | Set the title of the chart. | |
| width | No | Set the width of the chart, default is 800px. |
Implementation Reference
- src/tools/candlestick.ts:46-235 (handler)The core handler function that processes OHLC(V) data, constructs the ECharts candlestick chart option (with optional volume bars), configures layout and styling, and generates the output image.run: async (params: { data: Array<{ date: string; open: number; high: number; low: number; close: number; volume?: number; }>; height: number; showVolume?: boolean; theme?: "default" | "dark"; title?: string; width: number; outputType?: "png" | "svg" | "option"; }) => { const { data, height, showVolume = false, theme, title, width, outputType, } = params; // Sort data by date const sortedData = [...data].sort( (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime(), ); // Extract dates and OHLC data const dates = sortedData.map((item) => item.date); const ohlcData = sortedData.map((item) => [ item.open, item.close, item.low, item.high, ]); const volumeData = sortedData.map((item) => item.volume || 0); const series: Array<SeriesOption> = [ { name: "Candlestick", type: "candlestick", data: ohlcData, itemStyle: { color: "#ef232a", color0: "#14b143", borderColor: "#ef232a", borderColor0: "#14b143", }, emphasis: { itemStyle: { color: "#ef232a", color0: "#14b143", borderColor: "#ef232a", borderColor0: "#14b143", }, }, }, ]; // Add volume series if requested if (showVolume && volumeData.some((v) => v > 0)) { series.push({ name: "Volume", type: "bar", xAxisIndex: 1, yAxisIndex: 1, data: volumeData, barWidth: "60%", itemStyle: { color: (params: { dataIndex: number }) => { const dataIndex = params.dataIndex; return sortedData[dataIndex].close >= sortedData[dataIndex].open ? "#ef232a" : "#14b143"; }, }, }); } const echartsOption: EChartsOption = { animation: false, legend: { bottom: 10, left: "center", data: showVolume ? ["Candlestick", "Volume"] : ["Candlestick"], }, tooltip: { trigger: "axis", axisPointer: { type: "cross", }, borderWidth: 1, borderColor: "#ccc", padding: 10, textStyle: { color: "#000", }, }, xAxis: [ { type: "category", data: dates, boundaryGap: true, axisLine: { onZero: false }, splitLine: { show: false }, min: -0.2, max: dates.length - 0.8, }, ...(showVolume ? [ { type: "category" as const, gridIndex: 1, data: dates, boundaryGap: true, axisLine: { onZero: false }, axisTick: { show: false }, splitLine: { show: false }, axisLabel: { show: false }, min: -0.2, max: dates.length - 0.8, }, ] : []), ], yAxis: [ { scale: true, splitArea: { show: true, }, }, ...(showVolume ? [ { scale: true, gridIndex: 1, splitNumber: 2, axisLabel: { show: false }, axisLine: { show: false }, axisTick: { show: false }, splitLine: { show: false }, min: 0, }, ] : []), ], grid: showVolume ? [ { left: "12%", right: "10%", top: "15%", height: "50%", }, { left: "12%", right: "10%", top: "75%", height: "15%", }, ] : [ { left: "12%", right: "10%", top: "15%", bottom: "15%", }, ], series, title: { left: "center", text: title, }, }; return await generateChartImage( echartsOption, width, height, theme, outputType, "generate_candlestick_chart", ); },
- src/tools/candlestick.ts:13-45 (schema)Zod schemas defining the structure of individual candlestick data points and the overall input parameters for the tool, including data array, dimensions, volume toggle, theme, title, and output type.const data = z.object({ date: z.string().describe("Date string, such as '2023-01-01'."), open: z.number().describe("Opening price."), high: z.number().describe("Highest price."), low: z.number().describe("Lowest price."), close: z.number().describe("Closing price."), volume: z.number().optional().describe("Trading volume (optional)."), }); export const generateCandlestickChartTool = { name: "generate_candlestick_chart", description: "Generate a candlestick chart for financial data visualization, such as, stock prices, cryptocurrency prices, or other OHLC (Open-High-Low-Close) data.", inputSchema: z.object({ data: z .array(data) .describe( "Data for candlestick chart, such as, [{ date: '2023-01-01', open: 100, high: 110, low: 95, close: 105, volume: 10000 }].", ) .nonempty({ message: "Candlestick chart data cannot be empty." }), height: HeightSchema, showVolume: z .boolean() .optional() .default(false) .describe( "Whether to show volume chart below candlestick. Default is false.", ), theme: ThemeSchema, title: TitleSchema, width: WidthSchema, outputType: OutputTypeSchema, }),
- src/tools/index.ts:3-37 (registration)Imports the tool definition and registers it by including 'generateCandlestickChartTool' in the exported 'tools' array (at line 32), which is used to expose all MCP tools.import { generateCandlestickChartTool } from "./candlestick"; import { generateEChartsTool } from "./echarts"; import { generateFunnelChartTool } from "./funnel"; import { generateGaugeChartTool } from "./gauge"; import { generateGraphChartTool } from "./graph"; import { generateHeatmapChartTool } from "./heatmap"; import { generateLineChartTool } from "./line"; import { generateParallelChartTool } from "./parallel"; import { generatePieChartTool } from "./pie"; import { generateRadarChartTool } from "./radar"; import { generateSankeyChartTool } from "./sankey"; import { generateScatterChartTool } from "./scatter"; import { generateSunburstChartTool } from "./sunburst"; import { generateTreeChartTool } from "./tree"; import { generateTreemapChartTool } from "./treemap"; export const tools = [ generateEChartsTool, generateLineChartTool, generateBarChartTool, generatePieChartTool, generateRadarChartTool, generateScatterChartTool, generateSankeyChartTool, generateFunnelChartTool, generateGaugeChartTool, generateTreemapChartTool, generateSunburstChartTool, generateHeatmapChartTool, generateCandlestickChartTool, generateBoxplotChartTool, generateGraphChartTool, generateParallelChartTool, generateTreeChartTool, ];
- src/tools/index.ts:39-58 (registration)Re-exports the individual tool for direct import and use.// Re-export individual tools for convenient use in tests and other places export { generateEChartsTool, generateLineChartTool, generateBarChartTool, generatePieChartTool, generateRadarChartTool, generateScatterChartTool, generateSankeyChartTool, generateFunnelChartTool, generateGaugeChartTool, generateTreemapChartTool, generateSunburstChartTool, generateHeatmapChartTool, generateCandlestickChartTool, generateBoxplotChartTool, generateGraphChartTool, generateParallelChartTool, generateTreeChartTool, };