← fxLadderMM

fxLadderMM — Status & roadmap

BLOCKEDAudited 2026-09-13· hand-written (no shared engine) engine· quantroduction· spot

Where this strategy is today

BLOCKED — the code is correct, uniform and shippable. That is a statement about engineering, not about profitability; the performance verdict is separate and sits below it.

Dimension State
Correctness failing
Console output 3 tagged calls, 0 off-format
Side panel 29 rows, padded to the 3-column grid
Chart marks reference-levels
Palette 8 / 8 canonical
GUI settings 28 exposed · 0 read at runtime · 0 untunable · 0 inert
Deployed to a live install Not yet — audited and staged, not yet shipped

Performance verdict. Over three years on 7 markets it returns a median -95.9% against buy-and-hold's 39.2% — an edge of -134.7% — and is profitable on 0 of 7. On this window it is not a replacement for simply holding the asset, and nothing in these reports claims it is.

What it actually does

A hand-written Quantroduction quoting market maker — no shared generator engine. It stands a three-tier limit-order ladder on both sides of a reservation price and re-quotes it every cycle.

The header is explicit about its intended market: "TARGET PAIRS: EUR/USDT, GBP/USDT, AUD/USDT, BRL/USDT, NZD/USDT", and the vol regimes are calibrated for FX. It is measured here on crypto majors, where the same estimator reports 45 to 94 pips per cycle against an EXTREME threshold of 6 — so on every market in this test set it runs permanently in its widest regime.

Read from the shipped strategy source, not from its documentation.

The measured constraint

Time in market is 92.3%, over 42775 round trips across all 7 markets and three years. Everything in the performance report rests on that fraction of the bars.

Settings, measured

This strategy does not use the engine config surface.

What to build next

Ordered by expected effect on the result, not by effort.

1. Do not run this on crypto. It pays 130% of the account in fees.

Highest priority

Over three years on seven crypto markets this strategy returns a median −95.9% with a 96.6% maximum drawdown, against a buy-and-hold that returned +39.2%. It is unprofitable on 7 of 7 markets and beats buy-and-hold on 0 of 7.

The cause is not subtle and does not need a theory. Median fee drag is 130.4% of the account: across 193,232 fills at 0.10% maker per side, the strategy pays more than the entire account in fees over the window. No arrangement of the quotes can recover from that.

The arithmetic was fixed at design time. The ladder quotes 0.5, 1.5 and 2.5 basis points from the reservation price. A round trip at the widest tier grosses 0.05%. One round trip costs 0.20% in maker fees at the tier this pack's engine models. The spread it quotes is a quarter of the fee it pays, so every completed round trip loses about 0.15% before any question of skill arises.

That is not a flaw in the design — it is the design being used outside the conditions it states. The file's own header names EUR/USDT, GBP/USDT and AUD/USDT, where spreads are tight and fee tiers for a genuine maker are rebate-bearing. The shipped FL_MAKER_REBATE of −0.015% says exactly that: it expects to be paid to quote. On a book that charges 0.10% instead, a 0.5-pip ladder is a machine for donating fees.

So the recommendation is conditional, not dismissive. On a rebate venue, in FX pairs, at FX volatility, this strategy is doing something reasonable and has not been tested here. On crypto majors at ordinary spot fees it should not be run at all, and the fee gate added in this audit now says so in the log rather than leaving it to be discovered.

2. The −4% result it used to report was a strategy that had quit

Highest priority

Before this audit the strategy reported a median −4.0% return with a 4.2% maximum drawdown, pinned within a tenth of a point of FL_MAX_DD (4) on six of seven markets. That reads as disciplined risk control.

It was a stuck switch. peakEquity only ever rises, so the drawdown it feeds is a lifetime drawdown, while the flag it sets is cleared once a day. Once equity was 4% below its all-time high the daily reset cleared the flag and the next cycle immediately re-set it. Measured: on six of seven markets the strategy placed its last order within the first nine days of a 1,157-day window and never traded again.

The fix is one line — reset the peak with the flag — and it moves the median return from −4.0% to −95.9%. Nothing got worse; the −4% was never a result.

This is worth carrying to the rest of the pack as a search pattern rather than a one-off repair. Any strategy whose reported maximum drawdown sits suspiciously close to its own configured limit, with very low time-in-market, should be suspected of this before it is praised for it. The pack's own note that a good-looking result usually means a strategy stopped trading has a concrete mechanism here.

3. It is a market maker that buys 3.5 times as often as it sells

High priority

The header states a non-directional invariant: equal notional per tier per side, inventory corrected only by reservation-price shift, never by size skew. The code honours that — both sides are quoted with the same tierNotional.

The fills do not. Over the window it took 150,457 buys against 42,775 sells, and median exposure is 92.3%. It is long almost all of the time.

Nothing in the quoting logic causes that; the market does. A resting bid is hit when price is falling and a resting offer is lifted when price is rising, so in any market with a trend a symmetric ladder accumulates the losing side. This is ordinary adverse selection, and it is the risk a market maker is paid the spread to bear — except that here the spread is a quarter of the fee, so it is bearing the risk and paying for the privilege.

Two measurements would separate the two failures, which currently compound: re-run with fees set to zero to isolate adverse selection from fee drag, and re-run with the inventory band (FL_MAX_INV 75 / FL_MIN_INV 25) tightened to 60/40 to see whether a harder cap converts the loss into a smaller one. The zero-fee run already exists as a by-product of the cost-independence invariant and showed 288,073 buys against 150,457 — so fees are suppressing about half its activity, not correcting its direction.

4. It fails the cost-independence invariant, and here that is a symptom rather than the disease

Worth testing

The pack's cost-independence invariant asks whether fees change the P&L or the ability to act, and fails a strategy that places less than half as many buys when fees are charged. This strategy places 150,457 with fees against 288,073 without — a ratio of 0.52 across the pack, but 0.497 on ADA, which fails it.

That is worth reading correctly. The invariant exists to catch a strategy whose logic is accidentally gated on a fee-dependent quantity. Here nothing is gated: the strategy simply runs out of account. It pays 130% of its capital in fees, so the fee-charged run has less money to quote with and places fewer orders. The invariant is firing on a real difference, but the finding it points at is the fee drag above, not a logic bug.

No fix is proposed for the invariant itself. It is doing its job — a strategy that cannot afford to trade is a strategy whose ability to act depends on fees, and flagging that is correct.

5. It has never been tested on the pairs it was written for

Worth testing

The pack's seven-market test set is ADA, BTC, DOGE, ETH, LINK, SOL and XRP. This strategy's header names EUR/USDT, GBP/USDT, AUD/USDT, BRL/USDT and NZD/USDT, and every threshold in it is scaled for those: pip-denominated depths, a 6 bp/cycle EXTREME volatility threshold, three tiers rather than five because "FX books on crypto exchanges are thinner".

On the crypto test set the Garman-Klass estimator reports 45 to 94 pips per cycle. The strategy therefore spends the entire window in its EXTREME regime, with depths widened to 12–21 pips instead of the 0.5–2.5 it was tuned for. Every number in this report describes a strategy running permanently outside its declared envelope.

That is not a reason to discount the numbers — an operator who selects this strategy in the GUI and points it at BTC gets exactly this — but it is a reason not to read them as a judgement of the design. The useful next step is data, not tuning: fetch EUR/USDT and GBP/USDT at 1h and re-run. the market-data fetcher takes any Binance symbol, so this is an afternoon's work, and it is the only way to say anything true about whether the strategy works.

6. What this audit repaired

Read before acting on the others

Four defects, two of which changed behaviour substantially:

One repair was deliberately not made: the fallback idiom that stops 27 settings holding the value 0 is still present, because this file divides by three of those knobs and the pack's fixer correctly refuses to create a division by zero. That one needs per-knob work.

The strategy remains BLOCKED on the cost-independence invariant, and on this test set it should stay that way.

Operator output, measured

Everything below was read out of the strategy file by the presentation audit, not taken from its documentation. These are the surfaces an operator actually watches: the terminal log, the side panel, the chart, and the settings the GUI offers.

Terminal log
Tagged, aligned, coloured
3
Raw and off-format
0
Exempt (object and error dumps)
7

Every non-exempt line carries the strategy name, an event tag and the palette colour for that tag, so one terminal running many pairs stays readable.

Side panel
Data rows
29
Section headers
7
Rows with no tooltip
7
Padded to the 3-column grid
yes
Chart marks
Model
reference-levels

draws price levels into customChartTargets and no per-trade marks, so there is no intent-vs-fill distinction to get wrong

Colour palette
Non-canonical colours
0

One colour per meaning, identical in the log, the panel and the chart — the eight canonical roles.

Settings the GUI exposes

28 settings appear in the Gunbot strategy editor for this strategy. Which of them the code reads has not yet been measured for this lineage: it does not use the shared config surface, so there is nothing to wrap with a recording proxy.

LOG_LEVELWARMUP_CYCLESFL_PIP_BPSFL_NUM_TIERSFL_BASE_DEPTHFL_TIER_DEPTHFL_VOL_LBFL_VOL_EMAFL_VOL_DEPTH_MULTFL_MAX_SHIFTFL_MAX_INVFL_MIN_INVFL_REQUOTE_CYFL_DRIFT_REQFL_SPFL_MAX_FILLS_HRFL_PAUSE_CYMIN_ORDER_QUOTEFL_TLFL_CAPITAL_ALLOCFL_SIZE_PCTFL_SIZE_DECAYFL_INV_TARGETFL_INV_GAINFL_MAX_DDFL_DAILY_LOSSFL_MAKER_REBATEFL_TAKER_FEE

Open presentation findings