Configuration reference

Where Forven keeps its configuration, the order settings are resolved in, the pipeline threshold groups (stance preset, quick screen, gauntlet, walk-forward, robustness and deflated Sharpe, the door into paper, the paper pool, paper→live, safety floors, live ramp), and the research, risk and data-engine keys in the settings blob.

Forven reads its configuration from a layered stack: the process environment, a key-value (KV) store inside its SQLite database, an on-disk config.json, and built-in defaults. This page is the operator's reference to that stack — where each layer lives, the order it is consulted in, and the pipeline threshold groups you are most likely to touch. For environment variables, see environment variables. For the friendly UI over nearly all of this, see Settings.

Forven is a research tool. The thresholds described here govern a validation process — they do not create an edge, and no configuration guarantees against loss. Numbers below are illustrative defaults from the current build, not predictions, recommendations, or financial advice.

Where configuration lives

Everything Forven stores lives under one root directory, FORVEN_HOME — ~/.forven by default (on Windows, %USERPROFILE%\.forven). It holds:

  • forven.db — the main SQLite database, including the KV settings table. Almost everything you change in the app is stored here.
  • forven_lab.db — the lab database.
  • config.json — a small file of file-based settings, consulted below the KV store.
  • auth.json — encrypted provider and exchange credentials (the key that decrypts them lives elsewhere; see encryption & secrets).
  • workspace/ — the operator profile and AI workspace files.
  • backups/ — database snapshots (see Updating & backups).

Market data (the Parquet data lake) lives under FORVEN_HOME/data or the repository's data/ folder, depending on how you launch — see FORVEN_DATA_DIR.

If a legacy home from an earlier build exists (~/.juddex or ~/.judex), Forven merges it into ~/.forven on first run and renames the database files (juddex.db → forven.db). You do not migrate by hand.

# Inspect your Forven home on Windows
Get-ChildItem "$env:USERPROFILE\.forven"

Precedence: how a setting is resolved

When Forven needs a value, it consults four layers in order. The first layer that defines the key wins:

  1. Environment variable (highest). Process-level overrides such as FORVEN_HOME, FORVEN_PORT, and FORVEN_ALLOW_MAINNET. A safety flag set here cannot be relaxed from inside the app — that ordering is deliberate.
  2. KV store. Runtime settings written by the app and the API. The main keys:
    • forven:settings — the general settings blob behind most of the Settings page, including the nested research_settings and data_engine_settings blocks described below.
    • forven:pipeline_thresholds — every promotion-gate threshold on this page.
    • forven:pipeline:settings — pipeline cadence, throughput, and per-stage work-in-progress caps.
    • system_state — the system pause flag and the autonomy mode.
  3. config.json on disk. A file-based fallback for a handful of settings (for example the backup AI provider and some regime-gate options).
  4. Built-in defaults (lowest). For pipeline thresholds, that is the canonical default configuration shipped with the app — the Default stance.

Config self-heals on load. Each time pipeline thresholds load, they are reconciled against the current defaults: missing keys are filled in, values stored as percentages are converted back to fractions, and structurally unsafe values are repaired with a warning. For example, a stored config that drops walk_forward from the required gauntlet tests has it restored, because without it nothing meaningful gates the path to paper.

How pipeline thresholds resolve

The promotion-gate thresholds are resolved in three steps:

  1. Stance preset. pipeline_preset — relaxed, default, strict, or custom — sets every threshold in one move. Choose it in Settings → Lab → Pipeline stance. Editing any single knob flips it to custom, which uses your per-knob values as they are.
  2. Your overrides, stored in forven:pipeline_thresholds.
  3. Safety floors clamp the result, so no preset, custom value, or automated caller can soften a gate past them. See safety floors.

The side-by-side comparison of the three presets is on the promotion gates page. The tables below give the Default stance.

A few settings sit outside the stance presets, so picking a stance leaves them alone: the quick-screen rule with its widest window and out-of-sample floor, the door into paper (paper_door.*), the paper pool (paper_pool.*), and the live-gate evidence settings (paper_trading.live_*).

The pipeline threshold groups

Drawdowns and returns are stored as fractions (0.30 = 30%), even though the app displays them as percentages.

quick_screen — the triage gate

quick_screen is the cheap first gate, run before a strategy is allowed to spend compute in the gauntlet. quick_screen.rule decides how it judges:

  • fair_sample (the default) judges the whole window, in-sample and out-of-sample together. While the window holds fewer than min_trades trades, the quick-screen step doubles it — from the quick-screen backtest window (730 days unless you changed it) up to max_window_days, data permitting, backfilling older history first — so only a strategy below about five trades a year ends up untestable. The out-of-sample slice only has to avoid losing badly.
  • strict is the pre-plan screen: a fixed window, with the in-sample and out-of-sample slices judged separately.
KeyMeaningDefault
quick_screen.rulefair_sample or strict. Settings → Lab → Quick Screen (Step 1) → Quick-screen rule.fair_sample
quick_screen.max_window_daysFair sample: the widest window the screen widens to while it is short of trades. 0 = never widen.1460
quick_screen.min_oos_sharpeFair sample: the out-of-sample slice's Sharpe must be above this.-0.5
quick_screen.min_tradesReject below this trade count — over the whole, widened window under fair sample; the in-sample slice under strict.20
quick_screen.min_sharpeSharpe floor — the whole-window Sharpe must be above it under fair sample; the out-of-sample Sharpe under strict.0.0
quick_screen.min_profit_factorProfit-factor floor — on the whole window under fair sample; at both the in-sample and out-of-sample legs under strict.1.0
quick_screen.min_total_return_pctReturn floor (whole window under fair sample).0.0
quick_screen.max_drawdown_pctMaximum drawdown (whole window under fair sample).0.30
quick_screen.min_is_sharpeStrict only: reject a negative in-sample edge. Fair sample records it instead.0.0
quick_screen.max_is_oos_ratioStrict only: reject if IS Sharpe exceeds OOS Sharpe by more than this multiple (an overfitting signature). Fair sample records the ratio instead.3.0
quick_screen.max_is_maxdd_pctStrict only: maximum in-sample drawdown.0.30
quick_screen.min_robustness_scoreRobustness floor before the gauntlet. 0 because the score is earned inside the gauntlet.0
quick_screen.min_win_rateWin-rate floor. Off — momentum and breakout families profit at 30–40% win rates.0.0
quick_screen.max_plausible_sharpeReject Sharpe at or above this as a look-ahead leak signature.5.0
quick_screen.max_plausible_profit_factorReject profit factor at or above this as a look-ahead leak signature.8.0

Under fair sample, the in-sample/out-of-sample gap, the ratio and a sign flip (negative in-sample, positive out-of-sample) are recorded, not enforced: they appear in the pass message. A strategy that never fires on the 900-bar look-ahead probe is probed again on a 3,600-bar walk before it is reported unverifiable. A tail-risk trap sits outside the config: a win rate above 70% with a profit factor below 1.5 is rejected as a martingale-shaped curve.

gauntlet — the gauntlet→paper gate

gauntlet governs the gauntlet robustness battery and the deliberately achievable gate into paper. Which of these checks block that gate depends on the door into paper.

KeyMeaningDefault
gauntlet.required_testsTests that must have a saved verdict before paper. Under Strict paper they must also pass.["walk_forward", "param_jitter"]
gauntlet.min_robustness_scoreMinimum robustness score (out of 100).30
gauntlet.min_tradesMinimum trade count (Strict paper; the research door uses paper_door.min_trades).20
gauntlet.min_sharpeMinimum Sharpe.0.1
gauntlet.hard_min_is_sharpeHard in-sample Sharpe floor at gauntlet entry.0.0
gauntlet.max_drawdown_pctMaximum drawdown.0.30
gauntlet.min_oos_profit_factorMinimum out-of-sample profit factor (Strict paper; the research door uses paper_door.min_oos_profit_factor).1.05
gauntlet.mc_max_dd_p95Monte-Carlo 95th-percentile drawdown ceiling.0.40
gauntlet.wfa_max_degradationWalk-forward: maximum IS→OOS Sharpe degradation.0.35
gauntlet.wfa_min_oos_tradesWalk-forward: minimum out-of-sample trades.20
gauntlet.wfa_min_foldsWalk-forward: minimum judgeable folds.2
gauntlet.wfa_baseline_hurdle_paperBaseline hurdle at gauntlet→paper: off, observe, or enforce.observe
gauntlet.wfa_baseline_hurdle_liveBaseline hurdle at paper→live. A failure keeps the strategy in paper; nothing is archived.enforce
gauntlet.wfa_baseline_min_alpha_pctAnnualised out-of-sample alpha, after removing buy-and-hold and a fixed trend rule, must be above this.0.0
gauntlet.wfa_baseline_min_alpha_tOptional t-stat floor on that alpha. 0 disables it.0.0
gauntlet.wfa_baseline_min_oos_daysFewer out-of-sample days than this is insufficient evidence: reported, never blocking.60
gauntlet.async_result_max_age_minutesMinutes an async result may stay "running" before it is resubmitted.60

The five robustness tests are walk_forward, monte_carlo, param_jitter, cost_stress, and regime_split, ordered cheap-first so weak strategies fail fast. The Strict stance adds cost_stress to the required list.

Under the default research door, a FAIL of any of those tests, the walk-forward consistency checks (wfa_min_folds and the fold pass rate) and the robustness score are recorded at the door and enforced at paper → live. The return, drawdown and Monte-Carlo tail-drawdown (mc_max_dd_p95) floors apply under both doors.

The baseline hurdle regresses every walk-forward's out-of-sample returns against buy-and-hold of the same asset and a fixed trend-following rule over the same days and costs. A strategy that only beats zero may just be riding the market. It shows on the strategy page as the Beats baselines row. The estimate is noisy, which is why it only observes at the gauntlet→paper gate by default.

walk_forward — the out-of-sample simulator

KeyMeaningDefault
walk_forward.n_foldsNumber of walk-forward folds.5
walk_forward.in_sample_pctShare of each fold used for training in a plain walk-forward run; the rest is out-of-sample. The gauntlet's walk-forward does not use it: there, the optimizer's selection window is the in-sample prefix and the whole untouched holdout is tiled into out-of-sample folds.0.70
walk_forward.max_barsMaximum candles per fold (a compute bound).50000
walk_forward.min_oos_days_1hMinimum out-of-sample days per fold at 1h.30
walk_forward.fee_bpsFee applied in walk-forward, in basis points.4.5
walk_forward.slippage_bpsSlippage applied in walk-forward, in basis points.2.0

robustness_thresholds — the per-test pass marks

KeyMeaningDefault
robustness_thresholds.monte_carlo_percentile_minMonte-Carlo: minimum share of profitable resamples.0.65
robustness_thresholds.param_jitter_pass_rate_minParameter jitter: minimum share of reruns that pass.0.50
robustness_thresholds.param_jitter_min_tradesBaseline trades needed before a jitter sweep runs.10
robustness_thresholds.param_jitter_max_iterationsCap on jitter reruns.30
robustness_thresholds.cost_stress_max_degradation_pctCost stress: maximum Sharpe degradation under 2× fees and slippage (percentage points).60.0
robustness_thresholds.cost_stress_min_sharpeCost stress: minimum stressed Sharpe.0.3
robustness_thresholds.regime_split_profitable_minRegime split: minimum share of regimes that must be profitable.0.50
robustness_thresholds.regime_split_min_trades_per_regimeTrades a regime needs before it counts.5
robustness_thresholds.wfa_fold_pass_rate_minWalk-forward: minimum share of judged folds with positive OOS Sharpe.0.33
robustness_thresholds.wfa_min_fold_tradesOut-of-sample trades a fold needs before it is judged.5
robustness_thresholds.deflated_sharpe_gate_enabledEnforce the deflated Sharpe ratio: at paper → live (on backtest plus forward trades) under the research door, at gauntlet → paper under Strict paper. Always computed.true
robustness_thresholds.min_deflated_sharpeDeflated-Sharpe floor (a probability from 0 to 1) when the gate is on.0.90
robustness_thresholds.deflated_sharpe_default_trialsTrial count used when an optimization searched nothing (a one-combination run).50
robustness_thresholds.dsr_swarm_trials_enabledMultiply the trial count by 1 + the sibling strategies from the same idea cluster (family × asset) that failed.true
robustness_thresholds.dsr_swarm_lookback_daysWindow for counting those failed siblings. 0 = unbounded.90
robustness_thresholds.deflated_sharpe_trade_scopeWhich trades the DSR is computed on: confirmation_window (every trade of the confirmation backtest) or oos (the legacy out-of-sample tail).confirmation_window
robustness_thresholds.dsr_swarm_scopeWhose failed siblings count: same_origin (only the candidate's own search origin — Drop Zone, in-app agents, or another source) or all.same_origin

The deflated-Sharpe gate is on by default. On an existing install, a one-time startup step switches it on in your stored config; strategies already in paper or live are not re-judged, and if you turn the gate off afterwards it stays off. Under the default research door the DSR is recorded at the door into paper (it ranks the paper queue) and enforced when the strategy applies for live. A sibling only counts as a trial if a completed backtest reached the quick-screen trade floor and it was not judged untestable or look-ahead. An uncomputable DSR is treated as pending evidence, never as grounds for archiving.

The strategy page's Deflated Sharpe card still describes the DSR as advisory and draws a 0.95 "conventional" bar. The gate itself rejects below min_deflated_sharpe, which is 0.90 by default.

paper_door — the door into paper

paper_door decides which gauntlet checks block entry to paper. Paper risks no capital, so by default (mode: research, the Research door) the door stops only strategies that are broken or clearly losing. It still enforces:

  • at least min_trades confirmation trades, a non-negative return, an out-of-sample profit factor of at least min_oos_profit_factor and an out-of-sample Sharpe above min_oos_sharpe;
  • the drawdown, implausible-metrics and Monte-Carlo tail-drawdown floors;
  • no loss under 2× costs (a positive cost-stressed Sharpe).

Every robustness test must still have run with a saved verdict. The selection-bias checks — deflated Sharpe, walk-forward fold rate, regime split, parameter jitter, the Monte Carlo and cost-stress verdicts, and the robustness score — are recorded at the door (shown on the strategy, used to rank the paper queue) and enforced at paper → live. mode: strict (Strict paper) is the pre-plan door: every check blocks paper, the held-back test runs before paper, and a missing source-reconciliation reading blocks. It also switches multi-coin paper strategies off.

KeyMeaningDefault
paper_door.moderesearch or strict. Settings → Lab → Door into paper.research
paper_door.min_tradesResearch door: confirmation trades needed.20
paper_door.min_oos_profit_factorResearch door: out-of-sample profit-factor floor.1.0
paper_door.min_oos_sharpeResearch door: the out-of-sample Sharpe must be above this.0.0
paper_door.holdout_stageWhere the one-shot held-back test runs: live (when the strategy applies for live) or paper (at the door). Strict paper always uses paper.live
paper_door.source_reconciliation_missingA missing or stale source-reconciliation reading: allow paper or block it. A measured divergence over the limit always blocks.allow
paper_door.walk_forward · param_jitter · regime_split · monte_carlo · cost_stress · robustness_score · deflated_sharpePer check: observe (recorded at the door, enforced at paper → live) or enforce (blocks paper). Strict paper enforces all of them.observe

paper_pool — how many strategies paper-trade at once

A strategy that passes the door takes a paper slot if one is free. If the pool, its market or its family is full, it waits in a queue (paper_queue_full) in the gauntlet stage, ranked by its recorded evidence — deflated Sharpe, robustness score, out-of-sample Sharpe, and the breadth verdict (general +0.2, mixed +0.05, home_only −0.2). Waiting is capacity, not a rejection, and never counts toward the repeated-failure auto-archive; a queue entry that isn't re-confirmed for 14 days drops. Settings are in Settings → Lab → Paper pool.

KeyMeaningDefault
paper_pool.max_strategiesStrategies paper-trading at once. 0 = no cap.40
paper_pool.max_per_marketPaper strategies on one coin. 0 = no cap.3
paper_pool.max_per_familyPaper strategies of one family. 0 = no cap.10
paper_pool.retire_enabledRetire losing paper strategies automatically.true
paper_pool.retire_min_tradesClosed forward trades before a negative average can retire a strategy.15
paper_pool.retire_max_t_statA negative forward average retires the strategy once its t-stat is below this.-1.0
paper_pool.retire_max_drawdown_pctForward paper drawdown that retires a strategy.0.15
paper_pool.retire_idle_daysDays with no paper trade (and none open) before retirement. 0 = never.60
paper_pool.retire_on_sequential_failRetire when the sequential test fails: forward trades significantly worse than the backtest, or significantly losing.true

The hourly forven-paper-pool-tick job retires first, then admits from the queue, then starts at most one breadth test. A retired strategy is archived with paper_retired:<why> (losing, drawdown, idle or sequential_fail). Live strategies are never retired here.

paper_trading — the strict paper→live gate

The gauntlet→paper gate is deliberately achievable. The paper_trading group is the strict gate that protects real capital. (The public site calls a strategy at this stage a candidate; the stage name is paper.)

paper_trading.live_gate_mode picks the forward-evidence rule (Settings → Lab → Paper to Live gates → Live gate evidence rule):

  • sequential (the default) waits for live_min_forward_trades closed paper trades and live_min_paper_days days in paper, then asks three questions. Are the forward results not significantly worse than the backtest? Does the backtest and forward evidence combined — the backtest weighted by live_backtest_weight — clear a bar corrected (Šidák) for how many strategies were in paper over the last live_pool_lookback_days days, at a live_sequential_alpha false-positive rate? Is the forward Sharpe positive? Its state is collecting, continue, go or fail; go never promotes anything by itself. A bigger paper pool raises the bar.
  • fixed is the pre-plan rule: the min_paper_days, min_closed_trades, min_paper_sharpe and min_profit_factor_paper floors.

Under the research door, this gate also enforces what the door only recorded (walk-forward fold rate, jitter, regime split, the Monte Carlo and cost-stress verdicts, the robustness score), the deflated Sharpe on backtest plus forward trades, and — last — the one-shot held-back test.

KeyMeaningDefault
paper_trading.live_gate_modesequential or fixed.sequential
paper_trading.live_min_forward_tradesSequential: closed paper trades before the test judges.20
paper_trading.live_min_paper_daysSequential: days in paper before the test can say go.30
paper_trading.live_sequential_alphaSequential: the chance that any zero-edge strategy in the pool passes.0.05
paper_trading.live_backtest_weightSequential: how much the backtest counts next to forward trades (0 = forward only, 1 = equal).0.5
paper_trading.live_pool_correctionSequential: sidak or none.sidak
paper_trading.live_pool_lookback_daysSequential: the window for counting strategies in paper.90
paper_trading.live_require_breadthSequential: going live needs a finished, current breadth test whose verdict isn't home_only. A missing run is started from the gate and keeps the strategy in paper (breadth_pending).true
paper_trading.multi_coin_enabledMulti-coin paper strategies (below). Strict paper turns them off.true
paper_trading.multi_coin_max_coinsMost coins one multi-coin paper strategy trades, its home coin included (2–15).6
paper_trading.min_paper_daysFixed rule: minimum days in paper.14
paper_trading.min_closed_tradesFixed rule: minimum closed paper trades.10
paper_trading.min_paper_sharpeFixed rule: minimum per-trade t-statistic (forward-edge proof).1.0
paper_trading.min_profit_factor_paperFixed rule: minimum paper profit factor.1.2
paper_trading.min_total_return_pctPaper return must exceed this.0.0
paper_trading.max_drawdown_pctMaximum paper drawdown.0.15
paper_trading.min_profit_factor_liveHistorical (OOS) profit-factor floor for live.1.5
paper_trading.pf_position_reduction_thresholdBelow this profit factor, a strategy is admitted at half size.2.0
paper_trading.max_oos_is_ratioOut-of-sample Sharpe may not exceed in-sample by more than this multiple.1.5
paper_trading.live_strict_robustness_enabledRe-enforce the full robustness battery at this gate.true

The return, drawdown, profit-factor and ratio keys apply under both rules.

Multi-coin paper strategies. A paper strategy whose breadth test reads general also paper-trades the coins where its unchanged rule made money in that test — home coin first, then best Sharpe, up to multi_coin_max_coins — as one record. Each coin sizes on an equal share of the strategy's paper equity, trades closed on the same UTC day count as one day of evidence, and the coin list is chosen by the breadth test and then frozen. This is paper only: going live with several coins is held (multi_coin_live_review, "Multi-coin live review pending") and the strategy keeps paper trading.

By default live promotion is never automatic: whatever these thresholds say, moving a strategy to live requires you to type GO LIVE and set a per-asset notional ceiling. (The Allow automatic go-live setting, allow_auto_live_promotion, is off by default and needs a typed LIVE to switch on.) The paper→live gate also enforces the baseline hurdle (gauntlet.wfa_baseline_hurdle_live). See promotion gates.

safety_floors — the absolute rails

Safety floors clamp the gates from outside the preset system. They are editable in Settings → Lab → Safety floors; set a floor to 0 (or a ceiling to 1.0) to remove that rail.

KeyClampsDefault
safety_floors.min_tradesTrade count behind a →paper promotion.3
safety_floors.wfa_min_foldsJudgeable walk-forward folds.2
safety_floors.wfa_fold_pass_rate_minWalk-forward fold pass rate.0.20
safety_floors.param_jitter_pass_rate_minParameter-jitter pass rate.0.30
safety_floors.mc_max_dd_p95Monte-Carlo tail drawdown (a ceiling).0.50
safety_floors.live_min_closed_tradesClosed paper trades behind a →live promotion.3
safety_floors.live_max_drawdown_pctPaper drawdown behind a →live promotion (a ceiling).0.25

The live_* floors guard the real-money gate. Loosen those with care.

live_graduated, dethrone, and testing_mode

KeyMeaningDefault
live_graduated.allocation_schedulePerformance-gated allocation ramp: 25% in weeks 1–2, 50% in weeks 3–4, 100% from week 5. Flagged drift holds it at 25%.(see below)
live_graduated.decay_kill_switch_pctSharpe degradation, over a 72-hour window, that retires a live strategy.0.30
dethrone.paper_min_soak_days / paper_max_soak_daysHow long a new paper strategy is protected from being recommended for replacement.7 / 14
dethrone.paper_min_closed_tradesAfter the minimum soak, a strategy with fewer closed trades than this stays protected until the maximum.5
testing_modeBypass the quick-screen and gauntlet gates for rapid iteration. Never bypasses the paper or live gates.false
"live_graduated": {
  "allocation_schedule": [
    {"week_start": 1, "week_end": 2, "allocation_pct": 25},
    {"week_start": 3, "week_end": 4, "allocation_pct": 50},
    {"week_start": 5, "week_end": 999, "allocation_pct": 100}
  ]
}

Other runtime settings

These keys live in the forven:settings blob, not in forven:pipeline_thresholds. Change them from the app; the paths below are what you see in GET /api/settings.

research_settings — strategy creation and the held-back test

KeyMeaningDefault
research_settings.strategy_creation_daily_budgetAutonomous strategy-creation tasks queued per UTC day (0–500). Each writes one idea and builds strategies from it. Ideas you submit don't count.40
research_settings.strategy_creation_max_in_flightCreation tasks pending or running at once (1–20).2
research_settings.agent_registration_daily_capStrategies agents may register per UTC day across all their tasks. Once reached, agents are told to stop and write up what they found, and no new creation tasks start until 00:00 UTC. Your own, MCP and Brain registrations don't count, nor do candidates archived as untestable. 0 = no cap.120
research_settings.candidate_min_feed_coverage_pctAn agent candidate whose input feeds cover less of the quick-screen window than this is archived as untestable at registration. 0 disables.50
research_settings.auto_search_gridA sandboxed strategy (an agent or Drop Zone registration) that declares no parameter_space() is optimized over ×0.8, ×1.0 and ×1.2 of up to three numeric defaults (at most 27 combinations), and the deflated Sharpe is charged the combinations tried. Off: its own parameters run once and the default trial count is charged.true
research_settings.research_holdout.enabledHold back recent data from all research.true
research_settings.research_holdout.rollquarterly (automatic) or manual (uses cutoff).quarterly
research_settings.research_holdout.lag_quartersQuarters held back (1–8). At 1, three to six months are held back.1
research_settings.research_holdout.cutoffFixed cutoff date, used only when roll is manual.(empty)
research_settings.research_holdout.paper_modeAt the gate that runs the held-back test (paper → live by default; see paper_door.holdout_stage): enforce (a pass is required), observe (run and show, never block), or off.enforce
research_settings.research_holdout.min_tradesMinimum trades in the held-back period.5
research_settings.research_holdout.max_family_shotsHeld-back tests per strategy family per cutoff. 0 = no cap.3

The creation budget, in-flight limit and registration cap are in Settings → System → Throughput (advanced). Automatic search grid is in Settings → Lab → Robustness Gauntlet (Step 2). The held-back test is in Settings → Lab → Research, under Held-back data (research holdout). With the default quarterly roll, the cutoff is the start of the current quarter minus lag_quarters quarters. Each candidate gets one walk-forward on the held-back period: by default when it applies for live, or before paper under Strict paper or with Held-back test runs at set to Gauntlet to paper. established_at is stamped when the holdout is first switched on, and strategies created before it are exempt.

lag_quarters was 2 before the gate-plan update; a one-time startup step changes a stored 2 to 1. Set it back to 2 and it stays.

Risk keys

The hard limits are documented on risk controls. Two keys are new:

KeyMeaningDefault
live_max_leverageMax leverage (mainnet): the highest leverage a live position may open at on mainnet (1–3). Forven never goes above 3× on mainnet; this can only lower it. Testnet is not capped.3
live_max_book_margin_pctLive max per-wallet margin: margin a wallet's open positions tie up (notional ÷ exchange leverage), this order included, as a percent of that wallet's equity. Replaces live_max_book_notional_pct.80

data_engine_settings — freshness, collection, storage, research universe

These back the Settings → Data sections (Data Engine, Freshness SLAs, Collection, Storage, Research universe). data_engine_settings.enabled defaults to true; the Data Engine is no longer opt-in.

sla_tiers — how current a stored series must be, by who uses it. Allowed lag is the larger of (missed bars + 1) × the timeframe and the floor. A series is late past its allowed lag and in breach past sla_breach_multiplier (default 3.0) times it.

Tiermissed_barsfloor_minutes
live120
paper245
pipeline3120
universe6360
idle241440
KeyMeaningDefault
collector.enabledThe SLA collector, which refreshes the most overdue series first.true
collector.tick_secondsSeconds between collector runs.120
collector.max_tick_secondsTime budget per run.90
collector.max_requests_per_minuteRequest budget per venue.120
collector.strike_out_afterEmpty refreshes before a series is frozen.3
storage.trash_retention_daysDays deleted series stay in the trash before they are purged.7
storage.min_free_disk_gbDownloads refuse to start below this much free disk.5.0
storage.revision_keep_daysDefault cut-off offered by the revision-log prune action (never automatic).180
research_universe.enabledDeep history for symbols beyond the trading set, for discovery.true
research_universe.sizeSymbols in the research universe, ranked by liquidity.50
research_universe.base_timeframesTimeframes every research symbol gets.["1h", "4h", "1d"]
research_universe.intraday_timeframes / intraday_topIntraday timeframes, for the top N symbols.["15m", "5m"] / 20
research_universe.minute_topSymbols that also get 1-minute bars.10
research_universe.metrics_daysDays of open-interest, long/short and taker history backfilled.365
research_universe.asset_classescrypto and/or tradfi perpetuals.["crypto", "tradfi"]

Other operational settings

  • Throughput and cadence — the throughput preset in Settings → System → Throughput writes real values into the loop intervals, worker counts, and the daily strategy-creation budget (Trickle 4, Conserve 12, Balanced 40, Max 120 tasks a day). The scheduler page covers the jobs themselves.
  • Backtest windows — the default window and the per-stage windows in Settings → Lab. See backtesting.
  • System state — system_state holds the pause flag and the autonomy mode (manual, semi_auto, or auto).
  • Notification preferences — forven:notification_preferences holds the per-event Pop-up and Discord switches and the sidebar badge switches from Settings → Notifications. See notifications.
  • Retention windows — keys such as retention_activity_log_days (default 90) drive the database pruning job. See maintenance.

Steps: change a pipeline threshold safely

Tune the pipeline from the app rather than editing stored JSON by hand:

  1. Open Settings → Lab. Pick a Pipeline stance first; it sets the stance-bound gates at once (not the quick-screen rule, the door into paper, the paper pool or the live-gate evidence settings).
  2. To change a single knob, edit it in the Lab section. The stance flips to Custom. Drawdowns and returns are shown as percentages and stored as fractions.
  3. Save. The value is written to forven:pipeline_thresholds.
  4. On the next load it is normalized and clamped by the safety floors.
  5. Promotions evaluated from then on use it. The pipeline board shows which gate each strategy is waiting on.
# Read the resolved pipeline settings over the local API
# (if FORVEN_API_KEY is set, send it in the x-api-key header)
Invoke-RestMethod -Uri "http://127.0.0.1:8003/api/settings/pipeline"

What you'll see

After you save, the Settings form shows the new value and the stance reads Custom. GET /api/settings/pipeline returns the resolved config on the next load. A value looser than a safety floor is clamped to the floor — the gate enforces the floor regardless of what you stored, unless you change the floor itself.

Caveats

  • Environment beats everything. FORVEN_ALLOW_MAINNET is read from the environment only and cannot be set from the app. Paper is the default and supported mode; mainnet is default-deny and unsupported.
  • Fractions, not percentages. Drawdown and return keys are stored as fractions (0.30 = 30%).
  • Safety floors win. A preset or custom value can't go below them; only changing the floor itself can.
  • Stale config self-heals. Missing or unsafe keys are repaired on load — don't rely on hand edits to remove a required test; it will be restored.
  • The defaults on this page are illustrative values from the current build, not guarantees, and may change between releases.
  • Promotion gates — stance presets side by side, and how these thresholds are enforced
  • Environment variables — the variables at the top of the precedence stack
  • Settings — the app hub that writes most of these values
  • The gauntlet — the robustness tests these thresholds judge