Parameter Loop Advanced Configuration
The Parameter Loop worker is designed to be simple at first glance — define a grid, click run, see results. But beneath the surface lies a rich set of configuration options that give you fine-grained control over how sweeps execute, how results are stored, and how they surface in your workflow.
This guide covers every configuration field in detail.
Configuration Reference
The Parameter Loop's left-column dialog is divided into logical sections. Here's every field, what it does, and when to use it.
1. Sub-Worker Connection
| Field | Description |
|---|---|
| Connected worker | Dropdown selecting which worker in your canvas to sweep. The worker connected to the left out handle appears here automatically. |
The Parameter Loop doesn't know what kind of worker it's testing — it could be a Backtest, a Signal Generator, a Python Exec, or any other worker. The connection defines the target.
2. Sweep Parameters — The Grid Definition
This is where you define what to sweep and over what range.
Format 1: Explicit JSON List
Best for small, exact sets of values:
[
{"name": "stop_loss", "values": [1.0, 1.5, 2.0, 2.5, 3.0]},
{"name": "take_profit", "values": [2.0, 3.0, 4.0, 5.0, 6.0]}
]
Format 2: Range Notation
Best for numeric ranges with even spacing. Write a string in the values field:
| Input | Generates | Total Values |
|---|---|---|
"1-5" | [1, 2, 3, 4, 5] | 5 |
"1-5:0.5" | [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0] | 9 |
"1, 2, 3, 5, 10" | [1, 2, 3, 5, 10] | 5 |
Format 3: Mixed Types
Parameters don't have to be numeric. You can sweep strings, booleans, or any type:
[
{"name": "timeframe", "values": ["1h", "4h", "1d"]},
{"name": "trailing_stop", "values": [true, false]},
{"name": "position_size", "values": [0.05, 0.1, 0.15]}
]
This creates a 3 × 2 × 3 = 18-iteration grid.
Important — Grid Size Warning
The total number of iterations is the cartesian product of all parameter values. A grid with parameters of 10, 10, and 10 values = 1,000 iterations. The dialog shows the estimated iteration count before you run.
3. Sub-Worker Parameters (Base Configuration)
These are the base parameters passed to your sub-worker on every iteration. Sweep values are merged on top of these (sweep values take priority on key collisions).
Example — if your Backtest has:
"subWorkerParameters": {
"symbol": "XAUUSD",
"initial_capital": 10000,
"commission": 0.001,
"stop_loss": 1.0,
"take_profit": 2.0
}
And you sweep stop_loss and take_profit, then symbol, initial_capital, and commission stay fixed across every iteration while SL and TP vary.
4. Collection & Ranking
These fields control what data gets extracted from each iteration and how the "best" is determined.
collectField
A dotted path into the sub-worker's output that defines what constitutes the "result" for ranking purposes.
| Value | What It Collects |
|---|---|
| (empty) | The entire sub-worker output |
result.sharpe_ratio | The Sharpe ratio from the backtest summary |
result.total_return | Total return percentage |
result.summary.win_rate | Win rate from nested summary |
result.trades_count | Number of trades executed |
The collected value is what appears in the r.* columns of the results table and what the ranking system evaluates.
rankingField
Which field inside the collected result to use for ranking:
| Scenario | rankingField | rankingMode |
|---|---|---|
| Maximize risk-adjusted returns | sharpe_ratio | max |
| Minimize downside risk | max_drawdown | min |
| Maximize raw profit | total_return | max |
| Maximize consistency across blocks | consistency_score | max |
| Minimize trade duration | avg_trade_duration | min |
rankingMode
max— Higher values are better (Sharpe ratio, total return, win rate)min— Lower values are better (max drawdown, avg trade duration)
A note on multi-metric optimization: The Parameter Loop ranks by a single field. If you want to optimize for a combination (e.g., max Sharpe with min drawdown), create a composite metric in your strategy and collect that single field.
5. Safety Controls
| Field | Default | Description |
|---|---|---|
| maxIterations | 0 (no cap) | Hard limit on total iterations. Set to 50 during dev to avoid accidental huge sweeps. |
| continueOnError | true | When true, failed iterations are recorded as errors but the sweep continues. When false, the first failure aborts the entire sweep. |
When to change defaults:
- Development: Keep both at defaults. You want to see all results even if some combos fail.
- Critical sweeps: Set
continueOnError: false— if any combination fails, you want to know immediately and stop. - Slow workers: Always set
maxIterationsto a reasonable cap (e.g., 50) to avoid accidentally queuing thousands of iterations on a worker that takes 10 seconds per run.
6. Concurrency — Parallel Execution
| Field | Default | Range | Description |
|---|---|---|---|
| concurrency | 1 | 1 — 8 | Number of iterations to run simultaneously |
At concurrency: 1, iterations run sequentially — one after another. At concurrency: 4, four iterations run in parallel.
Performance impact:
| Concurrency | 25 iterations | 100 iterations | 500 iterations |
|---|---|---|---|
| 1 | ~5s | ~20s | ~100s |
| 2 | ~3s | ~10s | ~50s |
| 4 | ~2s | ~6s | ~28s |
When to increase concurrency:
- Your sub-worker is CPU-bound and you have multiple cores
- Your sub-worker is I/O-bound (network calls, database queries)
- You're running large sweeps (100+ iterations)
When to keep at 1:
- Iterations are memory-intensive and you risk OOM
- Your sub-worker uses polars/Arrow with large datasets
- You're debugging and want sequential output
7. Session Management
sessionLabel
When set, the full sweep results are saved to the Sessions tab in MongoDB (collection: parameter_sessions).
"sessionLabel": "xauusd_swing_june_2026"
What gets saved:
- The sweep parameter definitions
- Per-iteration compact results (flattened into
p.*andr.*columns) - Best iteration, best parameters, best value
- Column metadata for the frontend to render the table
Why always set a session label:
- You can load results later without re-running
- Production
use_bestmode requires a saved session - You can compare sessions across time: "Did the optimal SL change this month?"
Sessions tab in the UI:
After a sweep saves, the Sessions tab shows:
- Session name and creation date
- Parameter names and ranges used
- Best result summary
- One-click "Apply" to set parameters on the sub-worker
Best parameters flow:
Sweep completes → Session saved → Click row in Sessions tab
→ Parameters set on sub-worker → Save workflow → Ready for production
8. Output Control
storeFullOutput
When true, every iteration's complete sub-worker output is stored in the session (not just the collected result field). This can make sessions large. Default: false.
keepFields
When storeFullOutput is false, you can selectively keep specific fields:
"keepFields": ["result.sharpe_ratio", "result.total_return", "result.max_drawdown"]
Only these fields are stored per iteration — everything else is discarded.
displayFields
Controls which columns appear in the results table during and after the sweep:
"displayFields": ["sharpe_ratio", "total_return", "max_drawdown"]
When empty, ALL detected scalar fields are shown. Use this to keep the table focused on what matters.
9. Production Mode
| Value | Manual Run Test | Scheduled/Webhook |
|---|---|---|
disabled | Full sweep | Skip (exit immediately) |
use_best | Full sweep | Load best from session |
always_run | Full sweep | Full sweep |
bestValueField — When use_best loads the best parameters, it can also surface the best value (e.g., the Sharpe ratio of the winning iteration) into vars:
"bestValueField": "sharpe_ratio"
This writes vars._bestValue = 1.87 so downstream workers (Telegram notifications, webhooks) can report it.
pinnedBestParameters — Manual override that takes priority over the saved session:
"pinnedBestParameters": {
"stop_loss": 2.5,
"take_profit": 4.0
}
Use this when you already know the values and don't want to rely on session loading.
Configuration Cheat Sheet
| Goal | Key Settings |
|---|---|
| Quick exploration | concurrency: 4, maxIterations: 50, continueOnError: true |
| Deep optimization | concurrency: 1, maxIterations: 0, continueOnError: false, storeFullOutput: true |
| Production deployment | prodMode: use_best, sessionLabel: "...", displayFields: ["sharpe", "return"] |
| Dashboard monitoring | prodMode: always_run, concurrency: 2, maxIterations: 20 |
| Debugging failures | continueOnError: false, concurrency: 1 |
The Output Object
When the sweep completes, the Parameter Loop returns a structured output:
{
"action": "exit",
"totalIterations": 25,
"successfulIterations": 23,
"failedIterations": 2,
"iterations": [
{
"iteration": 1,
"parameters": {"stop_loss": 1.0, "take_profit": 2.0},
"result": {"sharpe_ratio": 0.42, "total_return": 8.3, "max_drawdown": -12.1},
"durationMs": 137
}
],
"bestIteration": 7,
"bestParameters": {"stop_loss": 2.5, "take_profit": 4.0},
"bestValue": 1.87,
"rankingField": "sharpe_ratio",
"rankingMode": "max",
"sessionSaved": true
}
Fields in the output:
iterations— Complete array of all iteration results (each contains the merged parameters + result + duration)bestIteration— The iteration number (1-based) that ranked highestbestParameters— The parameter combination that produced the best resultbestValue— The ranking field value for the best iterationsessionSaved— Whether the session was successfully saved to MongoDB
Summary
The Parameter Loop's configuration surface is intentionally deep — simple enough for a 2-minute setup, powerful enough for complex production workflows. Start with the defaults, then gradually tune each setting as your optimization needs grow.