--json output reference¶
This page is the contract (schema) reference for the alpha-forge CLI's --json output. It defines the top-level fields, types, and envelope conventions of the main commands, plus the meaning and increment rules of schema_version / forge_version, so agents and MCP/pipe consumers have a stable reference point when parsing output.
The conventions themselves (stdout purity, envelopes, exit codes) live in CLI conventions for agents. This page complements that with "the actual fields that appear".
Runtime catalog
The machine-readable catalog of every command (which commands have --json, the type of each option) is available via alpha-forge system describe --json. This page covers "what fields a --json output returns"; system describe --json covers "which commands have --json".
Three envelope shapes¶
Output shapes fall into three families by command type.
- List commands (
list/scan-all, etc.): a{"<plural>": [...], "count": n}envelope. Even when empty, an empty array + exit code0. - Single-run commands (
backtest run/optimize walk-forward/backtest monte-carlo, etc.): a raw object with no envelope (metrics and meta fields sit at the top level). - Errors: a fixed 3-key
{"error": ..., "code": ..., "id": ...}(see Error output).
Percent fields (*_pct) are already in percent units (e.g. 17.39 means +17.39%). Do not multiply by 100 again.
schema_version / forge_version¶
The backtest run --json output includes these two meta fields.
| Field | Type | Meaning |
|---|---|---|
schema_version |
int | The schema generation of the CLI output JSON. Currently 1. Bump it per the rules below |
forge_version |
string | The alpha-forge version that produced this output (e.g. "0.15.0") |
Distinct from the strategy JSON's schema_version
This schema_version is the contract generation of the CLI output JSON, a different concept from the strategy JSON file's schema_version (the strategy-definition schema generation seen in strategy show --json).
Increment rules (when to bump)¶
Bump schema_version by +1 only on a backward-incompatible change.
| Change | Bump? |
|---|---|
| Removing / renaming an existing field | Yes |
| Type change / meaning change of an existing field | Yes |
| Adding a new field (existing fields unchanged) | No (additions are backward-compatible) |
| Changing the envelope shape | Yes |
| Formatting only (compact ↔ indent, key order) | No |
The rule of thumb: additions are compatible; removals/renames/type or meaning changes are not. forge_version advances naturally every release, so use forge_version to track "when something changed" and schema_version to decide "whether consumer code must be fixed".
backtest run --json¶
A raw object with no envelope; metrics sit at the top level (60+ fields in practice). Only the contract-relevant meta fields are listed here.
| Field | Type | When present | Meaning |
|---|---|---|---|
schema_version |
int | always | CLI output schema generation |
forge_version |
string | always | producing version |
warnings |
array | always | runtime cautions (e.g. low trade count) |
freemium_limit_notices |
array | always | Trial-plan limit notices (include a code) |
run_id |
string | when a real run exists | run identifier |
result_id |
string | when a result is saved | saved-result identifier |
pre_filter_pass |
bool | on pre-filter evaluation | whether the pre-filter passed |
pre_filter |
object | on pre-filter evaluation | applied thresholds (sharpe_min / max_dd_max / monthly_volume_usd_min / min_trades / goal) |
criteria_check |
object | when pass/fail criteria exist | verdict (merged into the body) |
next_step |
array | when next actions are suggested | next-command candidates (string array) |
With --split, IS/OOS comparison meta is added: out_of_sample_metrics (OOS metrics), overfitting_score, overfitting_risk, and walk_forward_summary (is_sharpe / oos_sharpe / is_return_pct / oos_return_pct / overfitting_score / overfitting_risk).
With --summary, heavy per-trade / per-bar arrays are dropped for a lightweight JSON (the meta-field contract is unchanged).
optimize walk-forward --json¶
A raw object with no envelope.
| Field | Type | Meaning |
|---|---|---|
symbol / strategy / metric |
string | symbol / strategy ID / optimization metric |
windows |
array | per-window results (IS/OOS metrics, skip_reason, etc.) |
is_valid_windows / valid_oos_windows / total_windows / skipped_windows |
int | window counts |
all_is_invalid |
bool | whether IS optimization failed in every window |
freemium_limit_notices |
array | Trial limit notices |
pre_filter_pass |
bool | null | whether the average OOS metric meets the threshold (null if undecidable) |
pre_filter |
object | applied thresholds (sharpe_min / max_dd_max / min_trades / goal) |
pre_filter_pass / pre_filter are always present even without --goal (using default thresholds), matching backtest run's naming and contract.
backtest monte-carlo --json¶
Runs a Monte Carlo simulation from a saved backtest result's trade history. A raw object with no envelope.
| Field | Type | Meaning |
|---|---|---|
initial_capital |
number | initial capital |
simulations_run |
int | number of runs |
mean_final_equity / median_final_equity / worst_final_equity / best_final_equity |
number | final-equity statistics |
mean_max_drawdown_pct / max_drawdown_95pct |
number | max drawdown (mean and 95th percentile) |
ruin_probability_pct |
number | probability of ruin (%) |
pre_filter_pass |
bool | null | whether ruin probability is at or below the default threshold (5%) |
pre_filter |
object | max_ruin_pct (default 5.0) |
If the input result has fewer than 10 valid trades, an error is printed to stderr and exit code 1 is returned (no pure JSON is emitted).
List envelope¶
List / scan commands return {"<plural>": [...], "count": n}. Even when empty, an empty array + exit code 0.
| Command | Envelope keys | Main element keys |
|---|---|---|
strategy list --json |
strategies / count |
strategy_id / name / version / asset_type / timeframe / tags / notes / created_at / updated_at |
backtest list --json |
results / count |
saved-result rows (strategy_id / symbol / key metrics) |
analyze indicator list --json |
indicators / count |
name / category (plus params with --detail) |
analyze pairs scan-all --json |
pairs / count |
cointegration test results (plus cointegrated_count) |
system describe --json |
commands / count |
command / path / options / json_supported |
Error output¶
A not-found error (e.g. an unknown ID) prints the following fixed 3-key JSON to stdout when --json is set, and exits with code 1.
{"error": "strategy 'does_not_exist' not found", "code": "strategy_not_found", "id": "does_not_exist"}
| Field | Type | Meaning |
|---|---|---|
error |
string | localized message |
code |
string | stable machine-judgable code (e.g. strategy_not_found) |
id |
string | the resource ID that was not found |
Without --json, a single-line message goes to stderr and exit code is 1 (stdout is empty). Argument errors (Click UsageError) exit with code 2.
Related links¶
- CLI conventions for agents — stdout purity, envelopes, exit codes
- alpha-forge-mcp reference — using the CLI through MCP