Skip to main content
Glama

get_strategy_performance

Retrieve detailed performance metrics for a trading strategy, including returns, drawdown, Sharpe ratio, win rate, and daily NAV history for charting.

Instructions

Get detailed performance for a specific strategy — returns, drawdown, Sharpe, win rate, and daily NAV history for charting. Requires API key (get one free via register_trial).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
apiKeyYesYour API key from register_trial (starts with 'qtg_')
productIdYesStrategy product ID, e.g. 'PROD-E3X'
includeChartNoInclude daily NAV data points for charting

Implementation Reference

  • src/index.ts:89-164 (registration)
    The 'get_strategy_performance' tool is registered via server.tool() inside registerTools(). It defines the schema (apiKey, productId, includeChart) and the handler function.
    server.tool(
      "get_strategy_performance",
      "Get detailed performance for a specific strategy — returns, drawdown, Sharpe, win rate, and daily NAV history for charting. Requires API key (get one free via register_trial).",
      {
        apiKey: z.string().describe("Your API key from register_trial (starts with 'qtg_')"),
        productId: z.string().describe("Strategy product ID, e.g. 'PROD-E3X'"),
        includeChart: z
          .boolean()
          .optional()
          .default(true)
          .describe("Include daily NAV data points for charting"),
      },
      async ({ apiKey, productId, includeChart }) => {
        const auth = await validateApiKey(apiKey);
        if (!auth.valid) {
          return { content: [{ type: "text" as const, text: auth.message }] };
        }
    
        const [detailRes, chartRes] = await Promise.all([
          callAPI("getProductDetail", { productId }) as Promise<{
            code: number;
            data: Record<string, unknown>;
          }>,
          includeChart
            ? (callAPI("getProductChart", { productId }) as Promise<{
                code: number;
                data: Record<string, unknown>;
              }>)
            : Promise.resolve(null),
        ]);
    
        if (detailRes.code !== 0 || !detailRes.data) {
          return {
            content: [
              {
                type: "text" as const,
                text: `Strategy '${productId}' not found`,
              },
            ],
          };
        }
    
        const d = detailRes.data;
        const result: Record<string, unknown> = {
          productId: d.productId,
          name: d.name,
          market: d.market,
          description: d.description || d.shortDescription,
          totalReturn: d.totalReturn ?? d.totalReturn5Y,
          metricsYearLabel: d.metricsYearLabel,
          maxDrawdown: d.maxDrawdown,
          recent1dReturn: d.recent1dReturn,
          recent30dReturn: d.recent30dReturn,
          tradeCount: d.tradeCount ?? d.tradeCount5Y,
          status: d.status,
        };
    
        if (chartRes?.data) {
          const cd = chartRes.data;
          result.chart = {
            totalPoints: cd.totalPoints,
            lastUpdated: cd.lastUpdated,
            dataPoints: cd.dataPoints, // [{d, nav}, ...]
          };
        }
    
        return {
          content: [
            {
              type: "text" as const,
              text: JSON.stringify(result, null, 2),
            },
          ],
        };
      }
    );
  • Input schema for get_strategy_performance: apiKey (string), productId (string), includeChart (optional boolean, defaults to true).
    {
      apiKey: z.string().describe("Your API key from register_trial (starts with 'qtg_')"),
      productId: z.string().describe("Strategy product ID, e.g. 'PROD-E3X'"),
      includeChart: z
        .boolean()
        .optional()
        .default(true)
        .describe("Include daily NAV data points for charting"),
    },
  • Handler function: validates API key, calls getProductDetail and optionally getProductChart APIs, formats result with strategy metrics (totalReturn, maxDrawdown, recent1dReturn, recent30dReturn, tradeCount, etc.) and optional chart data (dataPoints with NAV history). Returns JSON stringified result.
    async ({ apiKey, productId, includeChart }) => {
      const auth = await validateApiKey(apiKey);
      if (!auth.valid) {
        return { content: [{ type: "text" as const, text: auth.message }] };
      }
    
      const [detailRes, chartRes] = await Promise.all([
        callAPI("getProductDetail", { productId }) as Promise<{
          code: number;
          data: Record<string, unknown>;
        }>,
        includeChart
          ? (callAPI("getProductChart", { productId }) as Promise<{
              code: number;
              data: Record<string, unknown>;
            }>)
          : Promise.resolve(null),
      ]);
    
      if (detailRes.code !== 0 || !detailRes.data) {
        return {
          content: [
            {
              type: "text" as const,
              text: `Strategy '${productId}' not found`,
            },
          ],
        };
      }
    
      const d = detailRes.data;
      const result: Record<string, unknown> = {
        productId: d.productId,
        name: d.name,
        market: d.market,
        description: d.description || d.shortDescription,
        totalReturn: d.totalReturn ?? d.totalReturn5Y,
        metricsYearLabel: d.metricsYearLabel,
        maxDrawdown: d.maxDrawdown,
        recent1dReturn: d.recent1dReturn,
        recent30dReturn: d.recent30dReturn,
        tradeCount: d.tradeCount ?? d.tradeCount5Y,
        status: d.status,
      };
    
      if (chartRes?.data) {
        const cd = chartRes.data;
        result.chart = {
          totalPoints: cd.totalPoints,
          lastUpdated: cd.lastUpdated,
          dataPoints: cd.dataPoints, // [{d, nav}, ...]
        };
      }
    
      return {
        content: [
          {
            type: "text" as const,
            text: JSON.stringify(result, null, 2),
          },
        ],
      };
    }
  • Helper function callAPI used by the handler to make HTTP POST requests to the QuantToGo API.
    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();
    }
  • Helper function validateApiKey used by the handler to verify API key validity before fetching performance data.
    async function validateApiKey(apiKey: string): Promise<{ valid: boolean; message: string }> {
      const res = (await callAPI("getApiStatus", { apiKey })) as {
        code: number;
        message: string;
      };
      if (res.code === 401) return { valid: false, message: "Invalid API key. Use register_trial with your email to get a valid key." };
      if (res.code === 403) return { valid: false, message: "Trial expired. Email admin@quanttogo.com to subscribe." };
      if (res.code !== 0) return { valid: false, message: res.message || "API key validation failed." };
      return { valid: true, message: "ok" };
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must cover behavioral aspects. It lists specific returned metrics and notes the authentication requirement. It does not mention potential errors, rate limits, or that it is read-only, but it provides sufficient context for an agent to understand the tool's non-destructive nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with two sentences that front-load the purpose and list outputs, then provide the authentication requirement. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must explain return values. It lists key metrics but not all possible details (e.g., format of NAV data, error handling). It covers the main points but misses some completeness for a first-time user.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains each parameter. The description adds value by reiterating the need for an API key and hinting at its acquisition via register_trial, but does not add significant new semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it gets performance metrics for a specific strategy, listing returns, drawdown, Sharpe, win rate, and daily NAV history. This distinguishes it from siblings like compare_strategies (compares multiple) and list_strategies (lists all).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions requiring an API key from register_trial, indicating a prerequisite. However, it does not explicitly guide when to use this tool versus alternatives like compare_strategies or get_signals, leaving some ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/QuantToGo/quanttogo-mcp'

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