Give this to your AI agent to get started

Copy this into ChatGPT, Claude, Meta Muse, Gemini or any AI agent. It connects to our AI agent, Nexus to get you started.

What can I do with Backtest API Docs at cymetica.com/backtest/api?
EventTrader
AI-Native Money
PAPER
Menu
Dark Mode
Plain English Mode
PAPER TRADING MODE — Enable real trading on your Account page
Back
REST + WebSocket + MCP

Backtest API & SDK

Run strategy backtests, browse the bot leaderboard, clone bots, and paper trade — all via API.

11
API Endpoints
3
Strategy Types
20
Max Concurrent
WS
Real-Time Stream

Quick Start

# Run a funding rate backtest
curl -X POST https://cymetica.com/api/v1/backtest-labs/run \
  -H "Content-Type: application/json" \
  -d '{"type":"funding_rate","params":{"coin":"BTC","days":30,"capital":10000,"leverage":1,"strategy":"cross_exchange"}}'

# Get bot leaderboard
curl https://cymetica.com/api/v1/backtest/leaderboard?sort=return&limit=10
from event_trader import EventTrader

client = EventTrader(api_key="evt_...")

# Run a backtest
result = await client.backtest.run_lab(
    type="funding_rate",
    params={"coin": "BTC", "days": 30, "capital": 10000}
)

# Get leaderboard
leaderboard = await client.backtest.leaderboard(sort="return", limit=10)

# Get bot profile
bot = await client.backtest.bot("cryptobull-blue")

The JS/TS SDK's npm release is in progress — these snippets show the interface it ships with. The Python SDK and the REST API are live today.

import { EventTrader } from "cymetica-eventtrader";

const client = new EventTrader({ apiKey: "evt_..." });

// Run a backtest
const result = await client.backtest.runLab({
  type: "funding_rate",
  params: { coin: "BTC", days: 30, capital: 10000 }
});

// Get leaderboard
const leaderboard = await client.backtest.leaderboard({ sort: "return", limit: 10 });

// Get bot profile
const bot = await client.backtest.bot("cryptobull-blue");
# Python
pip install cymetica-eventtrader

# TypeScript / Node.js — npm release in progress; Python SDK is live today
# npm install cymetica-eventtrader

Authentication

Most read endpoints are public (no auth required). Write operations use one of two methods depending on the endpoint family: Backtest Labs runs (/api/v1/backtest-labs/*) authenticate with an API key (X-API-Key header), while bot management (clone, trigger run, update settings) requires a Bearer token from a logged-in session.

# Authenticated request
curl -H "Authorization: Bearer $EVENTTRADER_API_KEY" \
  https://cymetica.com/api/v1/backtest/bots/your-bot-slug/run-backtest

Get your API key from /account → API Keys.

Which backtest surface?

Five surfaces, all current, each answering a different question. None supersedes another. The machine-readable spec of record is openapi-public.json, llms.txt and the MCP tools list_backtest_surfaces / get_backtest_models; this page mirrors them.

PageAnswersAPIAuth
/backtestHow has a specific clone-able bot performed, and can I clone it?GET /api/v1/backtest/bots/{slug}, /equity, /trades, GET /api/v1/backtest/leaderboard, POST /api/v1/backtest/clonereads: none · writes: Bearer
/backtest-labsWhat would one parameterised strategy have returned on one asset?POST /api/v1/backtest-labs/run — type: cross_exchange_arb | funding_rate | dex_replayX-API-Key
/backtest-rallyWhich theme basket beat BTC under a research model, then launch it as a rally card?GET /api/v1/research-backtest/models, /themes, POST /api/v1/research-backtest/run, GET /runs, /runs/{run_id}, /queue, /leaderboardnone (30/min per IP; 2 in-flight runs per anonymous IP, 5 per account)
/events/builderWould an event-card idea have paid off historically?POST /api/v1/event-cards/backtest-ideanone (30/min per IP)
/macromarketBuild an AI Index Basket from a macro theme, backtest and paper-trade it.POST /api/v1/macromarket/build, /backtest, /paper-tradeBearer

Backtest Labs

Run one parameterised strategy on one asset. Accepted type values: cross_exchange_arb (cross-exchange arbitrage), funding_rate (perp funding-rate capture) and dex_replay (DEX trade replay with params.strategy = mean_reversion | momentum | lp_vs_hold). Any other type returns {"error":"Unknown backtest type. Supported: cross_exchange_arb, funding_rate, dex_replay"}. Max 20 concurrent backtests via Redis queue.

POST /api/v1/backtest-labs/run Run a strategy backtest

Request Body

typestringStrategy type: cross_exchange_arb, funding_rate, dex_replay (for dex_replay, params.strategy = mean_reversion | momentum | lp_vs_hold)
params.coinstringAsset symbol (BTC, ETH, SOL, etc.)
params.daysintegerLookback period in days
params.capitalnumberStarting capital in USDC
params.leveragenumberLeverage multiplier
params.strategystringStrategy variant (e.g., cross_exchange)
curl -X POST https://cymetica.com/api/v1/backtest-labs/run \
  -H "Content-Type: application/json" \
  -d '{
    "type": "funding_rate",
    "params": {
      "coin": "BTC",
      "days": 30,
      "capital": 10000,
      "leverage": 1,
      "strategy": "cross_exchange"
    }
  }'
result = await client.backtest.run_lab(
    type="funding_rate",
    params={"coin": "BTC", "days": 30, "capital": 10000, "leverage": 1, "strategy": "cross_exchange"}
)
const result = await client.backtest.runLab({
  type: "funding_rate",
  params: { coin: "BTC", days: 30, capital: 10000, leverage: 1, strategy: "cross_exchange" }
});

Multi-Leg Backtesting — Baskets, AIBs and Themes

Backtest Labs above runs a strategy against one asset. To backtest a basket — several legs with weights — use the endpoints below. Basket symbols (AIB-, TREND-, EVCDX-, RALLY-, MM-) are not accepted by the single-asset endpoints. All results describe the past and are never a predicted return.

POST /api/v1/event-cards/backtest-idea Backtest a basket you define (no auth)

The API behind the “Backtest this idea” widget on /events/builder. Read-only: no card is created, no ledger or on-chain write happens, no money moves. Runs the same engine as the saved-card backtest, so an idea and a published card holding the same basket return identical numbers.

Request Body

constituentsarray2–20 legs of {symbol, weight} (optional coingecko_id). Weights are relative and renormalized, so 50/30/20 equals 5/3/2.
period_daysintegerOne of 7, 30, 90, 180, 365. Anything else returns 422.
starting_capitalnumberNotional to simulate. 0 < x ≤ 1,000,000.
fee_ratenumberPer-trade fee, 0–0.1 (0.001 = 10bps). Optional.
slippage_bpsnumberSlippage in basis points, 0–500. Optional.

Response

total_return_pctnumberReturn over the window, in percent.
sharpe_rationumberRisk-adjusted return.
max_drawdown_pctnumberDeepest peak-to-trough decline.
starting_capital_usdc
ending_capital_usdc
numberSimulated capital at each end of the window.
equity_curvearrayCurve points (count in n_points).
unresolved_symbols
dropped_symbols
arrayLegs that could not be priced and were excluded. Always check these before trusting the numbers.
curl -X POST https://cymetica.com/api/v1/event-cards/backtest-idea \
  -H "Content-Type: application/json" \
  -d '{
    "constituents": [
      {"symbol": "BTC", "weight": 50},
      {"symbol": "ETH", "weight": 30},
      {"symbol": "SOL", "weight": 20}
    ],
    "period_days": 90,
    "starting_capital": 10000
  }'
result = await client.basket_backtest.run(
    constituents=[("BTC", 50), ("ETH", 30), ("SOL", 20)],
    period_days=90,
    starting_capital=10_000,
)
print(result["total_return_pct"], result["sharpe_ratio"])
print(result["unresolved_symbols"], result["dropped_symbols"])
const result = await client.basketBacktest.run({
  constituents: [
    { symbol: "BTC", weight: 50 },
    { symbol: "ETH", weight: 30 },
    { symbol: "SOL", weight: 20 },
  ],
  periodDays: 90,
  startingCapital: 10000,
});
console.log(result.total_return_pct, result.sharpe_ratio);
et_basket_backtest(
  constituents=[
    {"symbol": "BTC", "weight": 50},
    {"symbol": "ETH", "weight": 30},
    {"symbol": "SOL", "weight": 20}
  ],
  period_days=90,
  starting_capital=10000
)
POST /api/v1/macromarket/build Build an AI Index Basket from a theme

Give it a plain-language theme and the Tuatara semantic model selects real trading vehicles (stocks, ETFs, crypto) and weights them by relevance. The basket gets an MM-… symbol and a /macromarket page.

Request Body

themestringe.g. "AI infrastructure".
num_assetsintegerHow many legs to select. Default 6.
weightingstringtuatara (relevance-weighted) or equal.
asset_classesarraySubset of crypto, equity. Omit for both.
curl -X POST https://cymetica.com/api/v1/macromarket/build \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $EVENTTRADER_API_KEY" \
  -d '{"theme": "AI infrastructure", "num_assets": 8, "weighting": "tuatara"}'
aib = await client.macromarket.build("AI infrastructure", num_assets=8)
print(aib["symbol"])   # e.g. "MM-AIINFRA"
const aib = await client.macromarket.build({
  theme: "AI infrastructure",
  numAssets: 8,
});
et_aib_build(theme="AI infrastructure", num_assets=8, weighting="tuatara")
POST /api/v1/macromarket/backtest Backtest an AIB by symbol, or a theme

Pass aib_symbol for an existing basket, or theme to build and persist one first. Quota-gated: an over-quota caller gets 402 before any expensive work runs. Results are simulated, not investment advice.

Request Body

aib_symbolstringAn existing MM-… symbol. Required unless theme is given.
themestringBuild a basket from this theme, then backtest it.
period_daysintegerLookback window. Default 365.
curl -X POST https://cymetica.com/api/v1/macromarket/backtest \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $EVENTTRADER_API_KEY" \
  -d '{"aib_symbol": "MM-AIINFRA", "period_days": 365}'
bt = await client.macromarket.backtest(aib_symbol="MM-AIINFRA", period_days=365)

# Or skip the build entirely and backtest a theme directly:
bt = await client.macromarket.backtest(theme="uranium miners")
const bt = await client.macromarket.backtest({
  aibSymbol: "MM-AIINFRA",
  periodDays: 365,
});
et_aib_backtest(aib_symbol="MM-AIINFRA", period_days=365)
et_aib_backtest(theme="uranium miners")
POST /api/v1/research-backtest/run Backtest a theme or ticker list (Rally engine)

The headline-basket research engine behind /backtest-rally. Races strategies against BTC and can launch the winner as a Rally Card. Signal/backtest only — no orders are placed. Full reference: /backtest-rally/api.

curl -X POST https://cymetica.com/api/v1/research-backtest/run \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $EVENTTRADER_API_KEY" \
  -d '{"themes": ["ai tokens"], "algo_model": "aib_sentiment", "hold_days": 2}'
run = await client.research_backtest.run(
    themes=["defi tokens", "ai tokens"], hold_days=2)
result = await client.research_backtest.get(run["run_id"])
await client.research_backtest.launch_rally_card(run["run_id"], basket_index=0)
const run = await client.researchBacktest.run({
  themes: ["defi tokens", "ai tokens"],
  params: { hold_days: 2 },
});
const result = await client.researchBacktest.get(run.run_id);
et_research_backtest_run(params={"themes": ["ai tokens"], "hold_days": 2})
et_research_backtest_launch_rally_card(run_id="<run_id>", basket_index=0)

Bot Leaderboard

Browse ranked AI trading bots with sorting and filtering. 60-second cache on leaderboard results.

GET /api/v1/backtest/leaderboard Get bot leaderboard

Query Parameters

sortstringSort by: return (headline return, desc), clones, win_rate, drawdown (asc). Default: return. Unknown values fall back to return.
categorystringFilter by category: all, crypto, politics, sports, finance (default: all)
teamstringFilter by team: all, red, blue
limitintegerMax results, 1–100 (default: 20)
offsetintegerPagination offset (default: 0)
periodstringHeadline-period filter, e.g. 30d, 6m, 24h (default: all). headline_return_pct is measured over each bot's own window and is NOT comparable across periods, so rank within one. Every row carries headline_period and headline_period_hours.
curl "https://cymetica.com/api/v1/backtest/leaderboard?sort=return&team=red&period=30d&limit=10"
leaderboard = await client.backtest.leaderboard(sort="return", team="red", limit=10)
const lb = await client.backtest.leaderboard({ sort: "return", team: "red", limit: 10 });

Bot Profiles

Get bot details, equity curves, and trade history. 60-second cache on profile data.

GET /api/v1/backtest/bots/{slug} Get bot profile

Path Parameters

slugstringBot slug identifier
curl https://cymetica.com/api/v1/backtest/bots/cryptobull-blue
GET /api/v1/backtest/bots/{slug}/equity Get equity curve

Returns time-series equity data for charting the bot's portfolio value over time.

curl https://cymetica.com/api/v1/backtest/bots/cryptobull-blue/equity
GET /api/v1/backtest/bots/{slug}/trades Get trade history

Query Parameters

limitintegerMax trades (default: 50)
offsetintegerPagination offset (default: 0)
curl "https://cymetica.com/api/v1/backtest/bots/cryptobull-blue/trades?limit=10"

Bot Operations

Run backtests and update settings. These endpoints require authentication.

POST /api/v1/backtest/bots/{slug}/run-backtest Run backtest AUTH

Triggers a new backtest run for the specified bot (Bearer token; no request body — the bot's own strategy, top-10 asset universe and a 30-day window are used). Responds immediately with {"run_id", "status": "queued", "slug"}; the refreshed results appear on the bot's profile and the leaderboard when the async run completes. Also callable as the MCP tool et_backtest_bot_run.

curl -X POST https://cymetica.com/api/v1/backtest/bots/your-bot-slug/run-backtest \
  -H "Authorization: Bearer $EVENTTRADER_API_KEY"

# 200 → {"run_id": "…", "status": "queued", "slug": "your-bot-slug"}
# then stream progress on wss://cymetica.com/ws/backtest/{instance_id}?run_id={run_id}
PATCH /api/v1/backtest/bots/{slug}/settings Update bot settings AUTH

Request Body

namestringNew bot name (optional)
avatar_urlstringNew avatar URL (optional)
curl -X PATCH https://cymetica.com/api/v1/backtest/bots/your-bot-slug/settings \
  -H "Authorization: Bearer $EVENTTRADER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Alpha Bot v3"}'

Bot Cloning

Clone bot species into new instances. Cloned bots get dedicated HD wallets (account 4 derivation path). Requires authentication.

POST /api/v1/backtest/clone Clone a bot AUTH

Request Body

species_slugstringSpecies slug to clone from
namestringName for the new cloned bot
curl -X POST https://cymetica.com/api/v1/backtest/clone \
  -H "Authorization: Bearer $EVENTTRADER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"species_slug": "cryptobull-blue", "name": "My Momentum Clone"}'
GET /api/v1/backtest/clone/deposit-info/{species_slug} Get clone deposit info AUTH

Returns deposit address and minimum deposit required to activate a cloned bot.

curl https://cymetica.com/api/v1/backtest/clone/deposit-info/cryptobull-blue \
  -H "Authorization: Bearer $EVENTTRADER_API_KEY"

Paper Trading

View paper trades and paper trading status for bots running in simulation mode.

GET /api/v1/backtest/bots/{slug}/paper-trades Get paper trades

Query Parameters

statusstringFilter: open, closed, all
limitintegerMax trades (default: 50)
offsetintegerPagination offset (default: 0)
curl "https://cymetica.com/api/v1/backtest/bots/cryptobull-blue/paper-trades?status=open&limit=20"
GET /api/v1/backtest/bots/{slug}/paper-status Get paper trading status

Returns current paper trading status including P&L, open positions, and account balance.

curl https://cymetica.com/api/v1/backtest/bots/cryptobull-blue/paper-status

WebSocket — Real-Time Backtest Updates

Stream real-time backtest progress and results via WebSocket.

WS wss://cymetica.com/ws/backtest/{instance_id}?run_id={run_id} Backtest progress stream

Message Types

stateeventBacktest state change (queued, running, completed, failed)
progresseventProgress update with percentage and current step
completedeventFinal results with performance metrics
failedeventError details on failure
heartbeateventKeep-alive ping
// JavaScript WebSocket example
const ws = new WebSocket("wss://cymetica.com/ws/backtest/bot-123?run_id=run-456");
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  switch (msg.type) {
    case "progress":
      console.log(`${msg.percent}% — ${msg.step}`);
      break;
    case "completed":
      console.log("Results:", msg.results);
      break;
    case "failed":
      console.error("Error:", msg.error);
      break;
  }
};

Rate Limits

Backtest runslimitMax 20 concurrent backtests (Redis queue). Additional requests are queued.
Leaderboardcache60-second cache on leaderboard and profile data.
API callslimitStandard rate limits apply (60 req/min for authenticated, 30 req/min for public).

MCP Tools

Two MCP surfaces. The hosted server at https://cymetica.com/mcp/v1 (JSON-RPC tools/list / tools/call, no install) exposes list_backtest_surfaces, get_backtest_models and get_strategy_returns (accepts cryptobull-blue, cryptobull_blue or bt-cryptobull-blue; returns the latest run's metrics with its measurement period plus the leaderboard headline figure and its window). The installable server (pip install cymetica-eventtrader-mcp) ships the full endpoint mirror below — these et_backtest_* names come from that package.

et_backtest_runtoolRun a backtest in Backtest Labs
et_backtest_leaderboardtoolGet bot leaderboard
et_backtest_bot_profiletoolGet bot profile
et_backtest_bot_equitytoolGet bot equity curve
et_backtest_bot_tradestoolGet bot trade history
et_backtest_bot_runtoolTrigger a backtest run
et_backtest_bot_settingstoolUpdate bot settings
et_backtest_clonetoolClone a bot
et_backtest_clone_deposit_infotoolGet clone deposit info
et_backtest_paper_tradestoolGet paper trades
et_backtest_paper_statustoolGet paper trading status