Global settings

Every AI Market Maker setting — the four global switches, the concurrency cap that is not what its label says, the risk limits, history retention and the one environment variable — with what each actually gates.

5 min readUpdated 3 August 2026settings, configuration, kill-switch, retention

Global settings live at /admin/ai/market-maker/settings, behind access.ai.market_maker.settings. They are stored in the platform's central settings table and saved through the shared settings endpoint, so a change invalidates the settings cache and reaches every process without a restart.

Four tabs: Trading, Bots, Risk and Emergency.

The platform stores every setting as a string. false is the string "false", which is truthy in JavaScript. All four global switches on this screen once compared against a true/false value and could therefore never match whichever way they were flipped — Enable AI Trading, Global Pause, Maintenance Mode and Enable Stop Loss all read as working controls and had no effect on anything.

They work now, and accept every form the settings screen and the API actually produce: true/false, on/off, yes/no, 1/0. If you are on a build before v6.1.5, do not rely on any of them.

Trading

Master switch for the whole AI trading system
Temporarily pause all trading activity
Maintenance mode — also disables trading
Days of per-trade history to keep

Enable AI Trading is read by the engine and by every scheduled job. With it off, the risk monitor and the price sync skip their passes entirely.

Global Pause and Maintenance Mode suppress trading only. Prices and charts keep advancing, and nothing jumps when the pause is lifted.

Halting the engine outright would freeze every market's price, flatten every chart, and produce a visible gap the moment the pause ended. Suppressing trades while the price process keeps running avoids that. Nobody ever saw a frozen chart from this, because none of the global gates could fire before they were fixed — this is the companion change that makes turning them on safe.

Trade History Retention governs processAiHistoryRetention. This is the addon's largest table by a wide margin: a MODERATE market writes about 3,500 rows a day and an AGGRESSIVE one about 9,000. 0 keeps everything. Anything below 2 is treated as 2, because the daily summariser reads yesterday's trades. Daily summaries and lifecycle audit rows are never pruned.

Bots

Ceiling on how many markets the engine will drive at once

The engine reads it into maxConcurrentMarkets. The market manager refuses to load a market once that many are already running, logs "Max concurrent markets reached", and returns a failed start. The label on the screen is wrong; the behaviour is what matters.

The symptom is specific and easy to misread: markets that will not start, with no error on the admin screen, and a dashboard alert saying the engine holds fewer markets than the database says are ACTIVE. Accepted range is 1–500; the engine falls back to 50 if the setting is unreadable.

Risk

Minimum quote balance a pool needs before its market may start
Maximum allowed daily loss, as a percentage of capital
Default volatility threshold for markets that do not set their own
Enable automatic stop-loss for all trades

Minimum Liquidity is checked twice — by the status endpoint when you press Start, and again by the engine when it loads the market. Both compare it against the pool's quote balance, not its TVL. A market that passes the first check and fails the second fails to start with the reason in the log and nothing on screen.

Max Daily Loss (0–25%) is the platform-wide limit. Breaching it trips the circuit breaker, which gates every market at once. A single market that loses more than its own limit is paused on its own; only a book-wide loss halts everything. See Risk and emergency controls.

Volatility Threshold (0–50%) is the fallback for a market that has not set its own volatilityThreshold. It is a measured daily percentage, computed from the engine's own published price on every tick and scaled using the real spacing between samples.

Before v6.1.5 volatility was only ever sampled inside the branch handling a successful external exchange price — a path an autonomous market never reaches. Two features read that number and both were therefore inert: the high-volatility auto-pause, which never ran once, and the spread quoted on real-liquidity orders, which was pinned at its minimum no matter how violently the price moved.

Emergency

The Emergency tab hosts the fleet-wide stop. It is documented in full on Risk and emergency controls.

The dashboard's emergency stop requires a written reason and stores it on every market's history entry. The panel on this screen still posts without one, so a stop triggered from here records the fallback sentence "Emergency stop triggered by admin". Use the dashboard's button if you want the record.

Per-market settings

These are not on this screen. They live on each market's Configuration tab and are documented in Creating and configuring a market:

Setting Range Gate it feeds
targetPrice Inside the price range Steering
priceRangeLow / priceRangeHigh At most 50% either side of target Containment
aggressionLevel CONSERVATIVE, MODERATE, AGGRESSIVE Bot seeding only
maxDailyVolume 0 or more Hard trade gate
volatilityThreshold 0–100 Hard trade gate, when the pause is on
pauseOnHighVolatility on/off Enables that gate
realLiquidityPercent 0–100 Whether real orders are placed at all
priceMode + externalSymbol + correlationStrength External tether
marketBias + biasStrength 0–100 Phase transitions
baseVolatility / volatilityMultiplier / momentumDecay 0.1–20 / 0.5–2.0 / 0.8–0.999 Price process

The environment variable

Ceiling on resting real orders per market, for every market at once

A market that reaches the ceiling stops placing new real orders until existing ones fill or expire, and says so once in the log. It refuses to place rather than force-cancelling the oldest quote: cancelling mid-tick races the matching engine's settlement, and a maker sitting at its ceiling is something you should see rather than have quietly worked around.

500 is generous — a maker showing depth at 20 levels a side needs 40 — and small enough that hitting it is unmistakably a leak rather than a busy market. A market can carry its own maxRestingRealOrders; the environment variable is the blunt instrument for moving every market at once during an incident.

Before v6.1.5 every print appended a new resting LIMIT order to the real Ecosystem book and nothing reliably removed the previous one — no refresh cycle, no cancel-before-replace, no cap. One live market reached 704,353 open orders. The backend loads open orders at startup, so that one market made the API take minutes to bind its port: the site served connection refused while the log filled with successful startup messages.

Orders accumulated before the fix do not disappear on update. Clean them with pnpm eco:mm:orders:clean.

What is not configurable

  • The engine tick interval is fixed at 1 second. Trade cadence is driven by the bots' daily budgets and the intraday activity curve, so changing the tick rate could not change how often a market trades even if you could reach it.
  • Bot personalities are seeded and cannot be changed.
  • The two-bot minimum is a constant in the engine.
  • The 20% band edge where containment engages is a constant in the price process.