Skip to main content
Glama

Run a backtest

run_backtest
Idempotent

Submit a point-in-time backtest. NON-BLOCKING: returns a run_id at once; poll get_backtest.

    `job_status` tells you where it is: `cached` (this exact backtest was already computed — the
    stored result is returned immediately), `done` (it finished within `wait_seconds`), or
    `queued` / `running` (call `get_backtest(run_id)` until it is `done` or `failed`). The same
    spec always has the same run_id, so re-submitting is free and never computes twice.

    The run may only see data stamped on or before `as_of` — that is enforced structurally, not
    by convention. Results arrive with the data `query_ids` behind them and an anti-overfitting
    verdict (out-of-sample, deflated Sharpe, multiple-comparison, crash stress); a run that
    fails the gate is returned REJECTED with reasons rather than hidden.

    Args:
        strategy_id: a registered strategy, e.g. 'buy_and_hold' or 'cross_sectional_momentum'.
        start / end: the測試期間 (YYYY-MM-DD). `end` must not be after `as_of`.
        as_of: the knowledge cutoff. REQUIRED — there is no "today" default.
        tickers: required when universe_kind='explicit'; ignored for 'point_in_time'.
        universe_kind: 'point_in_time' (survivorship-safe, resolved from listing/delisting
            dates at each rebalance) or 'explicit' (a list you supplied).
        market: optional market filter for a point-in-time universe.
        rebalance: 'daily' | 'weekly' | 'monthly'.
        cost_bps: one-way transaction cost in basis points.
        params: strategy parameters, e.g. {'lookback_days': 60, 'top_k': 5}.
        wait_seconds: how long this call may wait for a FAST run to finish before answering
            `queued`/`running` (0 = answer at once; capped at 10). It never waits for a slow run.
        costs: the trading costs to simulate, e.g. {"model": "tw_default_model"} (standard:
            0.1425% commission both sides + 0.3% securities tax on sells + slippage),
            {"model": "tw_default_model", "fee_discount": 0.28} (a 2.8-fold broker discount on
            the commission; the tax is statutory and cannot be discounted), or {"model": "none"}
            (commission and tax zeroed — the result is flagged as not a real-world result).
            Omit for standard. Do not combine with cost_bps. The response's `costs` says exactly
            what was applied.

    Strategies served by the Zipline engine are limited to a 3-year window per interactive
    request (`error: "window_exceeds_interactive_cap"`, with a suggested window). Full-period
    results for the strategy-library strategies are precomputed nightly on the marketplace.

    This measures history. It is not advice and it places no orders.
    

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
endYes
as_ofYes
costsNo
labelNo
startYes
marketNo
paramsNo
tickersNo
cost_bpsNo
rebalanceNomonthly
strategy_idYes
wait_secondsNo
universe_kindNopoint_in_time

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
cagrNo
hintNo
specNo
as_ofNo
costsNo
errorNo
queueNo
engineNo
periodNo
reasonNo
run_idNo
sharpeNo
statusNo
blockedNo
metricsNo
acceptedNo
turnoverNo
warningsNo
cache_hitNo
citationsNo
data_gapsNo
poll_withNo
query_idsNo
job_statusNo
gate_passedNo
bundle_trustNo
equity_curveNo
max_drawdownNo
bundle_versionNo
engine_versionNo
queue_positionNo
interactive_capNo
running_secondsNo
anti_overfittingNo
estimate_secondsNo
known_strategiesNo
marketplace_cardNo
equity_curve_baseNo
persistence_errorNo
rejection_reasonsNo
run_id_resolvableNo
survivorship_safeNo
citations_persistedNo
not_investment_adviceNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • addedInput schema / properties / costs
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Costs"
      +}
    • addedOutput schema / properties / costs
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Costs"
      +}
    • addedOutput schema / properties / interactive_cap
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Interactive Cap"
      +}
    • addedOutput schema / properties / marketplace_card
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Marketplace Card"
      +}
  2. Changed17 schema fields changed
    • addedInput schema / properties / wait_seconds
      Added value: +{
      +  "default": 3,
      +  "title": "Wait Seconds",
      +  "type": "number"
      +}
    • addedOutput schema / properties / bundle_trust
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Bundle Trust"
      +}
    • addedOutput schema / properties / bundle_version
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Bundle Version"
      +}
    • addedOutput schema / properties / cache_hit
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Cache Hit"
      +}
    • addedOutput schema / properties / data_gaps
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Data Gaps"
      +}
    • addedOutput schema / properties / engine
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Engine"
      +}
    • addedOutput schema / properties / engine_version
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Engine Version"
      +}
    • addedOutput schema / properties / equity_curve
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "items": {},
      +        "type": "array"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Equity Curve"
      +}
    • addedOutput schema / properties / equity_curve_base
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "number"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Equity Curve Base"
      +}
    • addedOutput schema / properties / estimate_seconds
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Estimate Seconds"
      +}
    • addedOutput schema / properties / job_status
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Job Status"
      +}
    • addedOutput schema / properties / metrics
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Metrics"
      +}
    • addedOutput schema / properties / poll_with
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Poll With"
      +}
    • addedOutput schema / properties / queue
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Queue"
      +}
    • addedOutput schema / properties / queue_position
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Queue Position"
      +}
    • addedOutput schema / properties / running_seconds
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Running Seconds"
      +}
    • addedOutput schema / properties / spec
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Spec"
      +}
  3. Changed1 schema field changed
    • addedOutput schema / properties / citations_persisted
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Citations Persisted"
      +}
  4. Changed2 schema fields changed
    • addedOutput schema / properties / persistence_error
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Persistence Error"
      +}
    • addedOutput schema / properties / run_id_resolvable
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Run Id Resolvable"
      +}
  5. Added

TDQS

A4.8/5.0
Behavior5/5

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

The description goes far beyond the annotations: it explains jobs can be 'cached' or 'done', that re-submitting the same spec is free and never computes twice, that as_of is structurally enforced, that failed gates return REJECTED rather than being hidden, and that it places no orders. It also discloses cost model caveats, such as zero-cost runs being flagged as not real-world. This is rich, honest behavior disclosure.

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 structured with clear headings and front-loaded key behavior ('NON-BLOCKING', 'return a run_id'). Every sentence adds value: control flow, idempotency, data visibility, parameter semantics, cost examples, interactive limits, and a safety disclaimer. The length is justified by the 13-parameter, asynchronous, safety-sensitive nature of the tool.

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—13 parameters, async job lifecycle, cost simulation options, and engine-specific limits—the description is complete. It covers lifecycle states, error behavior (window_exceeds_interactive_cap), result contents (query_ids, anti-overfitting verdict), and important constraints. Since an output schema exists, not detailing return values is acceptable. 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.

Parameters5/5

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

With 0% schema description coverage, the description compensates excellently. It gives meaningful semantics for strategy_id, start/end, as_of, tickers, universe_kind, market, rebalance, cost_bps, params, wait_seconds, and costs, including concrete examples and constraints like 'do not combine with cost_bps.' The only minor omission is 'label', but it is a self-explanatory optional field and the overall coverage is outstanding.

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 verb+resource: 'Submit a point-in-time backtest.' It immediately clarifies the non-blocking behavior (returns a run_id) and differentiates itself from get_backtest by explicitly telling the agent to poll that sibling. This is unambiguous and leaves no doubt about what the tool does.

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

Usage Guidelines4/5

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

The description clearly establishes when to use this tool: to submit a backtest when you need point-in-time, survivorship-safe analysis, and it explicitly names get_backtest as the polling counterpart. It also provides important conditions around wait_seconds and interactive window caps Oscar. However, it does not explicitly contrast with other siblings like replay_backtest or run_research, so it lacks a full when-not-to-use comparison.

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