Creating and configuring a market

The four-step create wizard, every field it writes and the validation that rejects it, plus the price controls that only appear afterwards — price mode, bias, forced phase, volatility and the target price.

6 min readUpdated 3 August 2026markets, configuration, price-range, volatility, bias

A market maker attaches one-to-one to an ecosystem market. The marketId column carries a unique index, so the second attempt on the same pair is refused with "AI Market Maker already exists for this market".

Creation happens in a four-step wizard at /admin/ai/market-maker/market/create. Everything else — price mode, bias, phase, volatility, the running-state controls — lives on the market's own Configuration tab afterwards.

What creation actually produces

One request writes four things in a single transaction:

  • the market maker row, status STOPPED;
  • a pool with zero balances on both sides;
  • six bots, all PAUSED — Scalper Alpha, Scalper Beta, Swing Trader, Accumulator, Distributor and Market Maker;
  • a CONFIG_CHANGE history entry recording the parameters it was created with.

Nothing trades. The market is created stopped on purpose: it has to be funded and started deliberately.

Step 1 — Select market

The list offers ecosystem markets that do not already have a market maker. The target price field is pre-filled from the market's own metadata price where one exists.

Step 2 — Price settings

Two inputs: a target price and a range, expressed as a percentage either side of it. The wizard converts that percentage into the two absolute bounds the API stores.

priceRangeLow  = targetPrice x (1 - percent/100)
priceRangeHigh = targetPrice x (1 + percent/100)

The API validates the result, and every one of these is a hard refusal:

Rule Message
All three prices above zero "Target price must be greater than 0"
priceRangeLow < priceRangeHigh "Price range low must be less than price range high"
Target inside the range "Target price must be within the price range"
Deviation from target at most 50% on each side "Price range deviation from target must be within 50%"
No value below 0.00000001 "Price values must be at least 0.00000001 (8 decimal places)"

The price process is contained inside the band you configure — but the restoring force only engages in the outer 20% of it. Once it is pulling, the direction of the next move becomes progressively predictable, which on a synthetic market is an exploitable edge and on one that settles binary options is a free bet.

That is why the dashboard reports at range edge as its own state rather than lumping it in with "inside the band": you can still fix it by widening the range, before the price actually leaves. A range too tight for the configured volatility also produces a startup warning in the server log naming the edge an observer would hold.

The band is measured geometrically, not linearly. On a range of 1 to 100 the centre is 10, not 50.5 — so a market sitting exactly on its anchor reads as centred rather than as 90% of the way to the floor.

Step 3 — Trading configuration

Aggression is a 1–10 slider that maps onto the three levels the API stores:

Slider Level Bot risk tolerance Bot average order size Bot daily trade budget
1–3 CONSERVATIVE 0.3 50 1,200
4–7 MODERATE 0.5 100 3,500
8–10 AGGRESSIVE 0.8 200 9,000

Those figures seed the six bots at creation and are editable per bot afterwards. They are sized from measured density, not from nominal arithmetic: a MODERATE market prints roughly 3,500 trades a day, one every 25 seconds on average, about every 10 seconds across the US/EU overlap and every 35 seconds overnight.

Older builds seeded 50/100/200 daily trades, which a market spent inside the first hour of each UTC day and then printed nothing at all until midnight. The allowance is now paced across the whole day along an activity curve, so an old market with an old number is strictly better off — the same allowance simply lasts until midnight. If it reads as abandoned rather than conservative, raise maxDailyTrades on its bots.

Real Liquidity (0–100) is the share of each trade's size that is placed as a genuine resting order in the Ecosystem book, backed by the pool. Zero means bot-to-bot only — a price series and a tape with no user-fillable orders and no money at risk. Start there.

Max daily volume is a hard trade gate, not a target. A market that reaches it stops quoting until the daily UTC reset. Its counter is currentDailyVolume, and it is zeroed by the daily reset job — so it is volume today, never a rolling 24 hours.

Step 4 — Review

The review step restates what will be created. Creating writes the transaction described above and lands you on the market's detail screen.

After creation: the Configuration tab

These controls do not exist in the wizard. Each is its own endpoint, each writes a history entry, and — since v6.1.5 — each applies to the running market immediately rather than at the next full reload.

Price mode

How the price relates to the outside world
  • AUTONOMOUS — the price process alone. No external reference.
  • FOLLOW_EXTERNAL — tethered to an external symbol at correlationStrength (0–100).
  • HYBRID — the same tether at half that strength. It is a blend, not a peg.

externalSymbol is required for both non-autonomous modes; the request is refused without it. The external price is fetched on a slow cached cadence, off the price step, so a slow exchange can never stall a tick.

The first time a tether engages, the server log states the estimated directional edge a client watching both feeds would hold over the next hour. That is a legitimate configuration for an ordinary market and a poor one for a market that also settles binary options. Use AUTONOMOUS there.

Market bias

Directional guidance for phase transitions
How strongly bias affects phase transitions

BULLISH, BEARISH or NEUTRAL, with a strength of 0–100. Bias influences how the market moves between phases; it is not a guaranteed direction.

Volatility

Base daily volatility percentage
Multiplier applied to the current phase
How quickly momentum decays

Accepted ranges are 0.120 for base volatility, 0.52.0 for the multiplier and 0.80.999 for momentum decay. At least one of the three must be present or the request is refused.

Volatility is integrated against wall-clock time, not against tick count, so a market's realised volatility matches what you configured regardless of how often the engine happens to tick, and a restart resumes on the correct distribution.

Market phase

Four Wyckoff-style phases — ACCUMULATION, MARKUP, DISTRIBUTION, MARKDOWN. The market transitions between them on its own; Market Phase Control forces one, bypassing the normal transition rules, and the response says so.

A forced phase now reaches the live market and expires when told to. Its volatility multiplier is applied by the engine only — an older build applied it twice, once in the engine and once written back onto the market's own volatility setting, so a forced phase ran at roughly 2.25x the volatility intended.

Target price

The price the market steers toward

Must sit inside the configured range or the request is refused with the range quoted back. A move of more than 5% is flagged as a large change but still allowed.

The price sync job warns when a target price has drifted more than 10% from its external reference, at most once per market per hour.

Reset daily counters

Zeroes currentDailyVolume and the bots' dailyTradeCount immediately rather than waiting for the UTC reset. Use it to bring a market that has spent its budget back to quoting inside the same day — but understand that you are handing out a second full allowance, and the budget existed for a reason.

Editing the core fields later

The same fields the wizard writes are editable from the Configuration tab: target price, both range bounds, aggression, max daily volume, volatility threshold, pauseOnHighVolatility and real liquidity percent. Validation is identical to creation.

Only fields that actually changed are recorded in history. An earlier build compared a DECIMAL column (which arrives from the database as a string) against a number, so every save wrote a CONFIG_CHANGE for fields nobody had touched — and a market with a 9–10 range could not be edited at all, because "9" > "10" is true as text.

Deleting a market maker

Deleting stops the market through the engine first, waits up to ten seconds for the engine to confirm, cancels the bots' open ecosystem orders so locked funds return, and only then removes the row. The pool, the bots and the entire history cascade with it.

Withdraw the pool before you delete. Nothing warns you that you are deleting money.