MCP Tools Reference¶
This page documents every tool the TradeServer MCP server exposes on tools/list, generated from the server's own tool registry. Every tools/call is authenticated with the bearer token (API key or OAuth token) the connector was set up with.
System¶
health_check¶
Reports whether this connector can actually be used, not merely reached. Returns a structured result including the running build (version + binary timestamp, so two deploys can be told apart), transport and auth reachability, license state (valid, expired, or unreadable), and a per-capability breakdown (read, script_write, execute, labs). Check capabilities before concluding the connector is healthy - a reachable server whose license cannot be read refuses every write while staying perfectly reachable.
No parameters.
HaasScript Management¶
list_scripts¶
Returns a paginated page of HaasScript records (Lua, Visual, Command) visible to the user - their own scripts plus the public community library, so the total is large on every account regardless of how many scripts you own. Each item includes id (SID), name (SN), type, dependency info, numeric folder id (FID) and resolved folder name (FN - empty string for the root folder or when FID cannot be resolved). Response shape matches the other paginated tools: 'I' is the current page, 'NP' the next cursor (-1 when exhausted), 'total_count' the count after filtering, 'page_length' the size actually applied. Use name_filter or folder_id to narrow rather than paging through everything.
| Parameter | Type | Required | Description |
|---|---|---|---|
next_page_id |
integer | No | Pagination cursor (0 or omit for first page). |
page_length |
integer | No | Scripts per page (default 100, max 500). |
name_filter |
string | No | Case-insensitive substring match on the script name (SN). |
folder_id |
string | No | Only scripts in this folder id (FID). |
get_script¶
Returns a single full HaasScript record including source code, compile result, numeric folder id (FID) and resolved folder name (FN - empty string for the root folder or when FID cannot be resolved).
| Parameter | Type | Required | Description |
|---|---|---|---|
script_id |
string | Yes | Script ID hash |
add_script¶
Creates a new HaasScript. Returns the created HaasScriptRecord.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Script name |
description |
string | No | Script description |
script |
string | Yes | Lua source code (may be base64+gzip compressed) |
type |
string | Yes | Script type: Lua or Visual. A custom command is a Lua script that calls DefineCommand; 'Command' is accepted as an alias for Lua. |
edit_script_source¶
Replaces the source code of an existing HaasScript and recompiles it.
| Parameter | Type | Required | Description |
|---|---|---|---|
script_id |
string | Yes | Script ID hash |
source_code |
string | Yes | New Lua source code |
settings |
object | Yes | HaasScriptSettings JSON. Must include at minimum: accountId, marketTag, interval, tradeAmount, chartStyle, orderTemplate. |
compile_script¶
Compiles a HaasScript without saving it. Returns compile result including errors and discovered input fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
source_code |
string | Yes | Lua source code to compile |
script_type |
string | No | Script type: Lua (default) or Visual |
delete_script¶
Permanently deletes a HaasScript. Returns true on success.
| Parameter | Type | Required | Description |
|---|---|---|---|
script_id |
string | Yes | Script ID hash |
search_haasscript_docs¶
Searches the HaasScript command reference: ~780 built-in commands and constants (indicators, trading actions, safeties, insurances, price data, helpers, enumerations) plus the user's own custom commands. Use this BEFORE writing or editing HaasScript to verify a command exists and to get its exact signature, parameters and return type - do not guess signatures. The query is matched against command names, aliases, categories, parameter names and description text; exact and prefix name matches rank first. An empty query with a category returns every command in that category. Paginate with next_page_id / page_length (defaults: next_page_id=0, page_length=10, max 50); the response contains 'results' (full command entries with signature, parameters, return type and category), 'total_count', 'next_page_id' (null when exhausted) and 'page_length'.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Search text: a command name (exact or partial, e.g. 'RSI', 'StopLoss') or keywords matched against descriptions (e.g. 'trailing stop'). May be empty only when category is provided. |
category |
string | No | Optional category filter, e.g. 'Technical Analysis', 'Easy Safeties', 'Order Handling', 'Enumerations Signal'. Case- and punctuation-insensitive. An unknown value returns the list of valid categories. |
next_page_id |
integer | No | Pagination offset (0 or omit for first page). |
page_length |
integer | No | Results per page (default 10, max 50). |
Backtest Execution¶
execute_backtest¶
Runs a backtest for a HaasScript over a specified Unix time range. Returns the SERVICE ID that accepted the execution (e.g. "LocalService-ENT"), not a backtest id - pass it to get_backtest_status / get_backtest_info as service_id. The run is addressed by the backtest_id YOU supplied, which this tool does not mint and does not echo back. So: get_backtest_status(backtest_id=<yours>, service_id=<returned>).
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Unique backtest ID (generate a new hash) |
script_id |
string | Yes | Script ID to backtest |
settings |
object | Yes | HaasScriptSettings JSON (accountId, marketTag, interval, tradeAmount, etc.). orderTemplate is optional and defaults to 500 (Limit) when absent or invalid. |
start_unix |
integer | Yes | Backtest start time as Unix timestamp (seconds) |
end_unix |
integer | Yes | Backtest end time as Unix timestamp (seconds) |
fill_when_touched |
boolean | No | Limit order fill rule for THIS backtest only: true = filled when the price touches the order price, false = only when the price trades through it (breached). Omit to use the account setting. Does not change the account setting or paper trading. The rule used is returned as BacktestFillWhenTouched by get_backtest_runtime. |
get_backtest_status¶
Returns the execution status of a backtest started with execute_backtest. Response: S = state, P = progress percent (0-100), M = status message, MID = message id. S values: 0 = LoadingScript, 1 = LoadingPriceHistory, 2 = Executing, 3 = Completed, 4 = Failed. Poll until S is 3 or 4. Only S=3 means the run finished and saved a result; never read P alone as completion. S=4 means the run failed or was cancelled: no result was saved, M says why, and the run cannot be resumed, so start it again with execute_backtest and a new backtest_id. The info/runtime/logs/positions tools then answer 'Backtest ID not found' for the failed id.
| Parameter | Type | Required | Description |
|---|---|---|---|
service_id |
string | Yes | Service ID returned when backtest was started |
backtest_id |
string | Yes | Backtest ID |
get_backtest_info¶
Returns summary information for a completed backtest. Without lab_id, targets standalone backtests and returns the standard info shape (RID/BID/BS/BE/ES/EE/ST/AT/ME/PT/RT/IA - PT is the formatted profit and RT the formatted ROI). With lab_id, proxies to the lab-scoped endpoint and returns the lab-result entry shape (RID/LID/BID/NG/NP/ST/SE/P/S - where S is the stats block with nested ROI/fees/report objects and P is the parameter map) - the same shape get_lab_results returns per entry, NOT the standard info shape. For the standalone-equivalent runtime detail of a lab combo (InputFields, Reports, FinishedPositions, etc.) use get_backtest_runtime(backtest_id, lab_id).
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Backtest ID |
lab_id |
string | No | Parent lab ID (optional). When provided, drills into the lab-internal backtest via LabsAPI instead of standalone BacktestAPI. Note: the response shape differs between the two paths - see the tool description. |
get_backtest_runtime¶
Returns the runtime state of a completed backtest, including the aggregate Reports block. By default targets standalone backtests; also pass lab_id to query a lab-internal backtest returned by get_lab_results. The two paths differ: on the STANDALONE path FinishedPositions is always empty, ManagedLongPosition/ManagedShortPosition are always blank stubs, and Chart is null - all are stored separately, so empty means 'stored elsewhere', NOT 'no trades'. Use the Reports block's P.C (closed count) to tell whether the run traded, and get_backtest_positions to fetch the positions. Under lab_id they are populated. Likewise the Files field lists export files by name and headers only - its Rows arrays are always empty; use get_backtest_export_data.
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Backtest ID |
lab_id |
string | No | Parent lab ID (optional). When provided, drills into the lab-internal backtest via LabsAPI instead of standalone BacktestAPI. |
get_backtest_logs¶
Returns a paginated slice of execution log lines for a backtest. By default targets standalone backtests; pass lab_id to drill into a lab-internal backtest returned by get_lab_results. Large backtests can produce logs that exceed the MCP transport size limit - paginate with next_page_id / page_length (defaults: next_page_id=0, page_length=200). The response shape matches the other paginated MCP tools: 'I' is the current page of lines, 'NP' is the next cursor (-1 when exhausted), 'total_count' is the full line count.
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Backtest ID |
lab_id |
string | No | Parent lab ID (optional). When provided, drills into the lab-internal backtest via LabsAPI instead of standalone BacktestAPI. |
next_page_id |
integer | No | Pagination cursor (0 or omit for first page). |
page_length |
integer | No | Lines per page (default 200, max 2000). Keep small enough that the page fits under the 1MB MCP response cap. |
get_backtest_positions¶
Returns a paginated list of trade positions from a completed backtest. By default targets standalone backtests. To query a lab-internal backtest returned by get_lab_results, also pass lab_id - there is no dedicated LabsAPI positions endpoint, so the MCP layer fetches the lab-scoped runtime payload and paginates its FinishedPositions list client-side. Shape on both paths: I = page of positions, NP = next cursor (-1 when exhausted; a final page shorter than page_length returns -1 directly), total_count = positions across all pages. Counts are NOT comparable across the two paths. Standalone total_count = closed positions PLUS every position still open when the backtest ended, so the gap over Reports P.C is 0..N. It is commonly exactly 1 - a simple managed strategy usually ends holding one position - and that is the trap: the relationship is CONDITIONAL, not an invariant. Grid and DCA strategies finish holding many open legs, where gaps of dozens are normal (103 vs 59 measured). Do not validate a client against a simple strategy and assume +1 generalizes; if you need the closed count, read Reports P.C directly rather than deriving it. Lab counts closed only (total_count == P.C). Do NOT try to infer the open count from get_backtest_runtime on the standalone path: UnmanagedPositions, ManagedLongPosition, ManagedShortPosition and FinishedPositions are all blanked AFTER the positions are saved, so that payload reports an empty position set regardless of how many were open.
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Backtest ID |
next_page_id |
integer | Yes | Pagination cursor (0 for first page). MUST be the NP value from the previous response. On the standalone path a guessed value below the live cursor range is rejected with an error rather than answered with a false NP:-1; on the lab_id drill-in path the cursor is a plain offset and out-of-range values are clamped. |
page_length |
integer | Yes | Number of results per page (max 1000) |
lab_id |
string | No | Parent lab ID (optional). When provided, drills into the lab-internal backtest by extracting positions from the lab-scoped runtime payload. |
get_backtest_export_data¶
Returns an export file written by a script during a backtest via InitExportData/WriteExportData, paginated by row. This is the ONLY way to read export rows over MCP (get_backtest_runtime's Files field gives names and headers only). Response contains I (rows for this page - CSV data lines as strings, or row objects with format=json), H (the CSV header line, csv only), NP (offset of the next row, -1 when exhausted), total_count (rows in the file, excluding the header) and page_length. Export files are unbounded and a whole file routinely exceeds the 1MB transport cap, so request one page at a time and follow NP. page_length defaults to 150, max 2000; lower it for wide rows, since the cap is on bytes not rows. total_count = 0 means no such export file (or it has no rows). By default targets standalone backtests; pass lab_id to drill into a lab-internal backtest returned by get_lab_results.
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Backtest ID |
name |
string | Yes | Export file name as defined by InitExportData - the keys of the Files map in the get_backtest_runtime response. |
format |
string | No | Output format: 'csv' (default) or 'json'. |
next_page_id |
integer | No | Row offset of the first row to return, excluding the CSV header. Start at 0; pass the NP value from the previous response to continue. Default 0. |
page_length |
integer | No | Rows per page (max 2000). Default 150. |
lab_id |
string | No | Parent lab ID (optional). When provided, drills into the lab-internal backtest via LabsAPI instead of standalone BacktestAPI. |
get_backtest_history¶
Returns a paginated list of all stored backtest results. Response: I = page of records, NP = cursor for the next page (-1 when exhausted; a final page shorter than page_length returns -1 directly), total_count = records across all pages.
| Parameter | Type | Required | Description |
|---|---|---|---|
next_page_id |
integer | Yes | Pagination cursor (0 for first page). Use the NP value from the previous response. |
page_length |
integer | Yes | Number of results per page (max 1000) |
list_active_backtests¶
Returns all currently running backtest executions for the user.
No parameters.
is_script_executing¶
Returns the current execution state for a script (whether a backtest is running).
| Parameter | Type | Required | Description |
|---|---|---|---|
script_id |
string | Yes | Script ID to check |
cancel_backtest¶
Cancels a currently running backtest. result true = a running backtest was actually cancelled; false = nothing to cancel (already finished, or unknown ID) - a no-op, not an error.
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Backtest ID to cancel |
service_id |
string | Yes | Service ID returned when backtest was started |
delete_backtest¶
Permanently deletes a stored backtest result. Returns true on success.
| Parameter | Type | Required | Description |
|---|---|---|---|
backtest_id |
string | Yes | Backtest ID to delete |
Trading Bots¶
list_bots¶
Returns the user's trading bots, paginated in a stable order (by ID, so paging never skips a bot; sort a page client-side if you want it ranked). Response contains I (items), NP (offset of the next page, -1 when exhausted), total_count and page_length. Entries are lean by default - ID, BN (name), SI (script ID), AI (account), PM (market), IA (activated), IP (paused), RP/UP/ROI and the TAE/AE/SE error flags; pass include_details=true for the full record (notes, chart settings). Narrow with active_only or name_filter. This is the only source of bot IDs - every other bot tool needs one from here.
| Parameter | Type | Required | Description |
|---|---|---|---|
next_page_id |
integer | No | Offset of the first bot to return. Start at 0; pass the NP value from the previous response to continue. Default 0. |
page_length |
integer | No | Bots per page (max 200). Default 100. |
active_only |
boolean | No | Return only activated bots. Default false. |
name_filter |
string | No | Case-insensitive substring match on the bot name (BN). |
include_details |
boolean | No | Return the complete bot record instead of the lean one (large). Default false. |
get_bot¶
Returns a single bot by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
bot_id |
string | Yes | Bot ID hash |
get_bot_runtime¶
Returns the current runtime state of a bot including positions and orders.
| Parameter | Type | Required | Description |
|---|---|---|---|
bot_id |
string | Yes | Bot ID hash |
get_bot_report¶
Returns the performance report for a bot (Sharpe ratio, win rate, profit factor, etc.).
| Parameter | Type | Required | Description |
|---|---|---|---|
bot_id |
string | Yes | Bot ID hash |
get_bot_open_orders¶
Returns the currently open orders for a bot.
| Parameter | Type | Required | Description |
|---|---|---|---|
bot_id |
string | Yes | Bot ID hash |
get_bot_positions¶
Returns open or closed positions for a bot. Use status='open' (default) or status='closed'. Both paths return I = page of positions, NP = next cursor (-1 when exhausted) and total_count - a CONSTANT total across all pages, counting each closed position once. Open positions use an offset cursor sliced at the MCP layer. Closed positions are archived the moment they close, so the archive is the whole set; the bot runtime also keeps the newest ~10 as a display cache, and the few not written yet (a deal that closed since the last save) surface on page 1 and count against page_length, so page 1 can hold up to max(page_length, that count) items.
| Parameter | Type | Required | Description |
|---|---|---|---|
bot_id |
string | Yes | Bot ID hash |
status |
string | No | 'open' (default) or 'closed' |
next_page_id |
integer | No | Pagination cursor (default 0). Use the NP value from the previous response. |
page_length |
integer | No | Page size (closed default 50, max 1000) |
get_bot_logs¶
Returns Log() output from a bot, newest first. Lines ARE persisted - they are written to the bot's log table and trimmed to the most recent 20,000 per bot, so history survives across ticks and restarts. NP is a keyset cursor over the log's own message id, not an offset, so pass it back verbatim to page further into the past. (total_count and page_length are not yet returned on this tool, unlike the other paginated tools - page until NP stops advancing.) A bot that has logged nothing returns empty. For structured diagnostic metrics rather than free text, emit values via CustomReport() and read them from get_bot_runtime's custom_report field.
| Parameter | Type | Required | Description |
|---|---|---|---|
bot_id |
string | Yes | Bot ID hash |
next_page_id |
integer | Yes | Pagination cursor (0 for first page) |
page_length |
integer | Yes | Number of log lines per page |
offset |
integer | No | Line offset within the page |
get_bot_profits¶
Returns one profit total per bot for the whole requested window - realized profit (P), fees (F) and executed-order count (TC), plus BID/BN and AI/AN/M. NOT a time series: there is no per-day breakdown and no date field on a record; call it once per window you want to compare. Fleet-wide only - filter the returned array client-side on BID for a single bot. Totals are built from archived positions, which are written when a position closes, so recent trades are included and zero means no position closed in that window. Only a deal that closed since the bot's last runtime save is missing (seconds, not days); for live realized profit use get_bot_runtime and read RP.
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date |
integer | Yes | Period start as Unix timestamp (seconds) |
end_date |
integer | Yes | Period end as Unix timestamp (seconds) |
Exchange Accounts¶
list_accounts¶
Returns all exchange accounts (real and simulated) for the authenticated user. The per-market MS margin-settings map is omitted by default - it was 96-98% of the payload (hundreds of near-identical entries per futures exchange) and routinely exceeded the 1MB transport cap. Pass include_margin_settings=true when leverage/margin settings are actually needed.
| Parameter | Type | Required | Description |
|---|---|---|---|
include_margin_settings |
boolean | No | Include each account's per-market MS margin-settings map (large). Default false. |
create_simulated_account¶
Creates a new simulated (paper-trading) exchange account on the user's trade server and returns the created UserAccount record (its AID is the account_id other tools take). The account is seeded with simulated funds, so it is ready for bots and backtests at once. Never creates or touches a live exchange account. Counts against the plan's simulated-account limit; the backend answers 'License limit' when that is reached and 'ACTIVATION_REQUIRED' when the user has not activated. Each call creates another account: list_accounts first to reuse one that already exists.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display name for the account (1-75 characters). |
driver_code |
string | Yes | Exchange driver code, uppercase and exactly as list_markets reports it (the match is case-sensitive), e.g. BINANCE, BINANCEFUTURES, BYBITSPOT. 'Invalid drivercode' means the code is not a known exchange. |
driver_type |
string | Yes | EnumExchangeType of the driver: Spot (0), Margin (1) or Leverage (2). Must match the exchange driver (Leverage for futures/perpetual drivers); name or number is accepted. |
Labs (Parameter Optimization)¶
Labs let you run automated parameter-space searches across a HaasScript to find optimal settings.
list_labs¶
Returns all lab records for the authenticated user.
No parameters.
create_lab¶
Creates a new lab for running parameter-space simulations on a HaasScript.
| Parameter | Type | Required | Description |
|---|---|---|---|
script_id |
string | Yes | Script ID to use for the lab |
name |
string | Yes | Lab name |
account_id |
string | Yes | Exchange account ID |
market |
string | Yes | Market tag (e.g. BINANCE_BTC_USDT_) |
interval |
integer | Yes | Candle interval in minutes |
style |
integer | Yes | Chart price plot style enum value |
clone_lab¶
Clones an existing lab record. Returns the new UserLabRecord.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID to clone |
name |
string | No | Name for the cloned lab (optional) |
get_lab_details¶
Returns the full details of a lab record including its configuration and parameters. NOTE: the parameter keys in 'P' reflect the lab's LAST SAVE - input keys encode the Input() call's source position, so if the script was edited since, these keys may be stale and no longer match the current compile. Do not treat them as currently valid; update_lab re-validates and migrates every key against the script's current inputs.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID |
update_lab¶
Updates a lab's configuration, settings, and parameter ranges. The 'parameters' array contains UserLabParameter entries; each 'K' is a hash-prefix key (e.g. '2-2-16-21.EMA Fast') or a bare input name (e.g. 'EMA Fast'). Every K - bare OR full - is validated and resolved against the SCRIPT'S CURRENT COMPILE on each call: stale keys from before a script edit are migrated to the current key automatically, and a K matching zero or multiple current inputs is rejected with an error listing the valid input names. Two inputs sharing one name cannot be addressed at all once their keys go stale - keep swept input names unique. Values to sweep can be specified in one of two ways: (a) 'O' as an EXPLICIT list of values - '[10, 30, 10]' sweeps exactly those three values (NOT an arithmetic progression); or (b) 'range' as a shorthand [start, end, step] that is server-side expanded into an explicit inclusive 'O' list (e.g. range=[10, 30, 10] expands to O=[10, 20, 30]). Use one or the other per entry, not both. NOTE: parameter keys encode the Input() call's source position, so EDITING THE SCRIPT RE-KEYS its parameters; get_lab_details returns the keys as last saved (possibly stale), and a successful update_lab re-canonicalizes them. Prefer bare names when configuring.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID to update |
name |
string | Yes | Lab name |
type |
string | Yes | EnumUserLabAlgorithm value: 0 = BruteForce, 1 = Intelligent, 2 = Random, 3 = Cluster. New labs are created as BruteForce (0). BruteForce runs EVERY combination of the swept values and is capped at 1000 combinations - a dozen parameters of a handful of values each is already billions, and start_lab_execution will reject it. For any sweep wider than 1000, use Intelligent (1): it samples the space in MaxPopulation * MaxGenerations backtests (config MP/MG) no matter how large the space is. |
config |
object | Yes | UserLabConfig JSON (maxBots, maxIterations, etc.) |
settings |
object | Yes | HaasScriptSettings JSON (accountId, marketTag, interval, etc.) |
parameters |
array | Yes | List<UserLabParameter> JSON array. Each entry: K=hash-prefix key or bare input name (both validated and resolved against the script's current compile), T=type, O=EXPLICIT value list OR range=[start, end, step] shorthand (mutually exclusive; range is inclusive and server-side expanded into O), I=enabled, IS=specific. |
start_lab_execution¶
Starts a lab execution over a time range. Returns updated UserLabDetails.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID to execute |
start_unix |
integer | Yes | Backtest start time as Unix timestamp (seconds) |
end_unix |
integer | Yes | Backtest end time as Unix timestamp (seconds) |
send_email |
boolean | No | Send email notification on completion |
get_lab_execution_status¶
Returns the current execution status of a lab. S: 0=created, 1=queued, 2=running, 3=completed, 4=cancelled, 5=failed - ¾/5 are terminal, so poll until S >= 3, not just S=3. CM carries the failure/cancel reason ('Cancelled by user' for a user-initiated cancel), or a live wait reason while queued (e.g. price history still downloading). WS is the unix timestamp of the lab's first dispatch rejection while queued (0 = never rejected; cleared on start) - the ~30-minute undispatchable auto-fail clock runs from WS, not from queue entry. TB (total backtests) is populated from the first poll; FB increments as combos complete and never exceeds TB; RB is a map of currently-running backtest UUIDs and shrinks to {} at completion. While queued, CM reports why (waiting on queue capacity or executors is normal and unbounded; waiting on price history fails automatically after ~30 minutes of being undispatchable, with the reason in CM). If S stays 1 with an unchanging CM for a long time, cancel and investigate rather than polling forever.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID |
get_lab_results¶
Returns a paginated list of backtest results for a lab, sorted by ROI descending across the WHOLE result set (page 1 is the global top-N). Response contains I (items), NP (offset of the next page, -1 when exhausted), total_count, page_length, and truncated (true only when the lab exceeds the 10,000-result aggregation cap - ordering and total_count then cover the newest 10,000). An entry whose S.IC flag is true came from a failed/partial execution - its ROI reflects incomplete state, so discard it when ranking. Each call ranks a fresh snapshot: while a lab is still executing, page boundaries can shift between calls, so fetch one large page for a stable ranking. Each result entry has a 'BID' field that is lab-internal - it is NOT queryable via the standalone backtest calls on its own. To drill into a specific combo, pass BOTH this lab_id AND the entry's BID as the backtest_id argument to get_backtest_info, get_backtest_runtime, get_backtest_logs, or get_backtest_positions; those tools will then proxy to the lab-scoped endpoint. Note: get_backtest_info under lab_id returns the same lab-result entry shape as this tool (not the standalone PT/RT info shape) - use get_backtest_runtime(bid, lab_id) for the full standalone-equivalent runtime detail.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID |
next_page_id |
integer | No | Absolute offset into the ROI-sorted result set (0 for first page, default 0). Use the NP value from the previous response. |
page_length |
integer | No | Number of results per page (default 50, max 200) |
cancel_lab_execution¶
Cancels a queued or running lab execution. result true = the lab was actually cancelled; false = nothing to cancel (already completed/cancelled/failed, or unknown ID) - a no-op, not an error.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID |
delete_lab¶
Permanently deletes a lab record. Returns true on success.
| Parameter | Type | Required | Description |
|---|---|---|---|
lab_id |
string | Yes | Lab ID to delete |
Markets & Price Data¶
list_markets¶
Returns available markets. When exchange_code is provided, returns paginated markets for that exchange. When omitted, returns a summary of all exchanges with their market counts.
| Parameter | Type | Required | Description |
|---|---|---|---|
exchange_code |
string | No | Filter by exchange code (e.g. BINANCE, BYBIT). When omitted, returns exchange summary only. |
next_page_id |
integer | No | Pagination offset (0 or omit for first page). Only applies with exchange_code. |
page_length |
integer | No | Markets per page (default 100, max 500). Only applies with exchange_code. |
check_market_data¶
Checks price-data availability for a market over a time range. Returns a coverage SUMMARY by default: first_unix, last_unix, count, expected_count (clamped to now, so end_unix in the future is fine), complete, gaps (up to 20 [from,to] unix pairs of MISSING candles - rare; they indicate a price-cache defect), zero_volume_count/zero_volume_runs (up to 20 [from,to] pairs of candles carrying no volume), and flat_zero_volume_count/flat_zero_volume_runs (the subset of those whose price also never moved). USE flat_zero_volume_* as the usability signal, NOT zero_volume_*: zero volume on its own does not mean the market is dead, because some venues publish no fills at all for some markets (Bitget's Reality tokenized stocks - rAAPL, rNVDA - route fills off-exchange, so every candle is zero-volume while the price moves normally and is correct). A run that is zero-volume AND flat is the backend flat-filling a period with no trades, which IS unusable for backtesting, e.g. a delisted market. count < expected_count with empty gaps means the stored history starts after start_unix (see first_unix). Pass include_candles=true for the candle bodies in ASCENDING time order, paginated as I / NP (offset cursor, -1 when exhausted) / total_count / page_length - note each page re-reads the range server-side, so prefer large pages.
| Parameter | Type | Required | Description |
|---|---|---|---|
market |
string | Yes | Market tag (e.g. BINANCE_BTC_USDT_) |
start_unix |
integer | Yes | Start time as Unix timestamp (seconds) |
end_unix |
integer | Yes | End time as Unix timestamp (seconds) |
interval |
integer | Yes | Candle interval in minutes |
include_candles |
boolean | No | Return candle bodies alongside the summary (default false - a 31-day 1m range is ~44,640 candles) |
next_page_id |
integer | No | Candle pagination offset (only with include_candles; default 0) |
page_length |
integer | No | Candles per page (only with include_candles; default 500, max 1000) |
sync_market_data¶
Triggers a data sync for a market.
| Parameter | Type | Required | Description |
|---|---|---|---|
market |
string | Yes | Market tag (e.g. BINANCE_BTC_USDT_) |
Wallet & Portfolio¶
get_wallet¶
Returns the raw wallet (balances) for a single exchange account.
| Parameter | Type | Required | Description |
|---|---|---|---|
account_id |
string | Yes | Exchange account ID |
list_wallets¶
Returns raw wallets for all exchange accounts belonging to the user.
No parameters.
get_balance¶
Returns the balance for an account converted to a target currency.
| Parameter | Type | Required | Description |
|---|---|---|---|
account_id |
string | Yes | Exchange account ID |
currency |
string | Yes | Target currency to convert to (e.g. USDT) |
aggregate_currencies |
boolean | Yes | Aggregate all currencies into a single total |
get_portfolio¶
Returns the full portfolio (holdings + value) across one or more accounts.
| Parameter | Type | Required | Description |
|---|---|---|---|
account_ids |
string | Yes | Comma-separated account IDs (or empty for all) |
coins |
string | Yes | Comma-separated coin list to include (or empty for all) |
currency |
string | Yes | Target currency for value conversion (e.g. USDT) |
timestamp |
integer | Yes | Unix timestamp for historical snapshot (0 = now) |