Donchian_Reversion_MM — Status & roadmap
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 | 19 tagged calls, 0 off-format |
| Side panel | 6 rows, padded to the 3-column grid |
| Chart marks | drawn only after the exchange confirms a fill |
| Palette | 8 / 8 canonical |
| GUI settings | 32 exposed · 32 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 -85.3% against buy-and-hold's 49.6% — an edge of -134.9% — 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
The pack's shared MM-DCA template with its selector MM_signal set to donchian. One file, fifteen possible strategies; the other fourteen signals and their settings sit dormant until the selector is changed. Fourteen other strategies in the pack are this same file with a different value.
With donchian selected it is a channel mean-reversion buyer:
- The channel.
donchian(h, l, MM_period=10)gives the 10-bar low, the 10-bar high and their midline, plusATR(MM_atrPeriod=10)for the padding. - Entry. Price at or below the lower band plus half an ATR —
price <= lower + atr × MM_entryPad(0.5). That adds one layer ofMM_tl(50 quote), decaying byMM_decay(0.75) per layer, up toMM_maxDca(3) layers, each further layer also requiring priceMM_step(0.3%) below the previous entry. Exposure capped atMM_maxExp(80%). - Exit — whole position, first match wins: hard stop at −
MM_maxDd(8%) from break-even; TTL atMM_maxHold(150) cycles; profit target atMM_gain+MM_fee(0.22% after this pack's fee repair); then the indicator exit,price >= midline − atr × MM_exitPad(0.5).
So it buys the bottom of a 10-bar channel and sells at the middle of it. The distance between those two is the trade, and on an hourly chart it is small — which is why the strategy takes 415 round trips per market in three years and holds a position only 9% of the time.
The exit ladder is the part worth knowing. Measured across all seven markets, 80.4% of exits are the profit target, 17.2% are the indicator, 2.4% are the stop, and the TTL never fires once in 2,509 exits.
Read from the shipped strategy source, not from its documentation.
The measured constraint
Time in market is 10.5%, over 8657 round trips across all 7 markets and three years. Everything in the performance report rests on that fraction of the bars. A strategy out of the market 89% of the time is not therefore a low-risk one: the 85.6% drawdown happens entirely inside the time it is committed.
Settings, measured
The GUI exposes 32 settings. Which ones this strategy actually reads was measured by running it with a recording config proxy rather than inferred from the source — a mm-dca file bakes 32 keys and only the active mode's branch reads any of them.
- Read at the shipped defaults:
MM_atrPeriod,MM_dcaMode,MM_decay,MM_entryPad,MM_exitPad,MM_fee,MM_gain,MM_maxDca,MM_maxDd,MM_maxExp,MM_maxHold,MM_minOrder,MM_period,MM_signal,MM_step,MM_tl - Read only once you change
MM_signal— the value that first reaches each:MM_af0,MM_afMaxunderpsar;MM_base,MM_conv,MM_spanBunderichimoku;MM_entry,MM_exitunderrsi;MM_entryPctundersupertrend;MM_exitAdx,MM_minStrunderadx;MM_fast,MM_minDip,MM_signalP,MM_slow,MM_smaPeriodundermacd;MM_multunderbb
What to build next
Ordered by expected effect on the result, not by effort.
1. The 8% stop is not an 8% stop — two thirds of them fill worse, and a tenth fill past −15%
Highest priority
MM_maxDd is set to 8 and the side panel draws the stop at exactly −8% from break-even. Where it actually filled, across 59 stop exits:
| realised loss | count | share |
|---|---|---|
| −8% to −9% | 34 | 58% |
| −9% to −10% | 14 | 24% |
| −10% to −12% | 5 | 8% |
| worse than −15% | 6 | 10% |
Mean −9.95%, worst −21.0% — 2.6× the setting. 39 of 59 overshot by more than half a point.
And that is the optimistic figure, because this engine gives the strategy one price per bar. The overshoot measured here comes only from the fill delay: the decision is taken on a closed bar and the market order fills at the next bar's open. Live, a second delay stacks on top — the stop sits behind if (!isNewCandleTick) return, so on an hourly chart it is only evaluated once an hour, and a move that starts at :05 is not even looked at until :00.
The obvious repair is to hoist the stop above that gate so it is checked every cycle. It was deliberately not made here, because this engine cannot settle it. Checking more often makes deep losses smaller and also stops out wicks that would have recovered, and with one price per bar there is no intrabar path to tell those apart. The pack already has the data to decide: the archived market data holds 1m, 3m and 5m BTC and 15m ETH/SOL. Re-run the strategy on 1m bars with the stop inside and outside the candle gate and the trade-off becomes measurable instead of arguable.
This is a property of the shared template, so the answer applies to all fifteen mm-dca strategies at once.
2. 80% of exits are a 0.77% win and 2% are a 10% loss
High priority
Every exit, all seven markets, three years, read from the strategy's own log:
| exit | count | share | mean gain | summed |
|---|---|---|---|---|
| Gain Target | 2,018 | 80.4% | +0.77% | +1,552% |
| Indicator Exit | 432 | 17.2% | −1.34% | −577% |
| Stop Loss | 59 | 2.4% | −9.95% | −587% |
| TTL Exit | 0 | 0% | — | 0% |
Those 59 stop exits — 2.4% of all trades — cost as much as all 432 indicator exits put together, and a third of everything the target exits earned. That is the whole risk profile of the strategy in one row, and it explains the shape the metrics show: a win rate of 76–87% with a profit factor of 0.64–1.09. A loser averages 3.7× a winner.
So the strategy is a short-odds bet that looks like a sure thing 80% of the time. Two experiments follow directly. Sweep MM_maxDd down, not up: a tighter stop that fills closer to its setting may cost less than a wide one that overshoots to −21%. And test a partial exit — the ladder buys in three layers and always sells all of them at once, so scaling out at the midline and holding a remainder is a change the existing state already supports.
Note what is not worth tuning: MM_maxHold fired zero times in 2,509 exits. It is read, so it is not inert, but at these defaults it is unreachable.
3. It is the best of the fifteen, and still loses to cash
High priority
At a median −28.8% over three years this is the strongest member of the mm-dca family — the other fourteen run to −85.4%, and the median of all fifteen medians is −79.6%. It is also the only one profitable anywhere on a median basis: ADA returned +10.4% with a profit factor of 1.09.
That is worth something, but the benchmark is unforgiving: buy-and-hold returned a median +39.2% over the same window, and holding cash returned 0%. Fee drag is a median 35% of the account, reaching 42% on LINK, across 415 round trips per market.
The honest reading is that the channel-reversion gate is the least bad of the fifteen rather than good. Before tuning it further, run the test the family-wide result points at: the same entry with the turnover cut by an order of magnitude — a wider channel (MM_period 10 → 50+), a wider target, or a minimum hold between trades. If the edge survives at a tenth of the trade count, the fee drag stops being the dominant term and the numbers become about the signal. If it does not survive, there was no signal to begin with.
4. One market carried the result and it was the one that fell
Worth testing
ADA is the only profitable market (+10.4%) and also the only one where buy-and-hold was negative (−27%). Every market where the asset rose — BTC +131%, SOL +217%, XRP +152% — the strategy lost, at −28.8%, −31.2% and −9.0%.
That is the signature of a strategy that sells into strength: buying a channel low and selling the midline caps the upside at half a channel while leaving the downside open. It is the same fact the one-year window flattered — over 2025-07 to 2026-07 every market fell, buy-and-hold returned a median −52.1%, and this strategy beat it on 7 of 7 markets while still losing 1.7%.
Worth measuring explicitly rather than inferring: split the three years by trend direction (the 200-bar slope is already computed elsewhere in the pack) and report the strategy separately on rising and falling stretches. A strategy that is flat in downtrends and loses in uptrends has a clear use and a clear misuse, and neither is visible in a single median.
5. Nothing needed repairing on this file beyond the log format
Read before acting on the others
This is the first strategy in the audit queue to come through with no defect of its own. Its settings surface is complete — all 32 GUI knobs are read, 16 at the shipped defaults and 16 once MM_signal is changed, with none inert and none untunable — its chart marks are fill-confirmed, its side panel is padded and fully tooltipped, and its palette is canonical.
That is partly because the defects it would have carried were already found and repaired on its siblings: the unread MM_fee that put the profit target on the cost line, the mislabelled MM_signal selector, and the fee tooltip that disagreed with the file by a factor of two were all fixed across the family during the SuperTrend_MM audit. What remained here was the log format, and the audit tool fixed that automatically.
The measured behaviour above is not a defect list. It is what the strategy does.
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.
- Tagged, aligned, coloured
- 19
- 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.
- Data rows
- 6
- Section headers
- 1
- Rows with no tooltip
- 0
- Padded to the 3-column grid
- yes
- Model
- fill-confirmed
A mark is drawn only once the exchange confirms the fill, so the chart never shows a trade that did not happen.
- 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
32 settings appear in the Gunbot strategy editor for this strategy. 32 of them are read at runtime — measured by running the strategy with a recording proxy over its config, not inferred from the source.
MM_af0MM_afMaxMM_atrPeriodMM_baseMM_convMM_dcaModeMM_decayMM_entryMM_entryPadMM_entryPctMM_exitMM_exitAdxMM_fastMM_maxDcaMM_maxExpMM_minDipMM_minStrMM_multMM_periodMM_signalMM_signalPMM_smaPeriodMM_spanBMM_stepMM_minOrderMM_tlMM_exitPadMM_gainMM_maxDdMM_maxHoldMM_slowMM_fee