Skip to main content
Glama

Valuein — SEC EDGAR Fundamentals & Smart-Money Data

Run Bounded Factor Backtest

run_backtest
Read-onlyIdempotent

A SMALL, BOUNDED, in-Worker sanity-check backtest — NOT a full-universe backtesting engine. Answers a quick question like 'does this factor actually work on these 5 names over the last year' inline, mid-conversation, without leaving MCP. Composes two existing tools (get_pit_universe + get_pit_valuation_ratios) across up to 10 tickers x 12 rebalance dates (120 cells): for each rebalance date, checks which requested tickers were in the survivorship-free PIT universe on that date (dropping — never erroring on — a ticker not yet listed or already delisted), then pulls each surviving ticker's point-in-time valuation multiples and computes the forward return to the NEXT rebalance date from the raw (unadjusted) close. Returns a flat {rebalance_date, ticker, factor_values, forward_return_pct} grid plus a small factor<->forward-return correlation per requested factor — a quick cross-sectional signal check, NOT a transaction-cost-aware portfolio simulation or a statistically validated backtest result. If the requested grid exceeds 120 cells, this tool does NOT silently truncate — it returns a stream_fallback response (signed Parquet download URLs, same shape as get_compute_ready_stream) and tells you to use those URLs. For a REAL full-universe, multi-date, survivorship-free backtest, use the Python SDK's AlphaEngine (pip install valuein-sdk) looped over as_of dates client-side — this tool is explicitly the small complement to that, not a replacement for it. Pro and Institutional only: it composes get_pit_valuation_ratios, which reads the daily price series the free tiers do not carry (licensed market data), so the free plans receive an ENTITLEMENT_DENIED upgrade envelope before any read. Coverage follows your plan tier same as the two tools it composes.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
factorsNoWhich of get_pit_valuation_ratios's own output fields to include as factor_values. One or more of: pe_ratio, ps_ratio, pb_ratio, ev_ebitda, ev_revenue, fcf_yield_pct, gross_margin_pct, operating_margin_pct, net_margin_pct. Omit to include all of them.
tickersYes1-10 stock ticker symbols, e.g. ["AAPL","MSFT"].
rebalance_datesYes1-12 historical dates (YYYY-MM-DD) to snapshot valuation multiples on. Order does not matter — the tool sorts them chronologically. Forward return is computed from each date to the NEXT one in the sorted list.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
noteYes
_metaYesProvenance envelope — data lineage for every MCP response
cellsNo
cappedYes
methodYes
caveatsYes
droppedYes
factorsYes
streamsNo
summaryNo
tickersYes
pit_safeYes
next_stepNo
grid_cellsYes
cells_computedYes
rebalance_datesYes
source_tools_usedYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / properties / _meta / properties / fundamentals_as_of / description
      Previous value: -"ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt. Use THIS — not `last_updated` — when telling a user how current the fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to."New value: +"ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt in bulk. Use THIS — not `last_updated` — when telling a user how current the cross-sectional fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to. It is a floor for a single filer, not a ceiling: a filer with a live partition receives its filing, facts and ratios intraday (minutes after EDGAR dissemination), so an entity-scoped read may carry a filing newer than this; cross-sectional ranks (factor scores, earnings signals) refresh with the weekly bulk export."
  2. Changed1 schema field changed
    • changedInput schema / properties / tickers / items / pattern
      Previous value: -"^[A-Za-z][A-Za-z0-9.\\-]{0,9}$"New value: +"^([A-Za-z][A-Za-z0-9.\\-]{0,9}|\\d{1,10})$"
  3. Changed2 schema fields changed
    • addedOutput schema / properties / _meta / properties / fundamentals_as_of
      Added value: +{
      +  "description": "ISO timestamp when the FINANCIAL STATEMENTS were last rebuilt. Use THIS — not `last_updated` — when telling a user how current the fundamentals are. The snapshot is republished on every weekday price refresh while the statements are carried forward unchanged, so `last_updated` can be far more recent than the numbers it sits next to.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / _meta / properties / price_as_of
      Added value: +{
      +  "description": "ISO timestamp when the price surfaces were last refreshed.",
      +  "type": "string"
      +}
  4. Changed2 schema fields changed
    • addedOutput schema / properties / _meta / properties / cost_usd
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Per-call cost transparency. Omitted for subscription-only tools that have no PAYG-equivalent price.",
      +  "properties": {
      +    "amount_usd": {
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "basis": {
      +      "description": "payg_charge = real agent-pay charge. payg_rate_card = indicative price, not billed.",
      +      "enum": [
      +        "payg_charge",
      +        "payg_rate_card"
      +      ],
      +      "type": "string"
      +    },
      +    "billed": {
      +      "description": "true = this amount was actually charged via PAYG for this call. false = indicative PAYG-equivalent value; your plan already covers this call for free.",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "amount_usd",
      +    "billed",
      +    "basis"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / _meta / properties / latency_ms
      Added value: +{
      +  "description": "Wall-clock milliseconds this tool call took, measured server-side around the handler.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
  5. Added

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark this as read-only and idempotent, and the description adds valuable behavioral context beyond that: tickers missing from the PIT universe are dropped rather than causing errors, oversize grids return signed Parquet URLs instead of silently truncating, and license-tier restrictions surface as ENTITLEMENT_DENIED. These are exactly the non-obvious runtime behaviors an agent needs to predict before invoking.

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 long, but every sentence carries decision-critical information: scope, boundedness, composition, error behavior, fallback, entitlement gates, and alternative tooling. It front-loads the most important distinction ('sanity-check, NOT a full-universe backtesting engine') and contains no filler or redundancy.

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 tool with this complexity—composing two PIT data sources, bounded grid logic, entitlement restrictions, and a non-trivial output contract—the description is complete. It covers edge-case behavior (dropped tickers, oversize fallback), auth/entitlement consequences, and the exact relationship to sibling tools. The existence of an output schema means the return grid does not need to be re-specified, and the description still gives a useful shape summary.

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?

The input schema already provides 100% parameter coverage with clear descriptions and enums, so the baseline is 3. The description adds meaning beyond the schema by clarifying the forward-return convention ('to the NEXT one in the sorted list'), the 120-cell bound, and the factor source fields from get_pit_valuation_ratios. It does not merely repeat schema content, so it earns a 4.

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 opens with a specific, bounded purpose: 'A SMALL, BOUNDED, in-Worker sanity-check backtest — NOT a full-universe backtesting engine.' It names the exact behavior, the composed tools, the output grid, and differentiates itself from the Python SDK AlphaEngine. An agent can immediately know what this tool is and what it is not.

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?

Usage guidance is explicit and decision-ready: use it for quick cross-sectional sanity checks up to 10 tickers x 12 dates mid-conversation, and use AlphaEngine for real full-universe backtests. It also tells the agent exactly what happens for free plans (ENTITLEMENT_DENIED) and for oversized grids (stream_fallback), leaving no ambiguity about when to call it versus alternatives.

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.