Skip to main content
Glama

MarketHeist Backtest

portfolio_risk

Read-onlyIdempotent

Answer both 'how bad did it get' and 'is it really diversified' for a built-in model portfolio, a canonical strategy or your own portfolio. Drawdowns: the deepest peak-to-trough episodes with months to trough and recovery, Ulcer index, longest time underwater, monthly VaR/CVaR 95, worst month and year, and returns in 2008, 2020 and 2022. Diversification: each holding's share of the risk next to its share of the money (60/40 is about 60% of the money and 93% of the risk), the number of independent bets over the full window, the last 10 years and the 36 months to Feb 2009 and Dec 2022, co-movement groups, near-duplicate pairs and the equal-risk weights. Correlations: the holdings' correlation matrix. Pass exactly one of template (e.g. classic-60-40, all-weather), strategy (e.g. faber-trend-timing) or assets (your own allocation, including nested portfolios, rotations and strategies as holdings via sleeve, with optional rebalance and overlay); list_portfolios shows valid ids. sections limits the output. Ids are precomputed from the monthly refresh (instant); assets are computed live, with independent bets over the full window (and the last 10 years for plain tickers); the 2008 and 2022 windows are computed for built-in portfolios only. Read-only. For headline CAGR/Sharpe use analyze_portfolio; for calendar returns use portfolio_returns.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
labelNoOptional display name for a custom `assets` portfolio. Default "Custom portfolio".
assetsNoYour own allocation instead of an id, computed live (drawdowns, risk share, bets and correlations of your own mix). Same format as analyze_portfolio: plain tickers and nested portfolios, rotations or strategies via `sleeve`. Weights in percent, summing to ~100.
overlayNoOptional portfolio-level trend-filter overlay applied to the WHOLE book: hold the entire portfolio only while its own level is above its N-month moving average, otherwise cash. Composition is monthly (a 10-month filter ≈ the classic 200-day one).
episodesNoHow many of the deepest drawdown episodes to list (1-8). Default 5.
sectionsNoWhich parts to return: drawdowns, diversification, correlations. Default: all three.
strategyNoCanonical rule-based strategy id, e.g. 'faber-trend-timing'. A strategy is one rule-based line, so its diversification section is reported as not applicable.
templateNoBuilt-in model portfolio id, e.g. 'classic-60-40', 'all-weather', 'golden-butterfly'. list_portfolios shows all 19.
rebalanceNoRebalancing cadence for custom portfolios (templates use their own).yearly

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • addedInput schema / properties / assets
      Added value: +{
      +  "description": "Your own allocation instead of an id, computed live (drawdowns, risk share, bets and correlations of your own mix). Same format as analyze_portfolio: plain tickers and nested portfolios, rotations or strategies via `sleeve`. Weights in percent, summing to ~100.",
      +  "items": {
      +    "properties": {
      +      "sleeve": {
      +        "additionalProperties": true,
      +        "description": "Advanced: a strategy node instead of a plain ticker — the app's SleeveRef, resolved server-side. Supported: a rotation/selection (`{source:'selection', config:{universe:[{ticker}], signal:{kind:'indicator', indicatorId, params} | {kind:'trailing-return', lookbackMonths, skipMonths (>= 1; the ranking for a month only sees data through the previous month-end)}, topK, weighting, rebalance}, label}`), a strategy-over-node (`{source:'strategy-over', child:{ticker}, config:<BacktestConfig>, label}`), a saved strategy preset (`{source:'backtest-live', ticker, frequency, config, presetId, label}`), a curated public-library strategy (`{source:'backtest-public', strategyId, label}`), a published backtest share (`{source:'backtest-share', shareId, label}`), a gallery template (`{source:'portfolio-public', templateId, label}`), or a nested portfolio (`{source:'portfolio-mine', portfolioId, config, label}`). Strategies with a config get a node-level overfit check (a share carries only its frozen curve, so no overfit).",
      +        "type": "object"
      +      },
      +      "ticker": {
      +        "description": "Yahoo Finance ticker, e.g. VTI, BND, GLD. Omit when `sleeve` is given.",
      +        "type": "string"
      +      },
      +      "weight": {
      +        "description": "Target weight in percent.",
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "weight"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / label
      Added value: +{
      +  "description": "Optional display name for a custom `assets` portfolio. Default \"Custom portfolio\".",
      +  "type": "string"
      +}
    • addedInput schema / properties / overlay
      Added value: +{
      +  "description": "Optional portfolio-level trend-filter overlay applied to the WHOLE book: hold the entire portfolio only while its own level is above its N-month moving average, otherwise cash. Composition is monthly (a 10-month filter ≈ the classic 200-day one).",
      +  "properties": {
      +    "kind": {
      +      "enum": [
      +        "trend-filter"
      +      ],
      +      "type": "string"
      +    },
      +    "months": {
      +      "description": "Moving-average window in months (≥ 2, e.g. 10).",
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "kind",
      +    "months"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / rebalance
      Added value: +{
      +  "default": "yearly",
      +  "description": "Rebalancing cadence for custom portfolios (templates use their own).",
      +  "enum": [
      +    "none",
      +    "monthly",
      +    "quarterly",
      +    "yearly"
      +  ],
      +  "type": "string"
      +}
  2. Added

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds substantive behavioral context the annotations cannot: built-in ids are precomputed and instant while `assets` are computed live, independent bets span the full window (and last 10 years for plain tickers), and the 2008/2022 windows exist only for built-in portfolios. These computational caveats meaningfully change how an agent should call it.

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

Conciseness4/5

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

Front-loaded with purpose before the dense enumeration of outputs, then selector rules, then routing. It is long, but the length tracks a genuinely complex tool and nearly every clause carries information (Ulcer index, co-movement groups, near-duplicate pairs, overfit checks). Minor density cost prevents a 5.

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

Completeness5/5

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

With no output schema, the description carries the return-value burden and does so by naming the three sections (drawdowns, diversification, correlations) and their contents. Combined with the selector constraints and sibling routing, an agent has everything needed to call it correctly.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds value beyond the schema: worked examples for template ('classic-60-40', 'all-weather') and strategy ('faber-trend-timing') ids, the mutual-exclusivity rule across the three selector params, and the note that `sleeve` enables nested portfolios/rotations/strategies, plus how `sections` scopes output.

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?

Opens with a concrete framing ('how bad did it get' and 'is it really diversified') and then enumerates the exact outputs: drawdown episodes with months-to-trough/recovery, Ulcer index, VaR/CVaR, risk-vs-money share, number of independent bets, correlation matrix. This distinguishes it from siblings like analyze_portfolio (CAGR/Sharpe) and portfolio_returns (calendar returns) by name.

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

Usage Guidelines5/5

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

Explicitly states the exactly-one-of constraint over `template`, `strategy`, and `assets`, points to list_portfolios for valid ids, and routes headline metric and calendar-return questions to analyze_portfolio and portfolio_returns respectively. When-to-use and when-not-to-use are both covered.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources