← volHarvester

volHarvester — Status & roadmap

ENGINEERING COMPLETEAudited 2026-09-15· hand-written (no shared engine) engine· quantroduction· spot

Where this strategy is today

ENGINEERING COMPLETE — 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 5 / 5 invariants pass
Console output 15 tagged calls, 0 off-format
Side panel 20 rows, padded to the 3-column grid
Chart marks reference-levels
Palette 8 / 8 canonical
GUI settings 20 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 -10.5% against buy-and-hold's 49.6% — an edge of -66.4% — and is profitable on 1 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

SUPERSEDED — use volRegimeMM instead. This strategy was renamed volRegimeMM at v2.0 and both files ship in this pack. They were measured against each other here on 3 years × 7 markets at 15m and are behaviourally identical: same trades, same returns, same final cash. There is no behavioural reason to choose this file over its successor, and both appear as separate selectable entries in the Gunbot GUI.

What it does: spot accumulation conditioned on the realized-volatility regime, not on price direction.

Four volatility estimators are computed each cycle and averaged into one σ — Parkinson (high-low range), a return-based rolling standard deviation, an ATR-normalised estimate, and an EWMA with λ = 0.97. That average is then z-scored against its own rolling history, and every decision reads the z-score rather than the raw σ:

The whole result is one trade per market

Over three years and 111,044 bars of 15m data the strategy takes roughly eleven positions per market. Of the 88 exits, the ladder accounts for them like this:

That is one stop per market — two on SOL — and it is the entire difference between the strategy and a profitable one. The median win rate is 91% and the median profit factor is 0.15. Those two numbers together are the whole diagnosis: it wins nine times out of ten and loses anyway, because a +2.54% win needs to happen 7.6 times to pay for one −19.40% loss and it gets about six.

Median fee drag is 0.3% of the account. This is not a cost problem — unlike most of the pack, the trading is far too infrequent for fees to matter. It is a risk-shape problem, and it sits entirely in the exit.

The stop overshoots its own limit. It triggers at −15% and realises a mean of −19.40%, worst −32.00%. The trigger is evaluated on a closed bar, the whole position is then sold at market on the next bar's open, and on a 15m bar in a fast market that gap is several points wide.

The one profitable market is DOGE (+3.5%, profit factor 3.41), and it is also the market with the lowest exposure (54% against a 70–100% range elsewhere). Less time holding, fewer chances to be caught 15% under water.

Correction, 2026-09-15: this page previously stated "There is no stop-loss sell. Every sell path requires a profit." That is false and was the first thing an operator would read when sizing a position. The emergency stop sells the entire holding at market. It fired zero times in the earlier 60-minute measurement, which is how the claim survived — the earlier pass described the sell paths it had seen fire rather than the ones in the file. At 15m it fires once per market and decides the result.

Correction, earlier: an earlier version described the strategy as capturing a variance risk premium and credited a Yang-Zhang estimator, following the file's own header. Both were wrong and the header has been corrected — see the fixes report. Capturing a variance risk premium needs options or variance swaps, which Gunbot does not access; the strategy takes outright long spot exposure. Yang-Zhang was declared in the persisted store and never computed.

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

The measured constraint

Time in market is 81.4%, over 88 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. Use volRegimeMM and retire this file

Highest priority

volRegimeMM is this strategy renamed, and the two are identical on every market at 15m as they were at 60m. Both are selectable in the GUI, so an operator can pick the retired one without knowing it is retired. Nothing here argues for choosing this file.

Everything below applies to both, because they are the same code.

2. The exit is the strategy — fix the stop before touching the signal

Highest priority

Median return is −10.5% over three years against a buy-and-hold of +49.6%, an edge of −66.4%. The median win rate is 91% and the median profit factor is 0.15.

Eight trades out of 88 produce that. Take-profits realise +2.54% on average across 49 exits; the eight emergency stops realise −19.40% on average, worst −32.00%. Summed, the wins are +125% and the stops are −155%.

So the shape to change is the ratio, and there are two independent ways in:

Stop overshoot. The stop is set at VH_MAX_DD = 15% and realises −19.40%. It is checked on a closed bar and then dumps the whole position at market on the next open. A staged exit — half at the trigger, the rest on the following bar — or a stop that also rests as a limit would recover several points of that gap without changing when the decision is made.

Win size. VH_GAIN is 1% and the take-profit path fires at 2× that. A +2.54% mean win against a −19.40% mean loss needs a 88.4% win rate merely to break even, and the strategy achieves 91% — which is why it is close to water rather than catastrophic. Raising VH_GAIN trades win rate for win size, and the measurement to run is the pair together, not either alone.

Median fee drag is 0.3%, so unlike most of this pack there is no cost argument for trading less. The trading is already rare.

3. Measure exposure against outcome — DOGE is the tell

High priority

DOGE is the only profitable market (+3.5%, profit factor 3.41) and also the one with the lowest exposure at 54%, against 70–100% everywhere else. ETH sits at 100% exposure and loses 10.5%.

That is one market and not a result, but it is the cheapest hypothesis available and it is directly testable: the accumulate gate is volZ ≤ −0.5 with no ceiling on how much of the account the ladder may commit, so in a market whose volatility stays below its own norm for a long stretch the strategy simply ends up fully invested and stays there. A maxExposure cap of the kind already applied to the Directional engine in this pack would bound that, and the pack has the tool for it.

Run the ladder at 60%, 80% and no cap across all seven markets and read the profit factor, not the return.

4. Re-tune the ladder, which has never been tuned

High priority

VH_MAX_DCA (6) and VH_DCA_DECAY (0.8) were dead until this pack's ladder repair — a bare return above the accumulate path made it unreachable while a position was held, and this strategy holds one on most bars, so the ladder never advanced past its first rung and DCA_DECAY ^ 0 was always 1.

They work now, which means their shipped values have never been measured doing anything. Six rungs decaying at 0.8 puts 26% of the ladder's total into the first rung and 7% into the last; whether that is the right distribution for a strategy whose losses come from being too far in is an open question with a cheap answer.

5. Check whether four estimators beat one

Worth testing

The ensemble averages Parkinson, return-standard-deviation, an ATR-normalised estimate and an EWMA, then z-scores the average. Four estimators of the same quantity on the same bars are highly correlated, and averaging them mostly removes the differences that would make any one of them informative.

The experiment is one line: run the strategy on each estimator alone and on the ensemble, same seven markets, same window, and compare. If the ensemble does not beat its best single member, three quarters of the computation is decoration — and the header has already been wrong once about what is in this array.

6. The settings measurement does not yet cover this lineage

Read before acting on the others

the presentation audit measures which settings a strategy actually reads by wrapping the shared settings accessor with a recording proxy. The 348 Gunbot Quant files route through the shared settings accessor; the Quantroduction files — this one included — build a plain P: { ... } from the GUI settings directly, so nothing is measured for them and the untunable and inert counts on this page are blank rather than zero.

Every dead setting found in this lineage so far was found by hand. Until the proxy covers P the same way, treat a blank knob section here as unmeasured, not clean — the distinction that has already hidden a defect class in this pack for months.

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
15
Raw and off-format
0
Exempt (object and error dumps)
10

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
20
Section headers
4
Rows with no tooltip
1
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

20 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_CYCLESVH_VOL_LBVH_EWMAVH_HIGH_ZVH_EXT_ZVH_LOW_ZVH_SELL_ZVH_BUY_ZVH_MAX_EXPVH_MAX_DCAVH_DCA_DECAYVH_COMPOUNDVH_SPMIN_ORDER_QUOTEVH_TLVH_CAPITAL_ALLOCVH_GAINVH_MAX_DDVH_FEE

Open presentation findings