compare_strategies
Compare multiple strategies side-by-side by evaluating returns, drawdown, and recent performance to identify the best option.
Instructions
Compare multiple strategies side-by-side — returns, drawdown, and recent performance.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| productIds | Yes | Array of product IDs to compare, e.g. ['PROD-E3X', 'PROD-PCR'] |
Implementation Reference
- src/index.ts:234-276 (handler)The main handler function for compare_strategies. Fetches all products from the API, filters by the provided productIds array (min 2, max 8), and returns a side-by-side comparison with productId, name, market, totalReturn, maxDrawdown, recent1dReturn, and recent30dReturn.
async ({ productIds }) => { const res = (await callAPI("getProducts")) as { code: number; data: Record<string, unknown>[]; }; if (res.code !== 0 || !Array.isArray(res.data)) { return { content: [{ type: "text" as const, text: "Failed to fetch strategies" }], }; } const selected = res.data.filter((p) => productIds.includes(p.productId as string) ); if (selected.length === 0) { return { content: [ { type: "text" as const, text: `None of the specified product IDs were found. Use list_strategies to see available IDs.`, }, ], }; } const comparison = selected.map((p) => ({ productId: p.productId, name: p.name, market: p.market || "—", totalReturn: p.totalReturn ?? p.totalReturn5Y ?? null, maxDrawdown: p.maxDrawdown ?? null, recent1dReturn: p.recent1dReturn ?? null, recent30dReturn: p.recent30dReturn ?? null, })); return { content: [ { type: "text" as const, text: JSON.stringify(comparison, null, 2) }, ], }; } ); - src/index.ts:227-233 (schema)Input schema definition for compare_strategies. Accepts productIds: an array of strings with at least 2 and at most 8 items, each describing a product ID like 'PROD-E3X'.
{ productIds: z .array(z.string()) .min(2) .max(8) .describe("Array of product IDs to compare, e.g. ['PROD-E3X', 'PROD-PCR']"), }, - src/index.ts:224-276 (registration)Registers the compare_strategies tool on the MCP server with its name, description, schema, and handler.
server.tool( "compare_strategies", "Compare multiple strategies side-by-side — returns, drawdown, and recent performance.", { productIds: z .array(z.string()) .min(2) .max(8) .describe("Array of product IDs to compare, e.g. ['PROD-E3X', 'PROD-PCR']"), }, async ({ productIds }) => { const res = (await callAPI("getProducts")) as { code: number; data: Record<string, unknown>[]; }; if (res.code !== 0 || !Array.isArray(res.data)) { return { content: [{ type: "text" as const, text: "Failed to fetch strategies" }], }; } const selected = res.data.filter((p) => productIds.includes(p.productId as string) ); if (selected.length === 0) { return { content: [ { type: "text" as const, text: `None of the specified product IDs were found. Use list_strategies to see available IDs.`, }, ], }; } const comparison = selected.map((p) => ({ productId: p.productId, name: p.name, market: p.market || "—", totalReturn: p.totalReturn ?? p.totalReturn5Y ?? null, maxDrawdown: p.maxDrawdown ?? null, recent1dReturn: p.recent1dReturn ?? null, recent30dReturn: p.recent30dReturn ?? null, })); return { content: [ { type: "text" as const, text: JSON.stringify(comparison, null, 2) }, ], }; } ); - src/index.ts:11-19 (helper)Helper function callAPI used by compare_strategies to fetch product data from the QuantToGo API via POST to 'getProducts'.
async function callAPI(fn: string, body: Record<string, unknown> = {}): Promise<unknown> { const resp = await fetch(`${API_BASE}/${fn}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); if (!resp.ok) throw new Error(`API ${fn} returned ${resp.status}`); return resp.json(); }