Skip to main content
Glama

MarketHeist Backtest

Server Details

Backtest and analyze any portfolio, incl. nested multi-strategy ones: returns, risk, factors, guides

Ownership verified
Status
Healthy
Uptime
10.7% over 58 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL

TDQS

A4.5/5.0

Scored across 10 tools

Disambiguation4/5

Each tool has a distinct focus and the descriptions explicitly cross-reference boundaries (e.g. analyze_portfolio points to portfolio_returns for seasonality and portfolio_risk for drawdowns). There is still real overlap: analyze_portfolio, portfolio_returns and portfolio_risk all report on the same portfolios with partly overlapping metrics (CAGR/Sharpe/drawdowns), so an agent must read the routing hints carefully to pick correctly.

Naming Consistency4/5

All names use consistent snake_case throughout, with most following a verb_noun pattern (analyze_portfolio, compare_portfolios, decompose_factors, find_guides, list_indicators, list_portfolios, run_backtest). Minor deviation: fund_history, portfolio_returns and portfolio_risk are noun phrases rather than verb-led, but the overall convention is readable and predictable.

Tool Count5/5

Ten tools is well-scoped for a portfolio/backtest analytics server. Each tool covers a genuinely distinct capability (listing, analysis, comparison, factor decomposition, returns, risk, backtesting, history lookup, guide search), so none feel redundant padding.

Completeness4/5

The surface covers the full read-only analytics lifecycle: discovery (list_portfolios, list_indicators, find_guides), single-portfolio analysis, comparison, factor decomposition, returns, risk, fund-history provenance and single-asset backtesting. Minor gaps: it is entirely read-only with no ability to persist or save a user's custom allocation, and no direct cross-ticker search utility, but core workflows are covered.

Available Tools

10 tools
analyze_portfolioA
Read-onlyIdempotent
Inspect

Analyze an asset-allocation ('lazy') portfolio and get long-run performance computed from real monthly price history (proxy-extended for decades of data), not estimated: CAGR, max drawdown, volatility, Sharpe, Sortino, Ulcer index, $10,000 growth, the number of independent bets (holdings whose returns average a correlation of 0.5 or more count as one group, then the effective count of groups by risk share), the top risk driver, trailing Sharpe, and a validity block (provenance, caveats, a reproduce-me hash) plus a cite block with the marketheist.io pages that show the same numbers. Use it for 'how did 60/40 / All Weather / Golden Butterfly perform' or for a custom mix. Provide exactly one of: a template id (19 model portfolios, listed in list_portfolios), a strategy id (7 rule-based canonical strategies, e.g. dual-momentum-gem) or a custom assets allocation (plain tickers and nested portfolios, rotations, strategies as holdings via sleeve). Template and strategy ids are answered from precomputed data through the stated month (instant, not rate-limited); custom assets and an overlay are computed live from market data. For seasonality and calendar years use portfolio_returns; for drawdown episodes and diversification use portfolio_risk; to compare portfolios use compare_portfolios. Read-only; surface the caveats when reporting.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelNoOptional display name for a custom `assets` portfolio. Default "Custom portfolio".
assetsNoCustom allocation (omit if using `template` or `strategy`). Weights are percentages summing to ~100. A holding is a plain ticker OR a strategy node via `sleeve`.
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).
strategyNoCanonical rule-based strategy to analyze. One of: dual-momentum-gem, tsmom-sp500, faber-trend-timing, sector-momentum-rotation, risk-parity-inverse-vol, gtaa-aggressive, adaptive-asset-allocation. Answered from precomputed data. Omit when using `template` or `assets`.
templateNoBuilt-in model portfolio to analyze. One of: golden-butterfly, all-weather, permanent, dragon, faber-ivy, faber-gaa, bogleheads-3fund, wealthfront-classic, betterment-core, classic-60-40, classic-40-60, swensen, ferri-core-four, couch-potato, coffeehouse, no-brainer, larry, buffett-90-10, total-sp500. Omit to analyze a custom `assets` allocation instead.
rebalanceNoRebalancing cadence for custom portfolios (templates use their own).yearly

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the readOnly/idempotent/openWorld annotations, it discloses that template and strategy ids are answered from precomputed data (instant, not rate-limited) while custom assets and overlays are computed live, and that results carry provenance, caveats, and a reproduce-me hash. It also instructs the agent to surface caveats when reporting.

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-loads purpose then usage, and every sentence carries real information for a 6-param nested tool. It is dense as a single run-on paragraph, and the long output enumeration could be tightened, but nothing is wasted.

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?

For a complex tool with nested objects and no output schema, the description covers inputs, computation provenance, returned metrics, validity/cite blocks, and usage routing. An agent has everything needed to call it correctly and interpret results.

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% (baseline 3), but the description adds meaning the schema does not enforce: the mutual exclusivity of template/strategy/assets, the definition of an 'independent bet' (correlation ≥ 0.5 groups), and the practical effect of the overlay. It reinforces rather than repeats 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?

Opens with a specific verb+resource ('Analyze an asset-allocation portfolio') and enumerates the exact metrics returned (CAGR, max drawdown, volatility, Sharpe, Sortino, Ulcer index, etc.), so an agent knows precisely what it produces. It also distinguishes itself from siblings like compare_portfolios, portfolio_returns, and portfolio_risk 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?

Gives concrete triggering examples ('how did 60/40 / All Weather / Golden Butterfly perform' or a custom mix) and explicitly routes other needs to alternatives: seasonality/calendar years to portfolio_returns, drawdown/diversification to portfolio_risk, comparisons to compare_portfolios. It also states the exactly-one-of input contract.

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

compare_portfoliosA
Read-onlyIdempotent
Inspect

Compare 2 to 4 portfolios (built-in model portfolios, canonical strategies or your own allocations) side by side over their COMMON window, which is the only fair comparison: two pages' headline numbers usually cover different periods (a portfolio holding gold starts in 2004, the Ivy portfolio in 1996). Returns CAGR, volatility, max drawdown, Sharpe, Sortino, Ulcer index, best/worst year and longest time underwater on the aligned months, each portfolio's own full-window figures (labelled with their start), the pairwise correlation of their monthly returns and a calendar-year table. Use it for 'All Weather vs Golden Butterfly vs 60/40', 'which of these held up better', 'my portfolio vs 60/40'. Each item in portfolios has exactly one of template or strategy (ids from list_portfolios) or assets (your own allocation, including nested portfolios, rotations and strategies as holdings, with optional rebalance and overlay), plus an optional label. Ids are precomputed from the monthly refresh; assets entries are computed live (at most 2 custom entries and 24 distinct tickers per call). Read-only. For one portfolio's detail use analyze_portfolio, portfolio_returns or portfolio_risk.

ParametersJSON Schema
NameRequiredDescriptionDefault
yearsNoCalendar-year rows to include (most recent N years of the common window; 0 = none). Default 10.
portfoliosYes2 to 4 portfolios to compare, e.g. [{"template":"all-weather"},{"template":"golden-butterfly"},{"template":"classic-60-40","label":"60/40"}].

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint/idempotent/non-destructive, so 'Read-only' is largely redundant. However the description adds real behavioral context beyond the structured fields: ids are precomputed from a monthly refresh while `assets` entries are computed live, and there is a hard limit of 2 custom entries and 24 distinct tickers per call. It stops short of noting any latency or cost differences between the precomputed and live paths.

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

Conciseness3/5

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

The content is largely on-point and front-loads the purpose, but it is one dense wall of text with clause-heavy sentences and no visual breaks, making it harder to scan than an equivalent set of shorter lines. The side commentary ('the only fair comparison', the gold/Ivy dates) adds color but lengthens an already long block.

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?

Although there is no output schema, the description enumerates the returned metrics precisely (CAGR, volatility, max drawdown, Sharpe, Sortino, Ulcer, best/worst year, longest time underwater, per-portfolio full-window figures, pairwise correlations, calendar table) plus the alignment model. Nothing material is missing for a comparison tool of this complexity.

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 meaning the schema does not: the 'exactly one of template or strategy or assets' invariant per item, the source of ids (list_portfolios), and the live-vs-precomputed distinction with its 2-entry/24-ticker caps. These constraints go beyond the raw property descriptions.

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?

It states a specific verb and resource ('Compare 2 to 4 portfolios ... side by side') and immediately scopes the operation to the COMMON window. Crucially it also names the siblings this is not for ('For one portfolio's detail use analyze_portfolio, portfolio_returns or portfolio_risk'), so an agent can separate it from the other portfolio tools without opening the schema.

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?

It provides explicit trigger phrases ('All Weather vs Golden Butterfly vs 60/40', 'which of these held up better', 'my portfolio vs 60/40') and an exclusion routing single-portfolio needs to three named alternatives. This is unambiguous when-to-use guidance with a clear boundary against siblings.

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

decompose_factorsA
Read-onlyIdempotent
Inspect

Explain WHAT DRIVES the returns of a ticker, ETF or built-in portfolio by decomposing them into common factor exposures (market, size, value, momentum, quality, low-volatility, duration, credit) plus an idiosyncratic residual. Use this when the user asks why two assets move together, what a fund is really exposed to, whether a stock is a growth or value tilt, how much of a return is just market beta, whether it has real alpha, or what is driving a portfolio's returns. Returns betas (loadings), t-stats, an additive variance decomposition (shares sum to R²), annualized alpha, idiosyncratic vs total volatility, and for a portfolio the holdings that drive each factor. Computed by OLS regression on real price history via tradeable ETF proxies (long-short factor spreads): measured exposure, not a forecast. Provide exactly one of target (a ticker, computed live), template (a built-in model portfolio), strategy (a canonical strategy) or assets (your own allocation, including nested portfolios, rotations and strategies as holdings, computed live); portfolio ids are answered from precomputed monthly data through the stated month. Portfolios (ids and assets) use the five default factors (market, size, value, duration, credit), are monthly and ignore frequency and factors. For performance numbers use analyze_portfolio. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelNoOptional display name for a custom `assets` portfolio. Default "Custom portfolio".
assetsNoYour own allocation instead of an id, computed live (monthly, default factors; the answer also lists the holdings behind each factor). Same format as analyze_portfolio: plain tickers and nested portfolios, rotations or strategies via `sleeve`. Weights in percent, summing to ~100.
targetNoYahoo Finance ticker to decompose, e.g. AAPL, QQQ, TLT, ARKK. Omit when using `template` or `strategy`.
factorsNoFactor ids to include. Default: MKT, SMB, HML, TERM, CREDIT (long history back to ~2001). All available: MKT, SMB, HML, MOM, QMJ, LOWVOL, TERM, CREDIT. The smart-beta trio (MOM, QMJ, LOWVOL) only has history from ~2011-2013, which shortens the analyzable window — factors without enough overlap are dropped and reported.
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).
strategyNoCanonical rule-based strategy whose returns to decompose, e.g. dual-momentum-gem. One of: dual-momentum-gem, tsmom-sp500, faber-trend-timing, sector-momentum-rotation, risk-parity-inverse-vol, gtaa-aggressive, adaptive-asset-allocation. Precomputed; default factors.
templateNoBuilt-in model portfolio whose returns to decompose, e.g. all-weather. One of: golden-butterfly, all-weather, permanent, dragon, faber-ivy, faber-gaa, bogleheads-3fund, wealthfront-classic, betterment-core, classic-60-40, classic-40-60, swensen, ferri-core-four, couch-potato, coffeehouse, no-brainer, larry, buffett-90-10, total-sp500. Precomputed; default factors.
frequencyNoReturn frequency for the regression of a `target` ticker. Monthly (default) is standard for factor analysis. Ignored for `template` / `strategy` (always monthly).1mo
rebalanceNoRebalancing cadence for custom portfolios (templates use their own).yearly

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the bar is lower, yet the description still adds substantial method context: OLS regression on real price history via long-short ETF proxies, 'measured exposure, not a forecast', precomputed monthly data for portfolios, and the drop-and-report behavior when factors lack overlapping history.

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 then when-to-use then output then input constraints, so it reads in the right order and every sentence carries information. It is nonetheless a single dense paragraph of roughly 250 words, and the input-mode constraints would scan faster as a short list.

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?

There is no output schema, so the description carries the return-value burden and does so fully: betas, t-stats, additive variance decomposition summing to R², annualized alpha, idiosyncratic vs total volatility, and per-factor holdings for portfolios. Nothing an agent needs to call this correctly is missing.

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

Parameters5/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 constraints the schema does not encode: exactly one of target/template/strategy/assets, that portfolios ignore `frequency` and `factors` and always use the five default factors monthly, and the short-history caveat on the smart-beta trio. This is genuine cross-parameter meaning beyond the field-level docs.

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?

States a precise verb+resource (decompose a ticker/ETF/portfolio's returns into named factor exposures plus idiosyncratic residual) and enumerates the exact factor set. It also explicitly contrasts itself with the sibling analyze_portfolio, so an agent can route without opening either schema.

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?

Gives an unusually rich when-to-use list framed as real user questions (why two assets move together, growth vs value tilt, how much is just beta, is there real alpha) and names the alternative tool for performance numbers. The when-not condition for each input mode is also stated.

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

find_guidesA
Read-onlyIdempotent
Inspect

Search MarketHeist's 90 published research pages and get the page's own verdict and numbers, with its URL to cite: 18 strategy guides (60/40, All Weather, Golden Butterfly, DCA vs lump sum, ...), 26 fund-history pages (how far back an ETF can be tested), 18 trend-filter pages (what a 10-month trend filter did to each portfolio), 16 risk breakdowns (share of risk vs share of money) and 12 rule-robustness pages (does the 200-day average or the golden cross survive other settings, costs and held-out years). Each result returns the title, current verdict, 3-7 headline numbers with the data month, and the last change-log entries. Use it to give a sourced, dated answer to 'does the 200-day average work on SPY', 'would a trend filter have helped All Weather in 2022', 'how far back does VXUS go'. query is free words, a ticker or a portfolio name; slug returns one page in full (e.g. 'risk/classic-60-40', 'robustness/sma-200-spy'). Read-only and precomputed from the monthly refresh. For live numbers on your own allocation use analyze_portfolio or run_backtest.

ParametersJSON Schema
NameRequiredDescriptionDefault
setNoRestrict to one page set: strategies, history, trend, risk or robustness. Default any.any
slugNoExact page as '<set>/<id>', e.g. 'risk/classic-60-40' or 'robustness/sma-200-spy'. Returns that page in full (every number, labels, change log); `query` is ignored.
limitNoMaximum results for a search (1-10). Default 5.
queryNoWords, a ticker or a portfolio name, e.g. '200-day SPY', 'all weather trend', 'VXUS', 'golden cross'.

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 and non-destructive; the description adds real context beyond them: results are precomputed from the monthly refresh, each result carries a title, verdict, 3-7 headline numbers with their data month, and change-log entries. It does not cover pagination or ranking behavior, keeping it short of a 5.

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?

Purpose is front-loaded and each sentence carries information, though the long parenthetical enumeration of the five page sets is dense. Effectively sized for the breadth of the corpus, with no filler sentences.

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 compensates by specifying the return shape (title, verdict, headline numbers with data month, change log). Combined with clear query/slug behavior 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 baseline is 3; the description goes further by explaining that `query` accepts free words, a ticker or a portfolio name, and that `slug` returns one page in full while `query` is ignored, adding precedence semantics not visible in the schema alone.

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?

States a specific verb+resource (search MarketHeist's 90 published pages and return each page's verdict, numbers and citeable URL), and enumerates the content sets so the agent knows exactly what corpus it queries. Explicitly distinguishes itself from analyze_portfolio and run_backtest.

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?

Gives concrete when-to-use triggers ('does the 200-day average work on SPY', 'would a trend filter have helped All Weather in 2022') and an explicit when-not-to-use routing to analyze_portfolio/run_backtest for live numbers on a custom allocation.

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

fund_historyA
Read-onlyIdempotent
Inspect

Tell how far back a fund can be tested on MarketHeist once its history is extended with older substitute funds: the proxy chain (e.g. VXUS <- VGTSX), the extended start month, the ETF's own first month and, for the 26 funds with a history page, how closely each stand-in tracked the ETF while both existed (grade close / approximate / stand-in, worst tracking error), the extended-history vs ETF-only CAGR and how many S&P 500 declines the extension adds. Use it for 'can I backtest VXUS to 2000', 'how reliable is the pre-2011 data for BND', before quoting any long-run number for a fund. One ticker per call (e.g. VXUS, VTI, TLT, GLD). Read-only and static: no market-data fetch. A ticker with no proxy chain starts at its own inception. For returns of the fund use portfolio_returns; for the rules behind a portfolio's start date use analyze_portfolio.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYesFund or ETF ticker, e.g. VXUS, VTI, BND, TLT, GLD, DBMF. Case-insensitive; one ticker per call.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description still adds real behavior: the data is static with 'no market-data fetch', and a ticker with no proxy chain simply starts at its own inception — an edge case an agent could not infer from the schema or annotations.

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?

The core capability is front-loaded in the opening clause, and nearly every sentence carries information (return payload, use cases, alternatives, edge case). The middle sentence is a very long list of outputs that borders on run-on and could be tightened, costing it the top mark.

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?

There is no output schema, so the description carries the full burden of describing the return payload — and it does so field by field (proxy chain, extended start month, tracking grade, worst tracking error, CAGR deltas, decline counts). Combined with the edge-case and read-only notes, an agent has everything needed to call and interpret it.

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% and the single parameter is fully documented, so the baseline would be 3. The description goes further by clarifying that one ticker is accepted per call and by defining value semantics for tickers lacking a proxy chain (they start at own inception), which is meaning beyond the schema's format description.

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 names a specific verb+resource (report how far back a fund can be backtested, via its proxy chain) and enumerates exactly what it returns: proxy chain, extended start month, ETF's own first month, tracking grade, CAGR comparison, and count of S&P 500 declines added. It is immediately distinguishable from siblings like portfolio_returns and analyze_portfolio, which it names as the tools for adjacent needs.

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?

It gives explicit triggering questions ('can I backtest VXUS to 2000', 'how reliable is the pre-2011 data for BND') and an explicit timing rule ('before quoting any long-run number for a fund'). It also routes to alternatives: portfolio_returns for returns, analyze_portfolio for portfolio start-date rules.

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

list_indicatorsA
Read-onlyIdempotent
Inspect

List the built-in technical indicators available for backtesting (RSI, moving-average crossovers, ADX, Bollinger, CCI, Stochastic, and more) with their IDs, parameters with defaults, and each indicator's default long rule. Call this to answer what strategies or indicators can be tested, or before run_backtest when unsure which indicator_id or parameters to use. Takes no arguments. Read-only and static (no market data is fetched, never rate-limited by the live budget). To find portfolios and strategies instead, use list_portfolios.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, but the description adds genuinely new behavioral context: it is static, fetches no market data, and is 'never rate-limited by the live budget' – information an agent cannot derive from the annotations.

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?

Front-loads the what, then the when-to-use, then operational notes, then the sibling redirect. Every sentence carries unique information with no filler.

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?

No output schema exists, but the description explains what the return contains (IDs, parameters with defaults, each indicator's default long rule), covers the zero-arg nature, and routes to siblings. Complete for an agent 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?

Zero parameters, so the baseline is 4. The description reinforces this with 'Takes no arguments' and describes what the returned records contain (IDs, parameters with defaults, default long rule), which helps the agent interpret the call.

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?

States a specific verb (List) and resource (built-in technical indicators), then enumerates the concrete families returned (RSI, MA crossovers, ADX, Bollinger, CCI, Stochastic). It also distinguishes itself from the sibling list_portfolios, so an agent can route without opening either schema.

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?

Gives explicit triggers: 'Call this to answer what strategies or indicators can be tested' and 'before run_backtest when unsure which indicator_id or parameters to use.' It also names the alternative (list_portfolios) with the condition that selects it, leaving nothing to inference.

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

list_portfoliosA
Read-onlyIdempotent
Inspect

List every portfolio and strategy the other tools accept by id, with a one-line description, holdings, headline CAGR / max drawdown / Sharpe with the start month and the data month, and the marketheist.io page and guide URLs. Three kinds: template (19 buy-and-hold model portfolios such as classic-60-40, all-weather, golden-butterfly, permanent; used as template in analyze_portfolio, portfolio_returns, portfolio_risk, compare_portfolios, decompose_factors), strategy (7 rule-based canonical strategies such as dual-momentum-gem and faber-trend-timing; used as strategy), and library_strategy (19 curated single-asset backtest strategies, usable as holdings via {source:'backtest-public', strategyId} in analyze_portfolio). Call this first when you do not know an id, to avoid guessing. query filters by name, id or a holding ticker (e.g. 'gold', 'TLT'). Read-only and precomputed (data through the stated month); the numbers are full-window headline figures over each entry's own start, so use compare_portfolios for a like-for-like comparison.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoWhich list: template (model portfolios), strategy (canonical rule-based strategies), library_strategy (curated backtest strategies) or all. Default all.all
queryNoOptional filter on name, id, description or a holding ticker, e.g. 'gold', 'momentum', 'TLT'.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the description rightly spends its words on other traits: the data is precomputed and only current through the stated month, and the headline CAGR/drawdown/Sharpe figures are full-window over each entry's own start, making them non-comparable across entries. That non-obvious caveat is exactly the kind of behavioral context annotations cannot carry.

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?

The key action and the critical 'call this first' guidance are front-loaded, and every sentence carries information. It is dense and the long parenthetical enumerations of examples make it longer than strictly necessary, but nothing is filler.

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?

There is no output schema, yet the description enumerates the return payload (one-line description, holdings, headline metrics with start and data month, page and guide URLs). Combined with the filtering and staleness notes, an agent has everything needed to call and interpret 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 enum values and the query filter are already documented; baseline would be 3. The description adds meaning beyond the schema by tying each `kind` value to how the resulting ids are consumed as parameters elsewhere, and by giving concrete filter examples ('gold', 'TLT').

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?

States a specific verb+resource (list every portfolio and strategy accepted by id) and immediately enumerates the three kinds with counts and named examples. It distinguishes itself from siblings by explicitly mapping each kind to the parameter name used in analyze_portfolio, portfolio_returns, portfolio_risk, compare_portfolios and decompose_factors.

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?

Gives an explicit trigger: 'Call this first when you do not know an id, to avoid guessing.' It also names the alternative and the condition for it (use compare_portfolios for a like-for-like comparison), so the agent knows both when to use this and when not to.

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

portfolio_returnsA
Read-onlyIdempotent
Inspect

Look up how a portfolio, strategy or fund actually returned: seasonality by calendar month (average return, share of positive months, number of years and a t-statistic so a thin 'September effect' is not presented as a law), calendar-year returns with partial years labelled (optionally next to the S&P 500), trailing 1/3/5/10/20/30-year returns, and the best and worst year and month. Use it for 'is September bad for 60/40', 'what did All Weather return in 2022', 'how has SPY done over 10 years', 'what did my own portfolio return each year'. Pass exactly one of template (e.g. all-weather, classic-60-40), strategy (e.g. dual-momentum-gem), ticker (any Yahoo ticker) or assets (your own allocation, including nested portfolios, rotations and strategies as holdings via sleeve, with optional rebalance and overlay); list_portfolios shows every valid id. Built-in ids and the funds with a history page are precomputed from the monthly refresh (instant); other tickers and assets are computed live from market data (proxy-extended monthly total returns). Read-only; every answer says which month the data runs through. For risk and drawdowns use portfolio_risk; to compare portfolios use compare_portfolios.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelNoOptional display name for a custom `assets` portfolio. Default "Custom portfolio".
yearsNoLimit the calendar-year table to the most recent N years (e.g. 10). Default: all years.
assetsNoYour own allocation instead of an id, computed live (monthly composition, proxy-extended). Same format as analyze_portfolio: plain tickers and nested portfolios, rotations or strategies via `sleeve`. Weights in percent, summing to ~100.
tickerNoA Yahoo Finance ticker, e.g. SPY, VTI, TLT, AAPL. Funds held by the built-in portfolios or with a history page are precomputed; any other ticker is computed live (proxy-extended where a proxy chain exists).
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).
sectionsNoWhich tables to return: seasonality, calendar_years, trailing. Default: all three.
strategyNoCanonical rule-based strategy id, e.g. 'dual-momentum-gem' or 'faber-trend-timing'. list_portfolios shows all 7.
templateNoBuilt-in model portfolio id, e.g. 'all-weather' or 'classic-60-40'. list_portfolios shows all 19.
benchmarkNo'sp500' adds S&P 500 (SPY, proxy-extended) columns over the same months and the difference. Default sp500.sp500
rebalanceNoRebalancing cadence for custom portfolios (templates use their own).yearly

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the read-only/idempotent annotations, it discloses the computation model (precomputed from monthly refresh vs. computed live with proxy-extended monthly total returns), the data-recency guarantee ('every answer says which month the data runs through'), and the overfit-check behavior for strategy nodes. These are real behavioral traits an agent could not infer from annotations.

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?

Purpose is front-loaded and every clause carries information, but the single dense paragraph pairs example queries with parameter routing, making it a heavy read. It earns its length through substance rather than padding, though it could be segmented for faster scanning.

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 and a 10-parameter nested-object input, the description enumerates what each table contains and how sections are selected, and covers the precomputed-vs-live distinction. Nothing essential for correct invocation is missing.

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 the critical constraint that exactly one of template/strategy/ticker/assets must be passed — mutual exclusivity the schema's flat properties do not express (no oneOf). It also contextualizes the sleeve/rebalance/overlay options and the benchmark default.

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?

States a precise verb+resource (returns: seasonality by month, calendar-year, trailing N-year, best/worst) and even names the specific statistics returned (t-statistic, share of positive months). It distinguishes itself from siblings by explicitly routing risk to portfolio_risk and comparison to compare_portfolios, so an agent can disambiguate without opening schemas.

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?

Gives concrete user-intent examples ('is September bad for 60/40', 'what did All Weather return in 2022') and states the mutually exclusive input modes with pointers to list_portfolios for valid ids. Explicit when-to-use-this-vs-alternatives guidance for both portfolio_risk and compare_portfolios.

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

portfolio_riskA
Read-onlyIdempotent
Inspect

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.

ParametersJSON 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

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.

run_backtestA
Read-onlyIdempotent
Inspect

Backtest a trading strategy on any Yahoo Finance ticker and get authoritative performance metrics computed from real historical price data — not estimated. Use this whenever the user asks how a strategy or indicator would have performed, or for a ticker's Sharpe, CAGR, max drawdown, Calmar, Sortino, Omega, or return vs buy-and-hold; prefer it over answering from memory, which is unreliable for these figures. Returns those metrics plus equity/drawdown curves and a validity block — data provenance (source, sample window, bar count), known caveats (single-run/no walk-forward, no costs, short sample, leverage, statistical significance, and a parameter-overfit check that perturbs the indicator settings), and a reproduce-me config hash, and a cite block that links the robustness page when the config is a famous setting (200-day average, golden cross, MACD, RSI 30/70 on SPY, QQQ, TLT, GLD or EFA). Surface the caveats when reporting results. Always pass execution_delay=1 to avoid lookahead bias. Call list_indicators first if unsure which indicator_id to use. Single asset only: for allocations use analyze_portfolio. Read-only; live market data, so heavy callers can hit the daily live-data limit.

ParametersJSON Schema
NameRequiredDescriptionDefault
tickerYesYahoo Finance ticker symbol (e.g. AAPL, ^NDX, BTC-USD, SPY).
lookbackNoRolling window for position_rule_type=percentile.
directionNoLong when indicator is above (or below) threshold/MA/percentile.above
frequencyNoBar frequency. Default: 1wk.1wk
ma_windowNoMA window for position_rule_type=crossover.
target_ddNoTarget max drawdown (negative decimal) for leverage_mode=target_dd. E.g. -0.40.
thresholdNoFixed threshold for position_rule_type=threshold. E.g. 50 for RSI, 1.0 for MA Crossover. Omit to use the indicator's default rule (the 'Default rule' list_indicators shows; e.g. RSI: above 50).
atr_periodNoATR period for regime_filter_type=volatility.
percentileNoPercentile rank threshold (0–100) for position_rule_type=percentile.
sma_windowNoSMA window for regime_filter_type=trend. Classic: 200.
target_volNoTarget annualized vol (decimal) for leverage_mode=target_vol. E.g. 0.15 = 15%.
max_atr_pctNoATR% threshold for regime_filter_type=volatility.
indicator_idYesBuilt-in indicator id. Call list_indicators to see all options. Common: rsi, bollinger, ma_crossover, ema_crossover, adx, cci, stochastic.
leverage_modeNonone=1×. fixed=constant multiplier. target_vol=scale to vol target. target_dd=scale to drawdown target.none
leverage_valueNoMultiplier for leverage_mode=fixed. E.g. 2.0 = 2×.
execution_delayNoBars of delay between signal and execution. Use 1 to avoid lookahead bias.
indicator_paramsNoIndicator parameters as a JSON string. E.g. '{"period":14}' for RSI. Omit to use defaults.{}
position_rule_typeNothreshold: long when value is above/below a fixed level. crossover: long when value is above its own MA. percentile: long when value is above its rolling percentile.threshold
regime_filter_typeNotrend: only hold when close > SMA(sma_window). volatility: only hold when ATR% < max_atr_pct.none
transaction_costs_bpsNoOne-way transaction cost in basis points (1 bps = 0.01%).

TDQS

A4.6/5.0
Behavior5/5

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

Annotations cover only the safety profile (readOnly/idempotent/openWorld/non-destructive), but the description adds substantial behavior the annotations cannot express: the validity block's known caveats (no walk-forward, no costs, overfit check), the cite block behavior, a reproduce-me config hash, and a live-data rate limit ('heavy callers can hit the daily live-data limit'). It also mandates execution_delay=1 to avoid lookahead bias.

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?

Purpose and routing are front-loaded in the first sentence, and the dense middle sentence earns its length by enumerating metrics and the validity/cite blocks. It is a single long paragraph with some run-on construction, but there is little wasted text.

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?

For a complex 20-parameter tool with no output schema, the description covers expected outputs, caveat-surfacing instructions, sibling routing, prerequisites, rate-limit risk, and a critical configuration directive. An agent has everything needed to call and report correctly.

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% with 20 parameters, so the schema already documents every field including defaults and enums. The description adds only the execution_delay=1 lookahead-bias directive, which the schema itself already states, so baseline 3 applies with no meaningful marginal value.

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?

States a specific verb and resource ('Backtest a trading strategy on any Yahoo Finance ticker') and immediately names the output classes (Sharpe, CAGR, max drawdown, Calmar, Sortino, Omega, return vs buy-and-hold). It also distinguishes itself from siblings by declaring 'Single asset only: for allocations use analyze_portfolio', so an agent can route without opening schemas.

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 when to use it ('whenever the user asks how a strategy or indicator would have performed'), when to prefer it over an alternative behavior ('prefer it over answering from memory, which is unreliable'), a prerequisite ('Call list_indicators first if unsure which indicator_id to use'), and a routing exclusion ('for allocations use analyze_portfolio'). Nothing is left to inference.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updates
    • Changedanalyze_portfolio1 field changed
      • addedInput schema / properties / label
        Added value: +{
        +  "description": "Optional display name for a custom `assets` portfolio. Default \"Custom portfolio\".",
        +  "type": "string"
        +}
    • Changedcompare_portfolios3 fields changed
      • addedInput schema / properties / portfolios / items / properties / assets
        Added value: +{
        +  "description": "Your own allocation instead of an id, computed live. Same format as analyze_portfolio's `assets` (plain tickers, or nested portfolios, rotations and strategies via `sleeve`).",
        +  "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 / portfolios / items / 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 / portfolios / items / properties / rebalance
        Added value: +{
        +  "default": "yearly",
        +  "description": "Rebalancing cadence for custom portfolios (templates use their own).",
        +  "enum": [
        +    "none",
        +    "monthly",
        +    "quarterly",
        +    "yearly"
        +  ],
        +  "type": "string"
        +}
    • Changeddecompose_factors4 fields changed
      • addedInput schema / properties / assets
        Added value: +{
        +  "description": "Your own allocation instead of an id, computed live (monthly, default factors; the answer also lists the holdings behind each factor). 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"
        +}
    • Changedportfolio_returns5 fields changed
      • addedInput schema / properties / assets
        Added value: +{
        +  "description": "Your own allocation instead of an id, computed live (monthly composition, proxy-extended). 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"
        +}
      • changedInput schema / properties / ticker / description
        Previous value: -"A fund with precomputed proxy-extended history: any holding of a built-in portfolio or strategy or a fund with a history page, e.g. SPY, VTI, VXUS, TLT, GLD, BND."New value: +"A Yahoo Finance ticker, e.g. SPY, VTI, TLT, AAPL. Funds held by the built-in portfolios or with a history page are precomputed; any other ticker is computed live (proxy-extended where a proxy chain exists)."
    • Changedportfolio_risk4 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. 8 tool updates
    • Changedanalyze_portfolio2 fields changed
      • changedInput schema / properties / assets / description
        Previous value: -"Custom allocation (omit if using `template`). Weights are percentages summing to ~100. A holding is a plain ticker OR a strategy node via `sleeve`."New value: +"Custom allocation (omit if using `template` or `strategy`). Weights are percentages summing to ~100. A holding is a plain ticker OR a strategy node via `sleeve`."
      • addedInput schema / properties / strategy
        Added value: +{
        +  "description": "Canonical rule-based strategy to analyze. One of: dual-momentum-gem, tsmom-sp500, faber-trend-timing, sector-momentum-rotation, risk-parity-inverse-vol, gtaa-aggressive, adaptive-asset-allocation. Answered from precomputed data. Omit when using `template` or `assets`.",
        +  "enum": [
        +    "dual-momentum-gem",
        +    "tsmom-sp500",
        +    "faber-trend-timing",
        +    "sector-momentum-rotation",
        +    "risk-parity-inverse-vol",
        +    "gtaa-aggressive",
        +    "adaptive-asset-allocation"
        +  ],
        +  "type": "string"
        +}
    • Addedcompare_portfolios
    • Changeddecompose_factors5 fields changed
      • changedInput schema / properties / frequency / description
        Previous value: -"Return frequency for the regression. Monthly (default) is standard for factor analysis."New value: +"Return frequency for the regression of a `target` ticker. Monthly (default) is standard for factor analysis. Ignored for `template` / `strategy` (always monthly)."
      • addedInput schema / properties / strategy
        Added value: +{
        +  "description": "Canonical rule-based strategy whose returns to decompose, e.g. dual-momentum-gem. One of: dual-momentum-gem, tsmom-sp500, faber-trend-timing, sector-momentum-rotation, risk-parity-inverse-vol, gtaa-aggressive, adaptive-asset-allocation. Precomputed; default factors.",
        +  "enum": [
        +    "dual-momentum-gem",
        +    "tsmom-sp500",
        +    "faber-trend-timing",
        +    "sector-momentum-rotation",
        +    "risk-parity-inverse-vol",
        +    "gtaa-aggressive",
        +    "adaptive-asset-allocation"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / target / description
        Previous value: -"Yahoo Finance ticker to decompose, e.g. AAPL, QQQ, TLT, ARKK."New value: +"Yahoo Finance ticker to decompose, e.g. AAPL, QQQ, TLT, ARKK. Omit when using `template` or `strategy`."
      • addedInput schema / properties / template
        Added value: +{
        +  "description": "Built-in model portfolio whose returns to decompose, e.g. all-weather. One of: golden-butterfly, all-weather, permanent, dragon, faber-ivy, faber-gaa, bogleheads-3fund, wealthfront-classic, betterment-core, classic-60-40, classic-40-60, swensen, ferri-core-four, couch-potato, coffeehouse, no-brainer, larry, buffett-90-10, total-sp500. Precomputed; default factors.",
        +  "enum": [
        +    "golden-butterfly",
        +    "all-weather",
        +    "permanent",
        +    "dragon",
        +    "faber-ivy",
        +    "faber-gaa",
        +    "bogleheads-3fund",
        +    "wealthfront-classic",
        +    "betterment-core",
        +    "classic-60-40",
        +    "classic-40-60",
        +    "swensen",
        +    "ferri-core-four",
        +    "couch-potato",
        +    "coffeehouse",
        +    "no-brainer",
        +    "larry",
        +    "buffett-90-10",
        +    "total-sp500"
        +  ],
        +  "type": "string"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "target"
        -]
    • Addedfind_guides
    • Addedfund_history
    • Addedlist_portfolios
    • Addedportfolio_returns
    • Addedportfolio_risk
  3. 1 tool update
    • Changedanalyze_portfolio2 fields changed
      • changedInput schema / properties / template / description
        Previous value: -"Built-in model portfolio to analyze. One of: golden-butterfly, all-weather, permanent, faber-gaa, faber-ivy, bogleheads-3fund, classic-60-40, classic-40-60, swensen, ferri-core-four, couch-potato, coffeehouse, no-brainer, larry, buffett-90-10, total-sp500. Omit to analyze a custom `assets` allocation instead."New value: +"Built-in model portfolio to analyze. One of: golden-butterfly, all-weather, permanent, dragon, faber-ivy, faber-gaa, bogleheads-3fund, wealthfront-classic, betterment-core, classic-60-40, classic-40-60, swensen, ferri-core-four, couch-potato, coffeehouse, no-brainer, larry, buffett-90-10, total-sp500. Omit to analyze a custom `assets` allocation instead."
      • addedInput schema / properties / template / enum
        Added value: +[
        +  "golden-butterfly",
        +  "all-weather",
        +  "permanent",
        +  "dragon",
        +  "faber-ivy",
        +  "faber-gaa",
        +  "bogleheads-3fund",
        +  "wealthfront-classic",
        +  "betterment-core",
        +  "classic-60-40",
        +  "classic-40-60",
        +  "swensen",
        +  "ferri-core-four",
        +  "couch-potato",
        +  "coffeehouse",
        +  "no-brainer",
        +  "larry",
        +  "buffett-90-10",
        +  "total-sp500"
        +]
  4. 2 tool updates
    • Changedanalyze_portfolio1 field changed
      • changedInput schema / properties / assets / items / properties / sleeve / description
        Previous value: -"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}, 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)."New value: +"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)."
    • Removedget_ohlcv
  5. 1 tool update
    • Changedrun_backtest1 field changed
      • changedInput schema / properties / threshold / description
        Previous value: -"Fixed threshold for position_rule_type=threshold. E.g. 50 for RSI, 1.0 for MA Crossover."New value: +"Fixed threshold for position_rule_type=threshold. E.g. 50 for RSI, 1.0 for MA Crossover. Omit to use the indicator's default rule (the 'Default rule' list_indicators shows; e.g. RSI: above 50)."
  6. 5 tool updates
    • First observedanalyze_portfolio
    • First observeddecompose_factors
    • First observedget_ohlcv
    • First observedlist_indicators
    • First observedrun_backtest

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides quantitative portfolio analysis tools, including return, volatility, Sharpe ratio, VaR, correlation, and rebalance simulation, using bundled OHLCV data over stdio.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables deterministic financial research by retrieving price history, calculating risk metrics such as Sharpe ratio and drawdown, and generating cited, provenance-aware reports.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to manage and analyze personal investment portfolios, including fund and stock holdings, net value tracking, XIRR calculations, penetration analysis, and backtesting.
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Local-first backtesting engine with built-in overfitting detection (PBO, deflated Sharpe, bootstrap CI, walk-forward) and a native MCP server for AI agents to validate trading strategies.
    4
    Apache 2.0
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources