ADAMANT Market-making bot: A Safer, Smarter Spread Support
0
1
Spread Support liquidity orders have always been one of the more powerful parts of the ADAMANT Market-Making Botāāāand also one of the most delicate.
They help keep spreads tight, make books look healthier, and improve tradability. But that strength comes with a challenge: if the logic is too naive, Spread Support can become exploitable. Refill loops can keep recreating exposure, volatile conditions can distort placement decisions, and one-sided market moves can turn a useful liquidity mechanism into a source of avoidable risk.
This update addresses that problem with a substantial three-phase upgrade. It introduces a dedicated simulation tool, separates Spread Support and Safe Liquidity into optional submodules, and replaces the old repeatable refill logic with a bounded mirror strategy designed to preserve tight spreads without opening unlimited lossĀ loops.

The result is a more testable, more modular, and much safer liquidity system inside the Premium version of the ADAMANT Market-Making Bot.
Premium mm bot: https://marketmaking.app/
The āLiquidity SS Upgradeā issue overview: https://github.com/Adamant-im/adamant-tradebot/issues/100
Why this upgradeĀ matters
Liquidity logic should do more than place orders. It should also behave predictably underĀ stress.
That is especially true for Spread Support (SS). Unlike depth-based liquidity, which naturally respects average buy and sell prices, SS orders exist to support the spread itself. That means they can be much more sensitive to hostile fills, sudden directional moves, or placement rules that make sense in calm conditions but break down in volatileĀ ones.
This release focuses on that exact boundary: how to keep Spread Support useful without letting it become an open-ended riskĀ source.
Phase 1: a simulation and visualization tool for SSĀ behavior
Before changing core logic, we built a dedicated standalone tool to inspect Spread Support behavior in a controlled environment.
The new harness consistsĀ of:
- trade/tests/liquidity_test.js
- trade/tests/liquidity_test.html
It runs as a standalone Express + Socket.io application and gives operators and developers a direct way to observe SS behavior before and after algorithm changes.

It supports twoĀ modes.
In paper mode, the tool keeps a single order book snapshot in memory. Spread Support iterations can be triggered manually, and clicking a price level simulates full fills of all orders up to that level. This makes it easy to reproduce edge cases, inspect reactions, and verify how the algorithm evolves after each iteration.
In live mode, the tool continuously refreshes the order book from the exchange and works with real ordersDb records. Iterations are still manually triggered, but the environment reflects actual market conditions.
The HTML interface was built to make SS behavior visually obvious. It includes a color-coded order book table that distinguishes external orders, depth liquidity, SS orders, and mirrored orders. It also includes a statistics panel with open, filled, and cancelled SS counts per side, buy and sell VWAP values, and per-iteration deltas. A read-only tradeParams panel shows the active runtime state, while manual controls allow operators to trigger SS liq iteration, inspect state changes, and even copy cell values with right-click. Every iteration highlights what changed, making the algorithm easier to reasonĀ about.
This tool matters because it turns liquidity behavior from something inferred from logs into something directly observable. That makes both development and verification much more reliable.
Phase 2: extracting Safe Liquidity and Spread Support into optionalĀ modules
The second phase was structural. It did not aim to change behavior. It aimed to make the system cleaner, easier to maintain, and more flexible across different builds.
Previously, core Safe Liquidity state and Spread Support placement logic lived inside mm_liquidity_provider. That worked, but it tightly coupled several distinct concerns inside oneĀ module.
This release separates them into two dedicated modules:
- trade/mm_liquidity_safe.js
- trade/mm_liquidity_ss.js
Safe Liquidity module
The new mm_liquidity_safe.js encapsulates the liqLimits state and all relatedĀ helpers:
- updateLiqLimits()
- loadLiqLimits()
- storeLiqLimits()
- resetLiqLimits()
- getLiqLimits()
- getVwapRangeString()
It processes only depth fills, using a strict subPurpose === ādepthā filter. That keeps Safe Liquidity focused on what it is supposed to track: depth-based execution history and the limits derived fromĀ it.
Spread SupportĀ module
The new mm_liquidity_ss.js encapsulates Spread Support behavior itself, including:
- updateSsLiquidity(liquidityOrders, orderBookInfo)
- updateSsVwap()
- SS priceĀ logic
- SS order-count limits
- mirror placement logic
Constants such as minimum and maximum SS orders per side were moved here as well, making the module self-contained.
Backward-compatible loading
The main mm_liquidity_provider.js now loads both modules through utils.softRequire().
That detail is important. These modules are optional.
If either one is missing, the bot still works correctly. Depth liquidity continues to operate. If mm_liquidity_safe is absent, Safe Liquidity limits are simply inactive. If mm_liquidity_ss is absent, Spread Support is inactive. No crashes, no broken flow, no need for separate code branches.
This is not a breaking rewrite. It is a modularĀ upgrade.
The provider also now delegates SS-specific closing rules to the SS module when present, replaces the inline SS placement loop with ss.updateSsLiquidity(), and refreshes the order book after SS placement so depth orders can use a current mid. That last detail improves order placement consistency by ensuring later modules work from fresh marketĀ state.
Phase 3: replacing refill loops with a bounded mirrorĀ strategy
This is the core behavioral change of theĀ release.
The old repeatable refill pattern could keep recreating exposure in ways that were undesirable under certain fill scenarios. The new strategy takes a different approach.

The core mirrorĀ rule
When a regular SS order is filled, the bot places a mirror order on the opposite side at the reflected price and with the sameĀ size.

It does not place a replacement on the sameĀ side.
That sounds simple, but the consequences are significant. Instead of endlessly refilling where liquidity was just consumed, the system acknowledges the fill and responds with a bounded counterpart across the spread. This keeps the market tighter without creating an unlimited feedback loop of same-side replenishment.
Mirror order properties
Mirror orders are explicitly markedĀ with:
- subType: āmirroredā
- subTypeString: ā (ss mirrored)ā
- priceCorrected: true
That last field is especially useful. It allows existing closeLiquidityOrders logic to skip valid mirrored orders even when they sit outside the normal SS spread window. In other words, mirrors can survive where they are supposed to survive without needing a separate cancellation pathway.
Cascade prevention
One major danger in mirrored logic is recursive behavior: a mirror gets filled, then mirrored again, then mirrored again, and soĀ on.
That is explicitly blocked.
Filled mirror orders are not mirrored further. The module checks subType, and once a mirror is created, the original order is marked as mirror-source. This prevents cascade chains and keeps the mechanism bounded.
Risk controls inside the mirrorĀ strategy
The mirror algorithm was designed not just to respond, but to respond safely. Several controls were added for thatĀ reason.
Mirror distanceĀ cap
If the mathematically ātrueā mirror price would land too far from mid, the bot does not blindly place it there. Instead, it falls back to a bounded price near the SS spreadĀ edge.
This prevents mirrors from ending up so far away that they become detached from meaningful liquidity behavior.
VWAP relevance guard
SS now maintains its own fill statistics through a dedicated fillsEngine epoch keyed with subPurpose: āssā. That means the bot can track SS buyVWAP and sellVWAP separately from depth liquidity.
But historical VWAP is only useful while it remains relevant. If SS VWAP drifts too far from current mid, it is treated as stale and ignored for placement constraints. The relevance threshold is set atĀ 2%.
This matters after strong directional reversals. Without such a guard, an old VWAP anchor could keep SS logic trapped on one side of the market long after conditions changed.
Wide-spread relaxation
In volatile markets, the external spread may temporarily grow much wider than the intended SS zone. When that happens by a defined multiplier, mirror occupancy checks are relaxed so Spread Support can continue operating instead of freezing due to strict placement assumptions that no longer fit theĀ market.
Bounded new regular SS placement
Regular SS placement now also respects SS VWAP when it is relevant. New regular buys are placed below SS buyVWAP, and new regular sells above SS sellVWAP.
That further reduces the chance of repeatedly adding fresh exposure at increasingly unfavorable levels.
Better statistics, better visibility, better operatorĀ control
This release also significantly improves observability and commandĀ output.
/stats improvements
The /stats command is now more accurate and more readable:
- it validates pairs through parseCommandParams
- accepts any pair or perpetual ticker, not just the defaultĀ pair
- formats 24h spread values inĀ bold
- uses stable precision for volumeInCoin2
- shows trading volume and executed-order statistics only for the defaultĀ pair
- includes ladder (ld) orders in executed-order stats
- adds a NotesĀ section

These changes are not cosmetic. They reduce confusion and make the command reflect context correctly.
New /orders liq full liquidity panel
A new rich liquidity statistics view is now available through /orders liqĀ full.
It includes:
- a Depth liquidity block with status, spread parameters, order counts, open amounts, Safe Liquidity limits, and fillĀ history
- a Spread Support block with SS spread range, order-size limits, regular and mirrored order counts, SS fill stats, VWAP, and MTMĀ PnL
- a Combined total block that aggregates depth and SS fillĀ data
- the current liquidity epoch startĀ time
- exchange minimum order information
- current order book information via reusable depthĀ helpers
Fill statistics tables are rendered in a compact four-column layout: label, Buy, Sell, andĀ Delta.

This gives operators a much clearer picture of what liquidity is doing right now and how it gotĀ there.
/orders liq and /orderbook improvements
The regular liquidity order list now shows percentage filled for partially filled orders and includes subPurpose and subType labels for liquidity orders, such as ss, mirrored.
The /orderbook command now includes a new Purpose column that shows which bot modules correspond to each price level. That information is derived from live ordersDb records, so the operator can immediately see whether a level belongs to depth liquidity, SS, mirrored liquidity, or another bot subsystem.

Safer operatorĀ commands
The /enable liq command now includes a confirmation step before changing liquidity parameters. It also validates build capabilities: depth range notation is rejected if mm_liquidity_safe is absent, and ss parameters are rejected if mm_liquidity_ss is absent, with a clear message explaining the limitation.
A new /enable liq reset subcommand resets mm_liquidityInitTs and clears liqLimits, effectively restarting the VWAP epoch after confirmation.
Manual /buy and /sell commands also received an important safety improvement. If a requested order price deviates from market by more than 1000%, the bot stops and asks for confirmation with /y. This protects operators from accidental extreme-price orders caused by stale assumptions or input mistakes.
Finally, /account info now handles empty fee lists from exchange APIs more gracefully and shows a proper message instead of blankĀ output.
No breakingĀ changes
One of the strongest parts of this release is that it delivers a substantial internal upgrade without introducing hard breakage.
Both mm_liquidity_safe and mm_liquidity_ss are optional. If either is absent, mm_liquidity_provider continues to operate correctly. Depth liquidity remains active. Safe Liquidity and Spread Support are simply inactive where unavailable.
The only format-level evolution is that fillsEngine stats keys may now include an optionalĀ :
What this release reallyĀ changes
At a high level, this upgrade does threeĀ things.
First, it makes Spread Support visible. The simulation tool turns hidden liquidity behavior into something that can be inspected, replayed, and validated.
Second, it makes Spread Support modular. Safe Liquidity and SS are no longer entangled inside one provider path, which makes builds cleaner and maintenance easier.
Third, and most importantly, it makes Spread Support safer. The mirror strategy replaces a more repeatable refill model with a bounded response pattern designed to keep the spread tight without enabling runaway lossĀ loops.

For market-making systems, that is the right direction: not more activity for its own sake, but smarter behavior under real market pressure.
Looking ahead
Spread Support is useful precisely because it sits close to the marketās most sensitive zone: the spread itself. That also means it needs stronger controls, clearer visibility, and better operator tooling than simpler liquidity mechanisms.
This release moves ADAMANT Market-Making Bot decisively in that direction.
The bot now has a dedicated SS simulation environment, cleaner liquidity architecture, richer liquidity reporting, safer operator controls, and a mirror-based Spread Support mechanism that is designed to be both practical andĀ bounded.
In other words, Spread Support is no longer justĀ tighter.
It is more understandable, more maintainable, and much harder toĀ exploit.
ADAMANT Market-making bot: A Safer, Smarter Spread Support was originally published in ADAMANT on Medium, where people are continuing the conversation by highlighting and responding to this story.
0
1
Securely connect the portfolio youāre using to start.




