Backtest360

com.backtest360Published by backtest360.comOfficial publisherv0.5.0Updated Oct 24, 2026

MCP server exposing the Backtest360 engine API as tools for AI agents.

VerifiedStreamable HTTPWeb executableFinanceData & Analytics

Overview

AI-generated overview

Backtest360 exposes the Backtest360 engine API so an assistant can discover indicators, build and validate trading strategies, run historical backtests, and get

What you can do
Discover engine references: catalogs, indicators, strategy templates, strategy schema, and key permissions and limits. Build and check strategies: validate a strategy document without running it. Run and compare backtests, evaluate the latest bar signal, and compute performance metrics from an external returns series. Export a multi-strategy comparison as an Excel workbook. Look up assets and market data: search or list tickers, ticker info, data ranges, latest quotes, and OHLCV price history. Browse and fetch macroeconomic series.
When to use it
Use it when you want to explore, validate, and backtest trading strategies conversationally against a deterministic engine, or pull quotes, price history, and macro data for analysis. It suits research and strategy iteration rather than live trading.
Requirements
A Backtest360 API key, sent as the X-API-Key header to the hosted endpoint or set as BACKTEST360_API_KEY for the local stdio package (Python 3.10+). Network access to the engine. Some tools (quotes, price history, data ranges) need a paid plan; the free tier runs backtests on data you upload.
Before you install
The API key is a secret; keep it out of shared config files where possible. Backtest runs, comparisons, and exports are quota-counted and compute-bound, and paid-plan tools depend on your plan. Export writes an Excel file. Results are historical analysis, not investment advice.

Installation

In SourceWeft

  1. Open Backtest360 in the dashboard and add it to a workspace.
  2. Connect X-API-Key credentials. They are stored privately and never shown on public pages.
  3. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/com.backtest360%2Fbacktest360/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "backtest360": {
      "type": "http",
      "url": "https://mcp.backtest360.com/mcp",
      "headers": {
        "X-API-Key": "<YOUR_API_KEY>"
      }
    }
  }
}

README

backtest360-mcp

[PyPI version] [Python versions] [License: MIT] [tests]

MCP server exposing the Backtest360 engine API as tools for AI agents.

Connect any MCP-capable AI client and drive real backtests conversationally: discover indicators, build and validate strategies, run backtests, and read the results — all against the deterministic Backtest360 engine. The server contains no AI and computes no numbers of its own; it is a thin, faithful adapter over the engine HTTP API. Your engine API key and its plan govern everything (permissions, rate limits, data access).

Two transports: a hosted HTTP endpoint at https://mcp.backtest360.com/mcp (send your key as an X-API-Key header) and local stdio (self-host — see below).

Install

bash
pip install backtest360-mcp        # or, from a clone: pip install -e .

Requires Python 3.10+ and a Backtest360 API key. Get one free, instantly at backtest360.com/api-access — submit your email and a key (format b360_…) is issued on the spot and emailed to you; no approval needed. Authentication is API-key only. The free tier runs backtests on data you upload; fetching historical price data from the engine server-side is a paid capability.

Configuration

Everything is environment-driven:

VariableRequiredDefaultPurpose
BACKTEST360_API_KEYyes—Engine API key, sent as X-API-Key
BACKTEST360_ENGINE_URLnohttps://api.backtest360.comEngine base URL
BACKTEST360_MCP_TIMEOUTno300Per-request timeout (seconds)
BACKTEST360_MCP_MAX_OUTPUT_BYTESno100000Hard cap on a single tool result

Connect an MCP client

Hosted (recommended)

Point your MCP client at the hosted endpoint over HTTP and send your key as an X-API-Key header:

json
{  "mcpServers": {    "backtest360": {      "type": "streamable-http",      "url": "https://mcp.backtest360.com/mcp",      "headers": {        "X-API-Key": "b360_..."      }    }  }}

Local (stdio)

Run the server yourself and let your client launch it over stdio (the common mcpServers shape):

json
{  "mcpServers": {    "backtest360": {      "command": "backtest360-mcp",      "env": {        "BACKTEST360_API_KEY": "b360_..."      }    }  }}

Prefer not to put the key in a config file? Point command at a small wrapper script that exports the key from your secrets manager and then runs backtest360-mcp. A minimal example config is in examples/mcp.json.

Tools

ToolWhat it does
engine_infoEngine version, API contract, health
get_meWhat the configured key can do: permission scopes, limits, current usage, capability flags
get_catalogReference catalogs: operators, execution modes, stop types, sizing methods, bar frequencies, metric sections
list_indicatorsIndicator discovery; per-indicator parameter schemas
list_templatesPredesigned strategy templates — discover compactly, fetch one in full, ready to validate and run
get_strategy_schemaJSON Schema for strategy documents
validate_strategyValidate a strategy without running it — returns structured, locatable errors
run_backtestRun a historical backtest
get_latest_signalEvaluate the most recent bar only (no P&L)
compare_backtestsRun several strategies on the same data, side by side
compute_statsCompute the metric set from an externally produced returns series
search_tickers / list_tickersAsset discovery for server-side data fetch
get_data_rangeAvailable history and bar-count estimate for a symbol
get_ticker_infoSymbol identity and data coverage in a single call
get_quoteLatest available price for a symbol (paid plan)
get_price_historyOHLCV price history over a date range (paid plan; long histories downsampled to fit)
list_macro_series / get_macro_seriesMacroeconomic data: list the series catalog, then fetch one series' observations

The cheap static catalogs are also published as MCP resources (backtest360://catalog/{name}, backtest360://schema/strategy) for clients that support resource attachment.

Prompts

Two workflow prompts scaffold the common multi-tool flows for a connected AI: each names which tools to call, in what order, and what to look at in the results. They carry no interpretation and compute nothing — the connected AI does the reasoning.

PromptArgumentsWhat it scaffolds
robustness_reviewsymbol, strategy (optional)Review a backtested strategy for robustness: validate → run → compare against buy-and-hold → weigh the evidence base (sample size, significance/robustness statistics, warnings) → caveated summary
build_and_validateideaTurn a plain-language idea into a validated strategy: survey the catalogs → fetch the schema → construct → validate-and-fix loop → dry-run

Response shaping

A full backtest result is megabytes; an agent's context is not. run_backtest and compare_backtests take response_detail:

  • summary (default) — headline metrics, warnings, counts, equity endpoints
  • stats — every metric the plan allows
  • full — plus series (downsampled, endpoints preserved) and trades (paginated)

run_backtest also takes max_series_points (default 500, must be >= 2) to override the series downsampling cap — set it higher for full-resolution series on a long run, or leave it unset for today's default.

include=["trades", "equity_curve", "monthly_returns", "yearly_returns", "signal_diagnostics"] adds specific blocks at any detail level. signal_diagnostics reports which per-bar entry/exit conditions fired, as a capped list of fire dates per condition (not the raw per-bar boolean arrays, which downsampling would corrupt) — or {"available": false, ...} when the run has no condition tree to evaluate (e.g. precomputed signals). Results exceeding the output cap are reduced further and explicitly marked truncated_by_mcp — never silently cut. Shaping only ever selects and thins what the engine returned; no value is computed or altered.

Error semantics

Designed for agents:

  • Fixable by changing the request → returned as a normal result: failed validations arrive as {"valid": false, "errors": [...]} with machine codes and document locations; engine rejections arrive as {"accepted": false, "error": ...} with a hint.
  • Not fixable that way → a tool error with explicit guidance: rate limits carry the Retry-After value; engine-busy says retry with backoff; a compute timeout says do not retry and reduce scope instead; permission problems name the missing capability. Engine request ids are included for support.

Running the tests (self-host)

bash
pip install -e ".[dev]"pytest   # unit suite vs a mock engine — no network

Questions / feedback

Questions or feedback? [email protected] — we read everything. backtest360-mcp is in active development, so help shape it.

Bug reports and feature requests: open an issue on GitHub.

License

MIT — see LICENSE.

Source: README.md at commit d332a0d

Tools

20

get_me

The configured API key's permissions, limits, and current usage. Cheap. Call early in a session — before planning work — to learn what this key can do instead of discovering limits through failed calls. Returns: ``scopes``: the permission scopes the key carries. ``limits``: requests per minute and per day, max concurrent requests, and the per-run bar cap (null when uncapped). ``usage``: current consumption against those limits, with reset countdowns in seconds. ``capabilities``: feature flags such as server-side data fetch and the full metric set. A small fixed-shape record, returned as the engine sent it.

Takes no parameters.

engine_info

Engine version, API contract number, and health. Free (not quota-counted). Call once at the start of a session to confirm the engine is reachable and which contract it serves.

Takes no parameters.

get_catalog

Fetch one engine reference catalog. Catalogs (cheap, cacheable per session): - 'operators' — comparison operators for condition expressions - 'execution-modes' — entry/exit anchors and fill algorithms, with the validity matrix by market type - 'stop-types' — stop-loss types, re-entry modes, and their parameters - 'sizing-methods' — position-sizing methods and their parameters - 'bar-frequencies' — supported bar frequencies and the signal x execution validity matrix (which combinations are allowed) - 'sections' — the full metric catalog: every statistic's stable id, display label, section, and description - 'sampling-modes' — Monte-Carlo resampling modes, each with its status and parameters Fetch the relevant catalog BEFORE building a strategy or config; build only from values it lists — never guess parameter names or frequencies.

Parameterscatalogrequired

list_indicators

List indicators, or fetch one indicator's full schema. Cheap, cacheable per session. With no arguments: a compact catalog — ``{"indicators": [...], "count": N}`` — where each entry carries id, name, category, kind, and value_dtype (no description, to keep the discovery scan small). Use it to discover what exists. Pass name='rsi' (id or name, case-insensitive) to get that single indicator's complete entry including its description and params_schema — do this before adding an indicator to a strategy so its parameters are exactly right. Pass compact=False for full entries for everything (large; the MCP server may cap it and set ``truncated_by_mcp`` — prefer compact or name=). Wire optimization: the compact discovery path asks the engine to omit per-entry descriptions (``descriptions=false``) since they are stripped locally anyway; the name= and compact=False paths request them. This is a pure saving — if the engine ignores the param it returns full entries and the local compact strip still yields a lean result.

Parametersnamecompact

list_templates

List predesigned strategy templates, or fetch one in full. Cheap, cacheable per session. The engine returns the templates available to the calling key. With no arguments: a compact catalog — ``{"templates": [...], "count": N}`` — where each entry carries id, origin, name, and description. Use it to discover what exists. Pass name='sma-cross' (id or name, case-insensitive) to get that single template's complete entry: its strategy logic (``condition_tree`` + ``indicators``, the same shape validate_strategy and run_backtest accept) plus parameter metadata — ``defaults`` (starting parameter values), ``requires``, and ``locked_params`` (parameters that must keep their template values). Pass compact=False for complete entries for everything (large; the MCP server may cap it and set ``truncated_by_mcp`` — prefer compact or name=).

Parametersnamecompact

get_strategy_schema

JSON Schema for the strategy document (condition_tree + indicators). Fetch this before composing a strategy by hand; the validate_strategy tool checks against the same rules.

Takes no parameters.

validate_strategy

Validate a strategy document without running a backtest. A cheap quota separate from backtest runs, so validate freely and ALWAYS before run_backtest. Args: strategy: The strategy document — name, indicators[], and condition_tree (see get_strategy_schema for the exact shape). injected_indicators: Names of custom time-series columns the caller will supply via data_inputs at run time, so conditions referencing them validate. Returns: On success: {"valid": true, "warmup_bars": ..., referenced indicators/columns}. On failure: {"valid": false, "errors": [...]} where each error carries a machine code, the location in the document, a message, and context (e.g. the list of valid column names). A failed validation is a NORMAL result, not an error — read the errors, fix the document, and validate again before running.

Parametersstrategyrequiredinjected_indicators

run_backtest

Run a historical backtest against the engine. Quota-counted and compute-bound. Validate the strategy first (validate_strategy is far cheaper). On a 504 compute timeout, do NOT retry the same request — reduce the date range, use a coarser frequency, or simplify the strategy. On 429/503, wait for the advertised Retry-After before retrying. Args: data_source: Either inline OHLCV ({"ohlcv": {dates, open, high, low, close, volume?}} as parallel arrays, ISO-8601 dates) or a server-side fetch ({"symbol", "start", "end", "frequency"} — requires a paid plan). strategy: Strategy document (indicators[] + condition_tree). Mutually exclusive with signals. signals: Precomputed signal series ({"dates": [...], "values": [-1|0|1, ...]}). Mutually exclusive with strategy. execution: Execution/cost/risk/sizing settings. Use values from get_catalog('execution-modes'/'stop-types'/'sizing-methods'); omit for engine defaults. benchmark: Optional benchmark data source (same shape as data_source) — when given, the result also carries benchmark-relative metrics (beta, alpha, information ratio, tracking error, up/down capture) and bar-alignment info. data_inputs: Optional custom time-series the strategy references (name -> {dates, values}). response_detail: 'summary' (default — headline metrics, smallest), 'stats' (every metric), 'full' (plus trades and series downsampled to a fixed, server-controlled number of points). include: Optional add-on blocks at any detail level: 'trades', 'equity_curve', 'monthly_returns', 'yearly_returns', 'signal_diagnostics' (which per-bar entry/exit conditions fired,

Parametersincludesignalsstrategybenchmarkexecutiondata_inputsdata_sourcerequiredtrades_limitresponse_detail

get_latest_signal

Evaluate the strategy on the most recent bar only — no P&L, no stats. Returns the latest signal (-1/0/1), which condition slots fired, and the bar timestamp. Use for "what would this strategy do right now" questions; use run_backtest for performance.

Parametersstrategyrequiredexecutiondata_inputsdata_sourcerequired

compare_backtests

Run several strategies on the same data and compare side by side. One quota-counted call, but compute scales with the number of strategies. If the wall-clock compute budget is exceeded, the call fails with a tool error (504) instead of returning partial results — narrow the request (fewer strategies, shorter date range, coarser frequency) and retry. Args: data_source: Shared data source (same shape as run_backtest). strategies: List of {"label": str, "strategy": {...}, "execution": {...}?} entries. Labels need not be unique or id-safe — they are echoed back verbatim in the result. include_benchmark: Add a buy-and-hold benchmark to the comparison. response_detail: Shaping level applied to each strategy's result. trades_limit: Max trades per strategy when detail is 'full'. Returns: {"strategies": [{"label", "result"}, ...], "equity_curves": {...}, "alignment"?}, each result shaped at the requested detail. When a benchmark is included, non-benchmark entries also carry "relative" (beta, alpha, information ratio, etc.). A 400/422 rejection returns {"accepted": false, "error": ...}; capacity/timeout/permission failures raise a tool error.

Parametersstrategiesrequireddata_sourcerequiredtrades_limitresponse_detailinclude_benchmark

export_backtest

Export a multi-strategy comparison as an Excel workbook. Quota-counted; needs a key whose plan includes full-metrics export (a 403 means the configured key's plan does not — do not retry). Returns the workbook base64-encoded — decode and write it to a ``.xlsx`` file. Args: data_source: Shared data source (same shape as run_backtest). strategies: Same shape as compare_backtests' ``strategies``. include_benchmark: Add a buy-and-hold benchmark to the export. Returns: {"filename", "content_type", "size_bytes", "content_base64"}. A 400/422 rejection returns {"accepted": false, "error": ...}; capacity/timeout/permission failures raise a tool error. If the encoded workbook would exceed the output size limit, raises a tool error — narrow the request (shorter date range, fewer strategies, coarser frequency) and retry.

Parametersstrategiesrequireddata_sourcerequiredinclude_benchmark

compute_stats

Compute the engine's performance metrics from a returns series. Use when the returns came from somewhere other than run_backtest (an external system, a portfolio) — backtest results already include these statistics. Args: returns: Per-bar log returns as {"dates": [...], "values": [...]} parallel arrays (ISO-8601 dates). trading_days_per_year: Required annualization factor — 252 for a daily equities calendar, 365 for 24/7 crypto. Must match the bar calendar of the returns series; a wrong value silently mis-annualizes Sharpe, volatility, and CAGR. benchmark_returns: Optional benchmark series, same shape — adds alpha/beta/capture metrics. trades: Optional trade records (entry_date, exit_date, direction, return_net, ...) — adds trade-level metrics. risk_free_rate: Annual risk-free rate as a decimal. Returns: {"stats": {...}} — the metric set the API key's plan allows. See get_catalog('sections') for every metric's id and description.

Parameterstradesreturnsrequiredrisk_free_ratebenchmark_returnstrading_days_per_yearrequired

search_tickers

Search available assets by ticker or name (relevance-ranked). Use to resolve a user's asset mention ("bitcoin", "S&P") to the exact ticker before requesting a server-side data fetch. asset_class filters to 'stocks', 'crypto', 'forex', or 'indices'.

Parameterslimitqueryrequiredasset_class

list_tickers

List available tickers, optionally filtered by asset class. The full universe is very large, so the MCP server caps the returned list and marks it ``truncated_by_mcp`` — pass asset_class to narrow it, or use search_tickers to resolve a specific asset by name.

Parametersasset_class

get_data_range

Available date range and estimated bar count for a symbol/frequency. Available on paid plans. Call before a server-side fetch so the requested start/end stay inside what the provider can deliver and the bar count stays inside the key's per-run limit.

Parameterssymbolrequiredfrequencyrequired

get_ticker_info

Identity and data coverage for one symbol, in a single call. Metadata only — no market data, so no paid plan is needed. Returns the asset's identity (name, asset class, exchange, currency, and whether it is still active) together with a coverage summary for the given frequency: the available date range and an estimated bar count. Use it to confirm a symbol resolves and that the history you need exists before requesting a quote or a price fetch. For the precise per-frequency range use get_data_range.

Parameterssymbolrequiredfrequency

get_quote

Latest available price for a symbol. Requires a paid plan (managed market data). Returns the most recent *available* bar for the given frequency — the end-of-day close for daily, the last completed bar otherwise — as open/high/low/close/volume plus an ``as_of`` timestamp for that bar. This is a last-known price, not a live tick; read ``as_of`` to judge how stale it is.

Parameterssymbolrequiredfrequency

get_price_history

OHLCV price history for a symbol over a date range. Requires a paid plan (managed market data). ``start`` is required (``YYYY-MM-DD``); ``end`` defaults to today. Returns a summary (symbol, resolved date range, total bar count, price range, gap flags), market-hours detection, and the OHLCV arrays. A long history is downsampled by the MCP server to a bounded number of points — first and last bar always kept, every column thinned on the same dates — with ``downsampled_from_bars`` and ``points_returned`` recorded on the ``ohlcv`` block; the untouched ``summary.total_bars`` still reports the true bar count. The window is bounded by the plan's per-request bar cap — call get_data_range first to size a request.

Parametersendstartrequiredsymbolrequiredfrequency

list_macro_series

List the available macroeconomic series (the catalog). Free — no special plan. Returns the set of macro series you can fetch with get_macro_series, each with its stable ``id`` (the value get_macro_series takes), title, category, native reporting frequency, and units, plus the list of categories. Optionally filter to one ``category`` (e.g. rates, yield_curve, inflation, employment, recession, growth). Call this first to find the ``id`` for the series you want.

Parameterscategory

get_macro_series

Observations for one macroeconomic series over an optional date range. Free — no special plan. ``series`` is an ``id`` from list_macro_series (e.g. treasury_10y, cpi, unemployment_rate); arbitrary external ids are not accepted. ``start``/``end`` are ``YYYY-MM-DD``, inclusive, both optional (full history when omitted). Returns the value series at its native reporting frequency, with the series descriptor and an ``as_of`` date. A long history is downsampled by the MCP server to a bounded number of points (first and last kept), marked with ``downsampled_from_bars`` and ``points_returned`` on the ``observations`` block. Note: values are the latest revised figures stamped by reference period, not point-in-time as-first-reported data — do not treat them as the values that were known at a past date.

Parametersendstartseriesrequired

Version history

1
  1. v0.5.0LatestSep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts