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' | 'quarterly'.
        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
fillsNo
queueNo
engineNo
periodNo
reasonNo
run_idNo
sharpeNo
statusNo
tradesNo
blockedNo
metricsNo
acceptedNo
turnoverNo
warningsNo
cache_hitNo
citationsNo
data_gapsNo
poll_withNo
query_idsNo
job_statusNo
lot_methodNo
gate_passedNo
trade_countNo
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
trade_detail_reasonNo
trade_detail_statusNo
not_investment_adviceNo
trade_detail_persistedNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • addedOutput schema / properties / fills
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "additionalProperties": true,
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Fills"
      +}
    • addedOutput schema / properties / lot_method
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Lot Method"
      +}
    • addedOutput schema / properties / trade_count
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Trade Count"
      +}
    • addedOutput schema / properties / trade_detail_persisted
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Trade Detail Persisted"
      +}
    • addedOutput schema / properties / trade_detail_reason
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Trade Detail Reason"
      +}
    • addedOutput schema / properties / trade_detail_status
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Trade Detail Status"
      +}
    • addedOutput schema / properties / trades
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "additionalProperties": true,
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Trades"
      +}
  2. 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"
      +}
  3. 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"
      +}
  4. Changed1 schema field changed
    • addedOutput schema / properties / citations_persisted
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "boolean"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "title": "Citations Persisted"
      +}
  5. 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"
      +}
  6. Added

TDQS

A4.9/5.0
Behavior5/5

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

Annotations cover safety (readOnlyHint=false, idempotentHint=true) but the description adds substantial behavior beyond them: idempotency rationale ("same spec always has the same run_id, so re-submitting is free"), point-in-time enforcement being structural, the anti-overfitting gate that can return REJECTED, and the exact cost model semantics. This is far more than the annotations convey.

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 the submit-and-poll model, then organized into statuses, constraints, and an Args block — every section earns its place. It is long (the Args block restates nearly all 13 parameters), and a stray non-English fragment ("the測試期間") is a small quality blemish, but sizing is justified by the 0% schema coverage.

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 13-parameter asynchronous tool, the description covers the submit/poll lifecycle, all failure modes (failed, REJECTED, window_exceeds_interactive_cap), cost-model caveats, and the no-advice/no-orders disclaimer. An output schema exists, so it correctly omits return-value documentation.

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 description coverage is 0%, so the description must carry all parameter meaning — and it does, documenting strategy_id, start/end/as_of, tickers (with its universe_kind conditionality), universe_kind, market, rebalance enum values, cost_bps, params, wait_seconds behavior, and three concrete `costs` shapes. Only `label` goes undocumented, a minor gap against otherwise near-total compensation.

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: "Submit a point-in-time backtest," and immediately frames it as asynchronous ("NON-BLOCKING: returns a run_id at once; poll get_backtest"). It explicitly names and routes to the sibling get_backtest, so an agent can distinguish submission from retrieval 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 when-to-use routing via the job_status states (cached / done / queued / running) and names the follow-up call (get_backtest(run_id) until done or failed). It also states constraints an agent must respect: the 3-year interactive window cap with the exact error code, and that full-period results are precomputed on the marketplace.

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