The Minerva Tester

Signals, strategies, backtests, and optimizations

A signal is a rule that reads price history and, each bar, says which way to lean: go long (bet the price rises), go short (bet it falls), or stay flat (hold nothing). "Buy when the price has risen for three days, sell when it falls for two" is a signal. A signal says nothing about how many shares to hold or what trading costs.

A strategy adds those missing pieces: a signal, plus a rule for how big a position to take, plus trading costs, plus risk controls like stops. A strategy is what actually makes or loses money. The same signal can be profitable or unprofitable depending on the sizing and costs around it, so the two are not interchangeable: a signal is a direction, a strategy is the full trade that produces a profit-and-loss result.

A backtest runs one fixed strategy over historical prices, one bar at a time, sizing each position and charging each cost as if you had traded it live. It produces the account balance the strategy would have had over that period. A backtest is a single configuration; it is not graded or certified.

An optimization searches a signal's parameters, selects a winner using held-back validation performance, and then attempts certification. The winner may pass, fail one or more mathematical gates, or have insufficient evidence. The statistical machinery in Sections 4, 7, and 8 applies to searches and certification: grading on held-back data, the five-gate Seal, the evidence floor, and the score.

A backtest can look strong and still be wrong — if it let the signal use prices it could not have known yet, assumed trades were free, or picked a winner out of thousands of tries that only won by chance.

01The three model types

A signal is the model's point-in-time trading opinion. It reads the data available at a bar and emits a forecast or target state: positive means long, negative means short, and zero means flat or no new position. The magnitude can carry signal strength. It is not the whole trade: position size, leverage, liquidity, commissions, slippage, stops, and circuit breakers are added by the strategy and simulator layers.

The signal contract also says what the opinion does to an open position. A long forecast can mean "be long now," "start a long trade that has a scheduled holding length," or "enter long and keep watching for an exit condition." Those are different promises. They change how Minerva grades the strategy, and they change how a user should read the paper-trader decision trace.

Every paper-trader trace separates model opinion from paper execution. The decision badge shows what the model wanted on that bar: BUY, SELL, HOLD, or a blocked decision. The reason text explains why. The forecast and strength numbers show conviction. The order line shows what the paper account actually did: no order, a filled quantity and price, or a blocked/skipped outcome. That distinction matters when you map the trace onto your own portfolio.

For a manual portfolio, read the trace in position terms: BUY means add or enter long exposure, or cover an existing short. SELL means reduce or exit long exposure, or open short exposure only if your rules allow shorts. HOLD means no new action from the model at that bar. A strong forecast with "no order placed" means the model opinion existed, but the paper account did not trade because the position, risk settings, cash, shorting permission, warmup state, or another gate prevented it.

Those BUY/SELL/HOLD meanings depend on which of three model types the trading signal declares. Model Type 1 treats the output as the position to hold now. Model Type 2 treats the output as an entry event with a known holding or review horizon. Model Type 3 treats the output as an entry event whose exit is managed by the model as new bars arrive.

The number of shares is decided after the model opinion. A paper trace takes the active risk profile, current equity and cash, existing position, signal price, shorting permission, minimum order value, leverage limit, and maximum position limit, then turns a BUY or SELL into an executable quantity. Fixed-dollar sizing uses dollars per trade / price. Fixed-percent sizing uses equity × percent / price. Risk-per-trade sizing uses (equity × risk percent) / (price × stop distance percent). Quantities are rounded down to whole shares unless fractional trading is enabled, in which case they are rounded down to two decimals.

Model Type 1, target-state

The output is the position to hold right now. If the signal says long, the intended stance is long. If it says short, the intended stance is short. If it says flat, the intended stance is no position. There is no separate exit rule — the output changing is the exit.

In the decision trace, a target-state BUY means the desired state changed to long. If the paper account is flat, it may open a long; if it is short, it may buy to cover. A target-state SELL means the desired state changed to short or away from long; if the paper account is long, it may sell to close. A target-state HOLD means the current bar does not call for a new state change. If the account is already aligned with the signal, the trace can correctly show no order placed.

How much is bought, sold, or held. For Model Type 1, quantity is the amount needed to move the paper account toward the target state, not a fresh bet every bar. A BUY while flat opens a risk-sized long. A BUY while short buys the open short quantity to cover it. A BUY while already long buys zero because the account is already aligned. A SELL while long sells the open long quantity. A SELL while flat can open a risk-sized short only when shorting is enabled. A SELL while already short sells zero because the account is already aligned. HOLD buys and sells zero; it preserves the current state until the signal changes.

Moving-average crossovers, trend-following rules, oscillators, statistical signals, and many fundamental screens work this way. The trace is useful because it tells you whether the model changed its desired stance or simply stayed with the existing one.

Model Type 2, deterministic horizon

The output is an entry event, and the trade has a known holding length or rebalance schedule. A breakout may enter and hold for a declared number of bars. A value signal may rebalance every set number of trading days. The key is that the trade's maximum reach is known when it opens.

In the decision trace, a deterministic-horizon BUY or SELL is an entry or rotation event. HOLD usually means no new entry event has fired on that bar, or the forecast was below the action threshold. If a paper order appears, the quantity and fill show how the paper account acted on the entry. If no order appears, the reason text tells you whether it was warmup, a weak forecast, a same-direction repeat, a risk cap, or another account-level condition.

How much is bought, sold, or held. For Model Type 2, quantity is sized at the entry or rebalance event. A BUY entry while flat opens a long using the active risk-sizing rule and then clamps the order to cash, leverage, and max-position limits. A SELL entry while flat opens a short only when shorting is enabled and then applies the same notional limits. If an opposite position is already open, the trace sizes the order to close that inventory before a new entry can be considered. If the same direction is already open, the trace buys or sells zero rather than pyramiding. HOLD buys and sells zero because no new scheduled entry or rebalance action has fired. When the known horizon ends, the exit quantity is the open position quantity, because the trade is being closed rather than newly sized from forecast strength.

Use these traces as scheduled trade evidence: the model is not merely saying "I like this stock"; it is saying "this is an entry point for a trade with a known review or expiry horizon." For your own portfolio, that means the trace should be paired with a calendar or holding-period rule, not treated as an open-ended opinion.

Model Type 3, model-managed exit

The output is an entry event, but the exit is managed by the model rather than scheduled. The model enters because a setup appears, then checks each new bar for the condition that ends the trade: reversion to a mean, a pattern break, a failed spread, or another model-owned exit rule.

In the decision trace, a model-managed exit BUY or SELL means the setup is active and strong enough to act. A later opposite-side trace can be the exit or reversal event, depending on the model and the current paper position. HOLD means the model is still waiting: either no setup, not enough strength, warmup still in progress, or the exit condition has not appeared.

How much is bought, sold, or held. For Model Type 3, the entry is risk-sized when the model-managed setup first fires. A BUY while flat opens a risk-sized long. A SELL while flat opens a risk-sized short only when shorting is enabled. While the model keeps managing the open trade, HOLD buys and sells zero; it means keep the current position and wait for the exit condition, not add more shares. If the exit condition produces the opposite side, the paper trace sizes the order to the currently open position so the trade can be closed. A new opposite entry is then sized by the same risk profile when the model produces that new entry. If the account is already aligned with the signal, the trace buys or sells zero rather than adding to the position.

These traces are especially useful for discretionary review. You can watch the reason text and forecast strength to see whether the model is still waiting, has fired an entry, or has moved to an exit. For your own portfolio, this is the place to compare the model's exit logic with your actual stop, target, and risk plan.

Some signals change model type by parameter — anchored VWAP is Model Type 3 by default when confluence is required and Model Type 1 when confluence is explicitly off; an adaptive moving-average signal is Model Type 1 on slope-change and Model Type 2 on price-cross. The contract is resolved from the actual parameters each run, never assumed.

How does this signal's trade end?
how does this signal's trade end? MODEL TYPE 1 · target-state BUY = target long SELL = target short / exit long HOLD = no state change trace: desired stance MODEL TYPE 2 · horizon BUY/SELL = entry event HOLD = no new entry review/expiry is known trace: scheduled trade MODEL TYPE 3 · model-managed exit BUY/SELL = setup active HOLD = still waiting exit is condition-based trace: entry or exit watch declared lifecycle → purge and embargo geometry

The reason this matters is mechanical: the lifecycle determines how far a trade can reach into later prices during validation. Misclassifying it would either leak future data into the grade or remove more history than necessary.

02The data

A backtest is only as accurate as the prices behind it. Minerva validates price data, normalizes it, and records the transformations that affect a result.

Coverage

  • Available US-listed securities. Minerva can use only symbols, resolutions, and date ranges for which production cloud bar objects exist. Availability varies by security, listing and delisting dates, and resolution; requested coverage is checked before a run.
  • Supported window. Production availability is bounded by 2016-04-19 through 2026-06-16, but each symbol and resolution may cover a smaller interval.
  • Granularity. Production bars are stored separately at 1-minute, 5-minute, 15-minute, 30-minute, 1-hour, and daily resolutions. Minerva does not construct every longer timeframe from a stored 1-minute base. When OHLCV aggregation is performed, open is first, high is the maximum, low is the minimum, close is last, and only volume is summed.
  • Sessions. Historical extended-hours bars are present. When a session distinction matters, Minerva can classify a bar as pre-market, regular hours, or after-hours from its timestamp and the market-hours calendar; it does not need a separate stored session label to know that history exists.

What a bar is, and how it's stored

pricesopen, high, low, and close price during the slice
volumeshares traded during the slice
timestampuniversal time, to the second
dataset detailsdataset identifier, normalized data marker, and bar length

Bars are stored two ways: column-oriented files on disk for loading long histories quickly, and a database keyed by stock and timestamp for exact lookups. Timestamps from different market-data feeds come in different units (seconds, milliseconds, microseconds, nanoseconds); Minerva reads the unit from the size of the number rather than assuming, so a millisecond timestamp isn't read as seconds.

Each batch of bars is identified by five things together — stock, start date, end date, bar length, and dataset identifier — plus a flag for whether dividends have been applied. The lookup order is fixed and recorded. This identity keeps a dividend-adjusted series and a raw series for the same stock from being mixed up.

Corporate Actions

A corporate action is a company event that changes a stock's raw price without changing what a holder actually earned. Two affect backtests directly:

  • A stock split divides each share — a $100 share becomes two $50 shares. The price halves overnight, but the holding is worth the same. Left uncorrected, a 2-for-1 split reads as a 50% crash.
  • A dividend pays cash to shareholders. On the ex-dividend date — the first day the stock trades without the upcoming dividend attached — the price drops by about the dividend amount. The holder isn't worse off; they got the cash. The series shows a drop anyway.

A signal run on uncorrected prices treats both as real moves and trades them.

Why pre-adjusted prices are wrong for backtesting

Many market-data vendors offer "adjusted" prices with splits and dividends already removed. These aren't safe to backtest on. To remove an event from history, the vendor rewrites every earlier price in the series, so a price dated 2018 is calculated using a split that happened in 2023 — the adjusted 2018 value depends on the future. A signal trained on it is using information that didn't exist yet, the same error as Section 3, hidden in the data. López de Prado (2018) covers this.

What Minerva does

Prices are stored split-adjusted but not dividend-adjusted. Minerva never inherits a vendor's pre-baked adjusted series; every correction is computed by Minerva at load time from its own versioned record of the actual events, so the exact adjustment applied to any result is known and reproducible.

  • Splits are applied when bars are built, so the stored series has no split jumps. A split is a known ratio on a known date, so applying it adds no future information.
  • Dividends are applied only when a test requests total-return prices, using the backward-cumulative total-return adjustment of CRSP, the standard reference. Going through cash dividends earliest to latest, every price strictly before each ex-date is scaled by:
adj_t  =  raw_t × ∏  (C_d − D_d) / C_d   over all ex-dates d later than t

where D_d is the dividend and C_d is the unadjusted close on the last bar before that ex-date. Two points keep this exact:

  • Each dividend's factor uses the original prices, not prices already scaled by an earlier dividend, so multiple dividends don't compound incorrectly.
  • Dividends with an ex-date after the last bar are skipped, so the most recent price isn't reduced by a payout that hasn't happened — the latest adjusted price equals the latest raw price. A test pins this.

The factor is applied to open, high, low, and close together so the bar's shape is unchanged. Volume is not scaled, because a dividend is cash, not a change in share count.

Why a backward factor is safe here, when a vendor's pre-adjusted series is not. The CRSP factor is a single constant applied to every price before an ex-date, so any two bars on the same side of that ex-date are scaled identically and the return between them is unchanged. The only return the adjustment alters is the one spanning the ex-date, which is exactly the artificial drop it exists to remove — no signal computed from returns can learn anything from a future dividend. That is different from a vendor's pre-adjusted series, where an unknown vintage of splits and dividends is baked into stored prices you cannot inspect, undo, or pin to a version. Minerva applies the adjustment only on request, only from a manifest-verified event record, and never for an ex-date after the last loaded bar.

How stale or wrong corporate-action data is caught

The split and dividend records and a manifest describing them are kept as one dataset tied together by SHA-256 hashes:

  • The manifest stores a hash of the dividends file, a hash of the splits file, and a hash of which stocks and date range are covered. These combine into a short version string (16 hex characters) recorded on every result.
  • Before using the data, a run checks coverage against the manifest. If a stock that needs adjusting isn't covered, the run stops instead of trading on uncorrected prices. A stock that never paid a dividend or split is covered — that's a recorded fact; a missing record is not.
  • Because the version string is computed from the file bytes, changing the data without rebuilding the manifest is caught: the hashes no longer match and the data is rejected.

A missing or inconsistent record stops the test rather than producing a wrong number that looks right.

Survivorship: companies that no longer exist

Of the roughly 3,000 companies in the Russell 3000 index at the end of 1986, fewer than 500 still existed by 2014. The rest were acquired, went bankrupt, or were delisted.

Testing on today's index members leaves out every company that disappeared, so the test only trades the survivors. This is survivorship bias. It can change the answer, not just improve it: Brown, Goetzmann, Ibbotson & Ross (1992) showed a strategy that looks profitable on the survivors can lose money once the failed companies are included. Today's membership also adds future information, because a company is in today's index partly because it did well after the date being tested.

  • Minerva reconstructs index membership as it was on each date. Each company's membership is stored as a start and end date, so the set of stocks on any given day matches what it actually was, including companies that have since disappeared.
  • Companies that were later delisted keep their full price history up to their last trading day. Missing data is never a reason to drop a company.
  • A "today's members" mode is available, but using it records a survivorship-bias warning on the result.

Bad and impossible prices

Market-data feeds occasionally carry a corrupt value, and one bad number can produce a large fake profit. (In a well-known case, a mistyped earnings figure of over $60,000 for a $20 stock distorted an entire index.)

  • A share price must be positive and finite. While bars are built, any price that is zero, negative, infinite, or not a number is dropped and replaced with the good prices in the same bar, preferring close, then open, high, low. A zero low can't create a fake −100% bar.
  • At scoring time, non-finite returns are removed before any statistic is computed, so one bad value can't distort a Sharpe ratio or a drawdown.
  • This removes impossible values, not merely improbable ones. A price that is a valid number but far out of line isn't flagged statistically yet.

03Keeping a signal from using future prices

If a signal uses information it could not have had at the time, the backtest is meaningless even though it may look strong. The most common form: compute a signal from today's closing price, then record a purchase at that same close. In real trading you can't — once you know the close, the day is over. Deutsche Bank's Seven Sins of Quantitative Investing gives a concrete one-day reversal example: Sharpe 1.41 when the trade is recorded at the close the signal just used, and 0.26 when the trade moves to the next available price. That measurement is from Luo et al. (2014), not from Minerva; it is included because this is exactly the class of look-ahead error Minerva is built to prevent.

Minerva prevents this in the structure of the simulation, not by asking signal authors to be careful. The order of events on every bar is fixed:

The order of events on every bar
yesterday ends today opens tomorrow opens today is live the signal sees only past days NOT today's high/low/close a new signal is held for tomorrow made yesterday → fills at today's open fills at tomorrow's open

An instruction computed from a bar's data is always filled at the next bar's open, never within the same bar. The specific guarantees are:

  • Next-bar-open fills. An instruction made at one bar's close is held in a pending order and filled at the next bar's open. You trade at the next available price, not the one the signal just read.
  • The current bar is invisible. When asked for an instruction at bar i, a signal receives the window [i − lookback, i) — completed earlier bars only. It never sees bar i, whose high, low, and close aren't final until the bar ends.
  • Warmup gating. Until enough past bars exist for the signal's indicators, the signal stays flat and no trade fires.
  • Backward-only normalization. Rolling averages use the trailing window only, never the full dataset, which would let later data affect earlier decisions.
  • Deferred stop tightening. Stops are checked against prices that actually occurred (a level set on an earlier bar, against this bar's real high/low). A trailing stop that tightens on one bar's close only takes effect on the next bar, so the same bar can't both move the stop and trigger it.
  • Deferred forced exits. A circuit-breaker exit (triggered when the day's loss crosses a threshold) is queued for the next bar's open, like any other order.
  • Causal running statistics. A position-sizing rule that adapts to the recent win rate updates its tallies only when a trade closes and reads them only at the next entry.
  • Causal liquidity. The amount that can be bought is based on volume from earlier sessions only (§5), never the current or a future bar.

Beyond the structural rules, Minerva includes a direct leakage check: it runs the same backtest twice, once normally and once with signals delayed by an extra bar, and compares the Sharpe ratios. If delaying drops the Sharpe by more than 20% — (normal − delayed) / |normal| > 0.2 — the signal is relying on information it should not have. The structural rules prevent the leak; this check confirms a given signal is not finding a way around them.

The reference simulator and compiled simulator are parity-tested for this behavior, including price alignment between the signal's visible context and the simulator's execution price.

04Grading on data the signal never saw

Finding a good signal usually means trying many parameter variations and keeping the best. The problem is that the best of many variations looks good even when none has any real edge — try 4,000 random variations and the luckiest looks strong by chance (the expected best score of N worthless variations grows with N). Grading that winner on the same data used to choose it measures the luck of the search, not the signal. This is overfitting, and it is the main reason backtested strategies fail when traded.

The fix is to grade each variation on data not used to choose it. The data used to choose is in-sample; the data held back to grade is out-of-sample. A variation that does well in-sample but poorly out-of-sample was fitting noise; one that holds up out-of-sample may have a real edge. On an optimization Minerva always does this, and it can't be turned off.

How the data is split

Rather than grading on one block of history, Minerva cuts the history into several equal time periods and tries every way of choosing some periods to grade on and the rest to search on. With N groups and k held-back groups, there are C(N,k) train/grade split evaluations, which combine into φ[N,k] = C(N,k) × k/N = C(N−1,k−1) distinct backtest paths. The product default of 10 periods with 3 held back therefore runs 120 split evaluations and forms 36 paths. Do not call C(N,k) the path count. The period count and grade-period count are adjustable within bounded ranges. This is Combinatorial Purged Cross-Validation (López de Prado, 2018).

One combination, of many
History cut into time periods. Graded on ◼ · searched on ▢ · gap ▨: 1 search 2 search ▨ gap 3 GRADE ▨ gap 5 search 6 search 7 GRADE 8 search 9 A gap sits on each side of a grade period so information doesn't cross the boundary. Repeat for every combination → split evaluations form distinct out-of-sample paths.

The two gaps

Even with separate search and grade periods, two kinds of information can cross the boundary, so Minerva inserts a gap on each side:

  • Purge (before a grade period). A trade opened in a search period but still open when a grade period starts depends on grade-period prices. Those straddling trades are removed from the search side. The gap is sized to how far the signal's trades reach forward, read from the Section 1 model type: a Model Type 1 signal needs no purge, while Model Type 2 and Model Type 3 signals purge by their declared holding length times a safety multiplier of 1.2, giving ~20% headroom.
  • Embargo (after a grade period). Prices on consecutive days are correlated, so the bars just after a grade period still carry information from it. A slice there is dropped too — 1% of the evaluation range's bar count (López de Prado ch. 7). Purge handles trade-overlap on the pre-test side; embargo handles serial correlation on the post-test side. They're independent.

Measuring overfitting directly

Across the 120 combinations, Minerva computes the Probability of Backtest Overfitting (Bailey et al. 2017). For each balanced split of folds into in-sample and out-of-sample halves, it takes the variation that ranked best in-sample, finds its rank out-of-sample, rescales to ω = rank / (N + 1), and takes the logit λ = ln(ω / (1 − ω)), which is negative when the in-sample best lands below the out-of-sample median. PBO is the fraction of splits with λ < 0. Above 0.5, the search is selecting variations that do worse than average on new data — it is fitting noise. This feeds the seal (§7, Test 2).

Selection uses out-of-sample results only. The best performer is found on search data, but only its out-of-sample rank counts toward the verdict.

05Trading costs and execution realism

Every real trade costs money: a commission, and the fact that you rarely get the exact price you wanted — you pay slightly more buying and receive slightly less selling. A backtest that ignores costs favors strategies that trade frequently, the ones most likely to fail once costs are real. This is where a signal and a strategy differ: a signal that looks strong on paper can lose money once costs are charged.

Every fill charges the configured commission plus the selected slippage model, on entry and exit. The default Fixed mode applies flat basis-point slippage. Volatility mode scales slippage with observed volatility. Almgren–Chriss adds the volume-sensitive spread and temporary/permanent market-impact terms below.

Almgren–Chriss spread

When Almgren–Chriss is selected, the spread term starts at 3 basis points (0.03%), rises on low-volume bars, and is capped at .

spread cost = price × (3 / 10,000) × √(reference_vol / current_vol)  [capped 4×]  × shares

Almgren–Chriss market impact

When Almgren–Chriss is selected, impact grows with the square root of the share of daily volume taken, split into a temporary part paid on the fill and a permanent part retained in the price.

participation = shares / average daily volume
impact (bps)  = 0.1 × volatility × participation^0.5 × 10,000
temporary     = shares × price × (impact / 10,000) × 0.6      (you pay)
permanent     = shares × price × (impact / 10,000) × 0.4      (stays in the price)

Coefficient 0.1, exponent 0.5 (the square-root law), temporary/permanent split 60/40. Volatility is measured over a trailing window.

Commissions and fees

A tiered, broker-realistic schedule: $0.0035 per share at the lowest volume tier dropping to $0.0005 at the highest, a $0.35 minimum per order, and a 1%-of-value ceiling. On top: a CAT fee of $0.000022 per share on both sides, a FINRA TAF of $0.000166 per share on sells (capped $8.30 per order), and the SEC Section 31 fee on sells (currently 0.0, suspended May 2025).

A stress adjustment

The Almgren–Chriss spread/volume multiplier is capped at . Separately, when regime cost scaling is active, the computed Almgren–Chriss slippage can be multiplied by the regime's cost multiplier. That multiplier does not alter commissions or the Fixed and Volatility slippage modes, and it is not the spread cap.

Limiting trade size to what actually traded

A backtest can record buying 100,000 shares of a stock that only traded 5,000 shares that day — an order that could not have been filled. Combined with position sizing, this produces large fake returns. Two limits prevent it, applied before any profit is counted:

  • A volume limit. Each entry or size increase is capped at about 1% (default 1.0) of the volume that was actually available; an exit closes the held position. "Available" is measured two ways and the smaller wins: a daily figure (1% of average daily volume) and a finer figure for the time of day (1% of what usually trades in that part of the session). Both use earlier completed sessions only. A stock with no prior history gets no entry capacity — the trade is skipped rather than filled against invented volume. An order above the cap is reduced; below one share, it's skipped. Short orders keep their sign.
  • A minimum stop distance. Some sizing rules take a larger position when the stop is closer. If the stop distance could round to near zero, the position would balloon. So the stop distance is held to at least the smallest real price increment — $0.0001 for sub-$1 stocks, $0.01 otherwise — before sizing.

In thinly traded names, these limits prevent a backtest from turning unavailable volume or sub-tick stop distances into a position size that could not have been executed in the market.

Other execution controls

  • Circuit breaker. When the day's loss crosses the configured limit, the position is exited at the next bar's open (§3), with full costs charged.
  • Leverage cap. Position size is capped at the configured leverage limit times equity.
  • Position bounds. A maximum position value and a minimum position size (default 1 share) are enforced; an order below the minimum is dropped.
  • Three slippage models. Fixed, volatility-scaled, and the Almgren–Chriss model above. The participation and stop-distance limits apply to all three, because capacity is an execution fact, not a property of the cost formula.

A separate fragility check

After an optimization, Minerva can re-run the winning strategy under deliberately worse cost assumptions and report how much it degrades: zero cost as a control, 2× and 3× slippage, 2× commission, and a combined case with 2× slippage plus 1.5× commission. The fragility score is 1 − (worst-scenario Sharpe / base Sharpe), clamped to [0, 1]; a strategy whose edge survives only at the default cost level scores high. Advisory, computed after selection.

Comparison with another platform

The same public strategy was run on Minerva and on QuantConnect, an established backtesting platform, with identical settings (AMD, daily bars, 2021-05-19 to 2026-02-18, $0.005 per share, next-open fills). The results matched closely: 33 trades on each, every entry on the same date, and a final account value of $250,412 versus $250,427 — about $15 on $250,000, or 0.006%. The arithmetic agrees. The one intended difference is that Minerva never lets a signal see the current bar, which makes its numbers slightly more conservative.

06The result metrics

Minerva computes results from the equity curve, the account's value over time (equity = cash + shares × price). Three rules apply to every metric: bad values are removed first; a metric with no valid answer is reported as N/A, not a made-up number; and an unrecognized bar length stops with an error rather than a guess.

Most metrics are stated per year so signals run at different speeds compare fairly. The annualization factor is √(bars per year), exact per timeframe: 98,280 bars/year for 1-minute, 19,656 for 5-minute, 6,552 for 15-minute, 1,638 for hourly, 252 for daily. An unrecognized timeframe raises rather than defaulting.

  • Total return and CAGR — how much the account grew, and that growth as a yearly rate.
  • Sharpe ratio — mean per-bar excess return divided by the standard deviation of per-bar returns, times the annualization factor for the result's actual metric basis. Risk-free return is subtracted only when that option is enabled. N/A if volatility is zero. Higher is better.
  • Sortino ratio — like Sharpe but the denominator counts only downward moves. N/A if there were no losing periods.
  • Calmar ratio — yearly return divided by the largest peak-to-trough drop. N/A if there was no drop.
  • Maximum drawdown — the largest peak-to-trough fall, as a percentage.
  • Win rate, profit factor, average win and loss, expectancy — from completed round-trip trades (an entry paired with an exit; unpaired legs are logged, not counted). Profit factor is N/A, never infinity, when there were no losing trades.

On an optimization, these are computed separately on each held-back period and combined; the average out-of-sample Sharpe is the headline number. The tests in §7 run on these held-back results, not on the data used to pick the winner.

07The Robustness Seal

On an optimization, the selected strategy is evaluated against five mathematical gates using held-back validation results. Certification requires all five gates plus the evidence floor. Missing a gate is a failure; a record too thin to judge is reported separately as insufficient evidence. Only the five mathematical gates enter the continuous score.

The five tests
OPTIMIZATION graded on held-back data 1 · Deflated Sharpe≥ 0.95 beats the luckiest attempt 2 · Overfitting prob.≤ 0.50 does the in-sample best flop? 3 · Skill vs chancep ≤ 0.10 could chance produce this? 4 · Track length≥ minimum enough history for the Sharpe? 5 · Consistency≥ 0.60 steady across eras, worst included all five + evidence? gate miss → no seal (names the failed test) pass + evidence → Robustness Seal

Test 1: Deflated Sharpe ratio ≥ 0.95

Takes the strategy's Sharpe ratio and subtracts what the luckiest of all the variations tried would be expected to score by chance, then asks how confident we can be that the edge clears that bar (Bailey & López de Prado, 2014). The chance bar rises with the search effort. Minerva estimates the effective number of trials from an eigenvalue-based similarity matrix derived from proximity and dependence among the searched parameter vectors, rather than from correlations among equity curves — trying one idea 4,000 times is not 4,000 independent attempts.

SR0 = sr_mean + √(sr_variance) × [ (1−γ)·Φ⁻¹(1 − 1/N) + γ·Φ⁻¹(1 − 1/(N·e)) ]  γ ≈ 0.5772
DSR = Φ( (SR − SR0) × √(T−1) / √( 1 − γ₃·SR + ((γ₄+2)/4)·SR² ) )

N is the effective number of trials, T the number of bars, γ₃ skew, γ₄ excess kurtosis. The stored Sharpe is annualized, but the variance term and (T−1) are per-bar, so Sharpe is divided by the annualization factor and variance by its square before entering the formula. When no usable family variance panel is supplied, Minerva uses Lo's null sampling variance: 1/years in annualized units, equivalently 1/T per bar. Call paths whose history units cannot be resolved retain the legacy constant. HAC-corrected Sharpe is an audit field, not the DSR gate input. Passing at 0.95 means the DSR is at least 0.95.

Test 2: overfitting probability ≤ 0.50

The PBO from §4: across every balanced in-sample/out-of-sample split of the folds, how often the in-sample best lands below the out-of-sample median. Above 0.5, the search selects variations that do worse than average on new data (Bailey et al., 2017).

Test 3: skill versus chance p ≤ 0.10

The ordinary gate tests one strategy against cash using 500 circular-block resamples of length n^(1/3), with the finite-sample p-value (1 + count) / (1 + B). For cloud families with more than 12 aligned survivors, Minerva uses one family-max bootstrap p-value for the family. That family-max statistic is not the full studentized Hansen SPA statistic. The following family-wise procedures are companion audit or screening outputs where available:

  • White's Reality Check — the maximum excess return across the family, every candidate recentered to zero, using 1,000 reshuffles.
  • Hansen's SPA — the same but each candidate's score is divided by its own volatility, and clearly inferior candidates are not recentered, which keeps a pile of bad candidates from hiding a good one. It uses 1,000 reshuffles and the threshold A_k = −0.25·ω_k·√(ln ln n / n).
  • Romano–Wolf StepM — a stepwise version that rejects the clear winners, removes them, and repeats, finding more true positives than a single pass.

A Model Confidence Set and Benjamini–Hochberg false-discovery control are also available for screening across many surviving candidates, bounding the share that are false positives.

Test 4: track length ≥ minimum required

A thin Sharpe on a short record cannot be told apart from zero. This computes the minimum track-record length the observed Sharpe needs to be statistically significant, adjusted for skew and fat tails (Bailey & López de Prado 2012), and fails a result with too little history to support the Sharpe it claims. Note this is the single-trial significance length; the penalty for the size of the search is Test 1's job, not this one:

MinTRL = 1 + (1 − γ₃·SR + ((γ₄+2)/4)·SR²) × (Φ⁻¹(1 − α) / SR)²  α = 0.05, SR per-bar

γ₃ skew, γ₄ excess kurtosis, as in Test 1. Like Test 1, this is a per-bar formula and de-annualizes the Sharpe first, so the two agree on units. The gate passes when the actual bar count is at least MinTRL.

Test 5: consistency across eras ≥ 0.60

The same strategy can look good or bad depending on which two-year window is shown. This grades steadiness across periods and checks the worst period specifically, not just the average:

ρ = clip[0,1](0.5 × p+ + 0.3 × clip[0,1](1 − sSR/2) + 0.2 × logistic(SRmin))

p+ is the share of windows with positive Sharpe, sSR is the standard deviation of window Sharpe values, and SRmin is the worst-window Sharpe. The worst window is also reported on its own.

08The MinervaScore

MinervaScore is a 0–100, verdict-consistent ranking of how far a validated result sits from five robustness thresholds. The paper demonstrates strong ranking performance in synthetic ground truth. Certification requires all five mathematical gates plus the separate evidence floor. The score is set so that 80 or above always means the Seal passed; below 80 means the result did not certify.

  • Per-test transformed margin. DSR uses its pre-Φ statistic u: zDSR = (u − Φ⁻¹(0.95)) / 1.128. PBO and SPA use clamped log-odds: zPBO = (logit(0.50) − logit(PBO)) / 10.028 and zSPA = (logit(0.10) − logit(SPA)) / 6.013. Regime uses zregime = (logit(ρ) − logit(0.60)) / 1.161. Track length uses zMinTRL = tanh((T − MinTRL) / max(0.2 × MinTRL, 50)). Probabilities are clamped to [10⁻⁶, 1−10⁻⁶] before the logit. A passed threshold contributes a positive margin; a miss contributes a negative margin.
  • Weighted combination. The five margins use weights 0.35 / 0.25 / 0.20 / 0.10 / 0.10 (DSR / PBO / SPA / track length / regime). The combined statistic is S = (w·z) / √(wᵀ Σeff w). Σeff is a frozen cross-sectional correlation matrix estimated once from the calibration population and shared by every strategy. It normalizes the ranking scale; it is not covariance estimated from the current run's folds and carries no combined-test inferential claim.
  • A conservative offset. The raw score is r = Φ(S − 0.5). The fixed 0.5 is a tunable conservative offset, not a López de Prado bias correction.
  • Verdict-consistent display mapping. A sealed result maps to 80–100. An uncertified result maps to 0–79.9 using the percentile of its raw score among 355,214 uncertified optimizer candidates in the frozen calibration reference population. For an uncertified result only, MinervaScore ÷ 0.8 is approximately that reference percentile. This interpretation does not apply to the sealed band, and absolute scores are comparable only within a calibration vintage. The guarantee by construction is that a displayed score of 80 or higher means the Seal passed.

09Robustness checks beyond the seal

The seal asks whether a result is statistically real. These additional checks ask whether it is stable — whether it survives small changes to its own parameters, depends on one lucky market regime, or sits on an isolated peak. They run on an optimization and are reported alongside the result.

  • Parameter sensitivity. Each sweepable parameter is re-tested at −50%, −25%, baseline, +25%, +50% of its value, one parameter at a time. Identity-affecting parameters (bar length, warmup) are skipped, and the number of test cells is capped (default 10, hard cap 25). A result that holds across the sweep is robust; one that collapses one step away from its tuned value was overfit to that exact value.
  • Monotonicity. The shape of each parameter's response curve is checked. A smooth curve is expected; a U-shaped or multi-peaked response suggests the tuned value sits on a spike rather than a stable region.
  • Neighborhood profitability. For the top results, Minerva looks at nearby parameter sets — within ±10% of each parameter's range, widening to ±25% and ±50% if too few neighbors exist — and reports the fraction that are profitable. An isolated profitable point surrounded by losers is a warning; a dense profitable neighborhood is evidence of a real region.
  • Regime attribution. Performance is broken out by market regime, so a strategy that made all its money in one regime and lost in the rest is visible rather than hidden in the average. Per-bar metrics are attributed to the active regime; trade-level metrics to the regime at entry.
  • Rolling Sharpe. An exponentially weighted rolling Sharpe over daily returns shows whether performance was steady or came from a few months, weighting recent periods rather than treating the whole history as one number.

10The settings you can change

On an optimization, these are the settings you control. For each, the question is whether raising it mainly improves the result, improves speed, or trades one for the other. Defaults are what the app uses unless changed.

The search

settingwhat it controlsdefaultraising it
search methodhow variations are exploredgenetic (an evolution-style search)genetic handles many settings at once; Bayesian is more efficient with few settings; grid tries every combination but grows very large
populationvariations per round128more thorough slower
generationsrounds of evolution3more thorough slower
mutation / crossover ratehow much variations are shuffled each round0.05 / 0.6more exploration; too high disrupts good variations

Total work is roughly population × generations × the number of train/grade combinations.

The grading

settingwhat it controlsdefaultraising it
number of periodstime periods the history is cut into10more thorough much slower
periods held backhow many are graded on at a time3more thorough slower
gaps (purge / embargo)the leak-prevention gapsautomaticmore accurate purge from holding length, embargo 1% of range

At the defaults this is 120 train/grade combinations per variation.

Statistical depth and speed

settingwhat it controlsdefaulteffect
bootstrap countreshuffles in the predictive-ability procedures500 gate; 1,000 companion family auditsa more precise p-value, slower
multi-fidelitytest on a small slice of data first, promote only survivorsoffmuch faster; a small risk an early rough result drops a good variation
early stoppingstop a clearly failing variation partway throughofffaster on bad variations, little effect on good ones

When multi-fidelity is on, the search runs in three stages: stage 1 on 20% of the history and one symbol, keeping the top 25%; stage 2 on 60% and three symbols, keeping the top 33%; stage 3 on the full data. Early stopping abandons a variation after 25% of its bars if its partial Sharpe is below −1.5 or its drawdown worse than −75%. The cost settings (§5) are on by default and change which strategies survive; starting capital and risk-per-trade set position size and don't affect speed.

11Accuracy mechanics reference

Minerva's accuracy contracts span data, signal replay, simulation, optimization, validation, and result storage. The point is not just to run fast; it is to make every reported number traceable to causal inputs and reproducible rules.

Bar identity, adjustment, and reproducibility

  • Bar identity is explicit. A bar series is identified by symbol + start + end + timeframe + dataset, plus whether dividends were applied and which corporate-action reference version was used.
  • Bar hashes are deterministic. Minerva hashes timestamp, open, high, low, close, and volume in order, with fixed numeric formatting, so local/cloud parity can compare exact loaded data rather than trusting labels.
  • Timestamp units are detected by magnitude. Numeric bar timestamps are interpreted as seconds, milliseconds, microseconds, or nanoseconds by size and converted to UTC-aware datetimes.
  • Minerva's price data is stored split-adjusted but not dividend-adjusted (§2). The dividend adjustment is applied at load time, and only when a test requests total-return prices. It is a CRSP-style backward adjustment: every bar before an ex-date is multiplied by (previous close - cash) / previous close. The same factor is applied to O/H/L/C; share volume is not scaled.
  • Corporate-action reference data is manifest-verified. Dividends, splits, symbol coverage, window bounds, and file hashes are tied to an immutable reference version. Missing coverage or mismatched hashes stop the run with structured details.
  • Future dividends are not applied. The adjustment routine skips ex-dates after the last bar in the loaded series so the most recent price remains the total-return anchor.
  • Fundamental/filing data is point-in-time. Financial statement rows are filtered by filing availability date before model context construction, so a signal cannot see a filing before it was available.
  • Loaded bars are normalized before simulation. The loader maps price, volume, and timestamp fields; filters to the requested window; sorts; deduplicates by timestamp; validates required price fields; attaches dataset metadata; then hashes the final series.

Causality in the simulator

  • Signals never see the current bar. Model context is built from prior bars only: from max(0, i − context window) through i, exclusive. Prediction caching is disabled inside the accuracy path so stale contexts cannot leak into new bars.
  • Orders execute one bar later. A signal generated on bar i queues a pending order; it can execute only at bar i+1's open. A signal on the final bar is recorded as non-executable.
  • Stops are tested before a new prediction. Fixed and trailing stops are evaluated first. The trailing stop is updated after the stop check, which means a new trailing level becomes actionable on a later bar, not retroactively on the same bar.
  • Exit semantics are part of the model contract. Target-state models, deterministic-horizon models, and model-managed exit models declare their lifecycle. Certification uses that explicit lifecycle to size purge and embargo geometry.
  • Daily circuit-breaker state is causal. The daily peak, circuit-breaker active flag, and participation budget reset at trading-day boundaries. A circuit-breaker trigger queues an exit for the next open and clears any pending entry.
  • Insolvency is terminal. If equity becomes non-positive, Minerva force-closes the position, writes the terminal equity state, and freezes the remaining equity curve at the non-negative terminal cash value.
  • Secondary data is sliced per bar. Economic and regime data may be prepared ahead of time for speed, but the per-bar model context receives only the data available at that bar.
  • Metrics exclude warmup observations. Return metrics operate on post-warmup equity changes, finite values only, with a scale-aware epsilon for near-flat curves.

Execution feasibility, costs, and sizing

  • Cost configuration is canonical. Slippage model names, commission settings, stress settings, and participation bounds are validated once and recorded in a normalized form with the result.
  • Execution capacity is causal and model-independent. Entry and size-increase shares are capped by max participation × min(ADV remaining for session, expected volume for this bar), where both the daily and time-of-day estimates use prior completed sessions only.
  • Participation applies across slippage models. Fixed bps, volatility slippage, and Almgren–Chriss slippage all receive already-clipped entry quantities. The slippage model prices execution; it does not grant extra capacity.
  • Session participation is budgeted. Minerva tracks entry and size-increase shares already opened during the current trading day, subtracts them from the causal ADV cap, and resets that budget only on a new trading day.
  • Stop-derived risk is tick-floored. Stop distance is floored to the conservative equity minimum tick: $0.0001 below one dollar and $0.01 at or above one dollar. The stop price is rounded consistently with the effective risk.
  • Sizing uses the same risk floor. Fixed-risk, Kelly, ATR, volatility-targeted, and signal-proportional sizing all route through the shared sizing helper and cannot turn a sub-tick stop distance into huge leverage.
  • Kelly statistics are causal. Kelly sizing is based only on closed trades observed so far, using net P&L after entry and exit costs.
  • Post-sizing caps are ordered. Minerva applies maximum position value, long cash capacity, leverage, minimum order size, then integer non-negative share normalization.
  • Commissions are explicit. The IBKR-style fee calculator includes per-share commission tiers, minimum commission, percentage cap, CAT, SEC, and FINRA TAF components where applicable.
  • Slippage inputs are causal. Volatility and Almgren–Chriss calculations use trailing context, current bar volume, causal ADV, reference volume, and optional regime cost multipliers, all passed through the same resolver.

Walk-forward, CPCV, and multiple-testing controls

  • CPCV is contract-aware. Purge geometry comes from the model-owned lifecycle horizon, not from observed winning trades. Target-state models need no lifecycle purge; deterministic-horizon and model-managed exit models must declare bars or days.
  • Feature warmup is not treated as label horizon. Warmup is past-looking and recorded as a diagnostic. Purge covers forward event overlap; embargo covers serial correlation after a test fold.
  • Embargo is computed from bar geometry. The default is the AFML 1% bar-count rule converted to calendar days for the active timeframe. Unknown timeframes or invalid ranges raise instead of inventing an annualization or gap size.
  • CPCV split evaluations are preflighted. Minerva validates split counts, date ranges, purge/embargo geometry, and feasible train/test windows before launching certification work. The C(N,k) split-evaluation count remains distinct from the C(N−1,k−1) path count.
  • PBO carries a method label. When a candidate-by-fold matrix is available, Minerva computes true CSCV PBO from in-sample winner ranks against out-of-sample ranks and records that method with the result.
  • Deflated Sharpe is family-aware. Candidate IDs are content-addressed from normalized parameters. Runtime execution keys are stripped from signal identity, while cost model, dataset, timeframe, universe, and date range stay in the trial family used for deflation. The effective trial count comes from proximity and dependence among those searched parameter vectors.
  • Units are kept consistent. Stored Sharpe is annualized, but DSR and MinTRL use per-bar variance formulas. Minerva de-annualizes before those formulas and uses the active timeframe's annualization factor.
  • The predictive-ability gate uses circular block bootstrap. The ordinary path tests one strategy against cash with block length n^(1/3), 500 resamples, and finite-sample p-value correction. Cloud families with more than 12 aligned survivors use one family-max bootstrap p-value; it is not the full studentized Hansen SPA statistic.
  • Family validation uses aligned return panels. Family max, White Reality Check, Hansen SPA, StepM, Model Confidence Set, and FDR procedures operate on a common candidate-by-bar matrix so cross-candidate dependence is preserved.
  • Benchmark length must match. Family-wise helpers raise on benchmark length mismatch rather than silently realigning or padding the benchmark.
  • FDR q-values are monotone-corrected. Benjamini-Hochberg and Benjamini-Yekutieli restore q-values to input order after reverse cumulative minimum correction.
  • HAC Sharpe and MinTRL are separate diagnostics. Lo-style Newey-West HAC Sharpe uses Bartlett weights and floor(T^(1/3)) lag selection; it is an audit field, not the DSR gate input. The Bailey & López de Prado MinTRL reports the required bar count and pass/fail state.
  • The Robustness Seal is an AND gate plus an evidence floor. DSR, PBO, the predictive-ability bootstrap p-value, minimum track-record length, and regime stability all have to pass, and the record must contain enough evidence to judge. A gate miss and insufficient evidence are distinct verdicts. Only the five mathematical margins enter MinervaScore.

Optimizer, signal, and ledger audit trail

  • The optimization request requires timeframe. Annualization comes from the explicit timeframe or bar interval, and unknown values raise.
  • Cost settings are normalized before search. Optimizer startup validates cost parameters, records the canonical model, and injects run-level position sizing into model parameters before trials execute.
  • Regime search knobs are separated from model parameters. Regime settings are removed from the signal parameter search surface and, when applicable, the regime count is pre-fit by BIC before candidates are scored.
  • Bars are preloaded once for the run. The optimizer loads requested bars through the shared bar loader, stores diagnostics and the bar hash, and reuses the identity-keyed cache for trial execution.
  • Signal replay is segment-audited. Signal outputs are stored per symbol and keyed by timestamp, model, parameter hash, timeframe, and dataset. Coverage segments store request bounds, bar bounds, emitted counts, bar hashes, and canonical parameters.
  • Trial rows preserve validation context. Trial rows store the transaction cost model, data version, dataset, timeframe, WF/CPCV metrics, PBO and method, DSR, SPA, family-wise method and p-value, MCS, FDR, HAC Sharpe, MinTRL, symbol consistency, and equity-curve JSON.
  • Batch ledger writes are transactional. Optimizer finalize writes trial rows in a single transaction and memoizes family curve reads within the batch so the DSR family scope is consistent across rows.
  • Results preserve audit fields. Returned results include validation fields, run-level family statistics, model confidence set, false-discovery controls, PBO method, position sizing, regime policy, and per-symbol summaries.
  • Post-selection diagnostics are labeled advisory. Execution stress reruns the finalist under cost mutations; parameter robustness scores the top candidates by the profitability of nearby evaluated neighbors and reports whether neighbor coverage is sufficient.

12Position sizing

The model decides only direction — long, short, or flat. A separate sizing method turns each accepted signal into a dollar position and a whole number of shares. The position is sized once, at the entry that opens it, from the strategy’s current equity; it is not resized while the trade is held. So the same signal can put on very different amounts of risk depending on the method.

The backend defines six methods; five are selectable in the current Minerva form. Volatility Targeting remains a backend method but is not available in that form. Each method takes current equity E and entry price P and produces a raw share count q₀; shared caps (max-position value, long-cash, leverage, minimum size, market participation) can only reduce it.

  • 100% of Equity — position notional equal to current equity; a standardized full-exposure baseline.
  • Fixed Risk — sizes so the initial stop would lose a set percent of equity, i.e. roughly risk% ÷ stop% of equity. The legacy names fixed_fractional and fixed are aliases for this.
  • Kelly — Fixed Risk with the risk fraction re-estimated from the win rate and payoff of completed trades (causal — closed trades only).
  • Volatility Targeting — Minerva’s Carver-style method; scales exposure by forecast strength and inverse instrument volatility toward a target.
  • Signal Proportional — a Fixed Risk position deliberately scaled by signal strength.
  • ATR-Based — the Fixed Risk budget applied against an ATR distance (ATR × multiple) instead of the stop.

Consecutive signals don’t stack

Because a position is sized only when it opens, firing the same-direction signal again while the trade is live does nothing. Size is recomputed only at the next entry — after an exit returns the strategy to flat — or on a reversal. This holds for every sizing method, including backend-only Volatility Targeting.

One trade, three long signals
NO PYRAMIDINGThree long signals in a row don’t buy three times. The first opens the trade; the next two do nothing. Exposure changes only when a new trade opens — recomputed from whatever the equity is then.
Timeline of consecutive long signalsThe first long signal while flat opens a position; later same-direction signals while holding are ignored; a stop or model exit returns to flat; the next signal opens a fresh position sized from the new equity.HOLDING · LONGHOLDING · LONGFLATFLATENTERsize from$100k equityIGNOREDalready longIGNOREDno resizeEXITstop · model→ flatENTERsize fromNEW equityIGNOREDalready longLong signals ▲ · only the two green ENTERs move any money.
Entry — sized from current equity Same-direction signal while holding — ignored Exit — back to flat, equity updates

Shorts are the mirror image: a short signal opens a position of −q shares with the stop above entry, and consecutive shorts while already short are ignored the same way.

The six methods at one entry

The same accepted long signal — equity $100,000, entry $100, a 5% stop, 0.5% risk budget, a 10/20 forecast — sized by each method as a share of the account:

Requested position as a share of equity
100% of Equity
q₀ = ⌊E ÷ P⌋
$100k · 100%
Volatility Targeting
q₀ = ⌊(F/Fₛ)·(E·τ·M·IDM/16) ÷ (P·σ)⌋
$62.5k · 62.5%
Kelly
q₀ = ⌊E·K ÷ D⌋
$20k · 20%
ATR-Based
q₀ = ⌊E·r ÷ (k·ATR)⌋
$12.5k · 12.5%
Fixed Risk
q₀ = ⌊E·r ÷ D⌋
$10k · 10%
Signal Proportional
q₀ = ⌊(E·r ÷ D)·m⌋
$6k · 6%
Show the numbers
MethodReq. sharesReq. position% of equityModeled stop-loss
100% of Equity1,000$100,000100%5% ($5,000)
Volatility Targeting625$62,50062.5%3.1% ($3,125)
Kelly200$20,00020%1% ($1,000)
ATR-Based125$12,50012.5%0.6% ($625)
Fixed Risk100$10,00010%0.5% ($500)
Signal Proportional60$6,0006%0.3% ($300)

Reading ATR-Based: it budgets a 0.5% loss against its ATR sizing distance (ATR × 2 = $4), but the shared 5% stop ($5) is wider, so its modeled stop-loss is $625 — 0.625% of equity, slightly above the budget. The other five equal their target because they size on the 5% stop itself (or, for 100% of Equity, take the full stop on full exposure).

How the position tracks equity across trades

Run six trades in a row, each a fresh entry after the previous one closes. The colored bars are the dollars deployed at each entry; the grey line is total equity. Because every entry resizes from current equity, the bars rise and fall with the line while the fraction stays fixed. Switch runs to see growth versus drawdown.

Six trades, resized from current equity each time

Six winning exits (+5% to +10% each). Every method's bars climb as equity compounds — 100% of Equity balloons, Signal Proportional inches up, but each stays the same fraction of its own (now larger) equity.

100% of Equity≈ 100% of equity
Entry 1: deploys $100,000 (100% of $100,000 equity)Entry 2: deploys $108,000 (100% of $108,000 equity)Entry 3: deploys $114,480 (100% of $114,480 equity)Entry 4: deploys $125,928 (100% of $125,928 equity)Entry 5: deploys $132,224 (100% of $132,224 equity)Entry 6: deploys $141,480 (100% of $141,480 equity)Final equity $154,213t1t6
Final equity
$154k
Total return
+54.2%
Stop / trade
5%
q₀ = ⌊E ÷ P⌋

Buys ~100% of current equity on every entry.

Volatility Targeting≈ 62.5% of equity
Entry 1: deploys $62,500 (62.5% of $100,000 equity)Entry 2: deploys $65,625 (62.5% of $105,000 equity)Entry 3: deploys $68,086 (62.5% of $108,938 equity)Entry 4: deploys $72,341 (62.5% of $115,746 equity)Entry 5: deploys $74,602 (62.5% of $119,363 equity)Entry 6: deploys $77,866 (62.5% of $124,585 equity)Final equity $131,593t1t6
Final equity
$132k
Total return
+31.6%
Stop / trade
3.1%
q₀ = ⌊(F/Fₛ)·(E·τ·M·IDM/16) ÷ (P·σ)⌋

Scales with forecast strength and how calm the instrument is.

Kelly≈ 20% of equity
Entry 1: deploys $20,000 (20% of $100,000 equity)Entry 2: deploys $20,320 (20% of $101,600 equity)Entry 3: deploys $20,564 (20% of $102,819 equity)Entry 4: deploys $20,975 (20% of $104,876 equity)Entry 5: deploys $21,185 (20% of $105,924 equity)Entry 6: deploys $21,481 (20% of $107,407 equity)Final equity $109,341t1t6
Final equity
$109k
Total return
+9.3%
Stop / trade
1%
q₀ = ⌊E·K ÷ D⌋

Risk fraction K is re-estimated from completed trades.

ATR-Based≈ 12.5% of equity
Entry 1: deploys $12,500 (12.5% of $100,000 equity)Entry 2: deploys $12,625 (12.5% of $101,000 equity)Entry 3: deploys $12,720 (12.5% of $101,758 equity)Entry 4: deploys $12,879 (12.5% of $103,029 equity)Entry 5: deploys $12,959 (12.5% of $103,673 equity)Entry 6: deploys $13,073 (12.5% of $104,581 equity)Final equity $105,757t1t6
Final equity
$106k
Total return
+5.8%
Stop / trade
0.6%
q₀ = ⌊E·r ÷ (k·ATR)⌋

Sizes off an ATR distance instead of the stop.

Fixed Risk≈ 10% of equity
Entry 1: deploys $10,000 (10% of $100,000 equity)Entry 2: deploys $10,080 (10% of $100,800 equity)Entry 3: deploys $10,140 (10% of $101,405 equity)Entry 4: deploys $10,242 (10% of $102,419 equity)Entry 5: deploys $10,293 (10% of $102,931 equity)Entry 6: deploys $10,365 (10% of $103,651 equity)Final equity $104,584t1t6
Final equity
$105k
Total return
+4.6%
Stop / trade
0.5%
q₀ = ⌊E·r ÷ D⌋

Risks 0.5% to a 5% stop → ~10% of equity.

Signal Proportional≈ 6% of equity
Entry 1: deploys $6,000 (6% of $100,000 equity)Entry 2: deploys $6,029 (6% of $100,480 equity)Entry 3: deploys $6,051 (6% of $100,842 equity)Entry 4: deploys $6,087 (6% of $101,447 equity)Entry 5: deploys $6,105 (6% of $101,751 equity)Entry 6: deploys $6,131 (6% of $102,178 equity)Final equity $102,730t1t6
Final equity
$103k
Total return
+2.7%
Stop / trade
0.3%
q₀ = ⌊(E·r ÷ D)·m⌋

Fixed-risk size dialed by confidence (m = 0.6 here).

Total equityPosition deployed at each entry (method color)Dashed line = $100k start
Show the numbers for this run
MethodExposureStop / tradePos. t1Pos. t6Final equityReturn
100% of Equity100%5%$100,000$141,480$154,213+54.2%
Volatility Targeting62.5%3.1%$62,500$77,866$131,593+31.6%
Kelly20%1%$20,000$21,481$109,341+9.3%
ATR-Based12.5%0.6%$12,500$13,073$105,757+5.8%
Fixed Risk10%0.5%$10,000$10,365$104,584+4.6%
Signal Proportional6%0.3%$6,000$6,131$102,730+2.7%

Wins and stop-outs alternate. Equity drifts sideways and the deployed dollars breathe with it. The higher-exposure methods swing hardest between entries.

100% of Equity≈ 100% of equity
Entry 1: deploys $100,000 (100% of $100,000 equity)Entry 2: deploys $108,000 (100% of $108,000 equity)Entry 3: deploys $102,600 (100% of $102,600 equity)Entry 4: deploys $108,756 (100% of $108,756 equity)Entry 5: deploys $103,318 (100% of $103,318 equity)Entry 6: deploys $110,550 (100% of $110,550 equity)Final equity $105,023t1t6
Final equity
$105k
Total return
+5%
Stop / trade
5%
q₀ = ⌊E ÷ P⌋

Buys ~100% of current equity on every entry.

Volatility Targeting≈ 62.5% of equity
Entry 1: deploys $62,500 (62.5% of $100,000 equity)Entry 2: deploys $65,625 (62.5% of $105,000 equity)Entry 3: deploys $63,574 (62.5% of $101,719 equity)Entry 4: deploys $65,958 (62.5% of $105,533 equity)Entry 5: deploys $63,897 (62.5% of $102,235 equity)Entry 6: deploys $66,693 (62.5% of $106,708 equity)Final equity $103,373t1t6
Final equity
$103k
Total return
+3.4%
Stop / trade
3.1%
q₀ = ⌊(F/Fₛ)·(E·τ·M·IDM/16) ÷ (P·σ)⌋

Scales with forecast strength and how calm the instrument is.

Kelly≈ 20% of equity
Entry 1: deploys $20,000 (20% of $100,000 equity)Entry 2: deploys $20,320 (20% of $101,600 equity)Entry 3: deploys $20,117 (20% of $100,584 equity)Entry 4: deploys $20,358 (20% of $101,791 equity)Entry 5: deploys $20,155 (20% of $100,773 equity)Entry 6: deploys $20,437 (20% of $102,184 equity)Final equity $101,162t1t6
Final equity
$101k
Total return
+1.2%
Stop / trade
1%
q₀ = ⌊E·K ÷ D⌋

Risk fraction K is re-estimated from completed trades.

ATR-Based≈ 12.5% of equity
Entry 1: deploys $12,500 (12.5% of $100,000 equity)Entry 2: deploys $12,625 (12.5% of $101,000 equity)Entry 3: deploys $12,546 (12.5% of $100,369 equity)Entry 4: deploys $12,640 (12.5% of $101,122 equity)Entry 5: deploys $12,561 (12.5% of $100,490 equity)Entry 6: deploys $12,671 (12.5% of $101,369 equity)Final equity $100,735t1t6
Final equity
$101k
Total return
+0.7%
Stop / trade
0.6%
q₀ = ⌊E·r ÷ (k·ATR)⌋

Sizes off an ATR distance instead of the stop.

Fixed Risk≈ 10% of equity
Entry 1: deploys $10,000 (10% of $100,000 equity)Entry 2: deploys $10,080 (10% of $100,800 equity)Entry 3: deploys $10,030 (10% of $100,296 equity)Entry 4: deploys $10,090 (10% of $100,898 equity)Entry 5: deploys $10,039 (10% of $100,393 equity)Entry 6: deploys $10,110 (10% of $101,096 equity)Final equity $100,591t1t6
Final equity
$101k
Total return
+0.6%
Stop / trade
0.5%
q₀ = ⌊E·r ÷ D⌋

Risks 0.5% to a 5% stop → ~10% of equity.

Signal Proportional≈ 6% of equity
Entry 1: deploys $6,000 (6% of $100,000 equity)Entry 2: deploys $6,029 (6% of $100,480 equity)Entry 3: deploys $6,011 (6% of $100,179 equity)Entry 4: deploys $6,032 (6% of $100,539 equity)Entry 5: deploys $6,014 (6% of $100,238 equity)Entry 6: deploys $6,040 (6% of $100,659 equity)Final equity $100,357t1t6
Final equity
$100k
Total return
+0.4%
Stop / trade
0.3%
q₀ = ⌊(E·r ÷ D)·m⌋

Fixed-risk size dialed by confidence (m = 0.6 here).

Total equityPosition deployed at each entry (method color)Dashed line = $100k start
Show the numbers for this run
MethodExposureStop / tradePos. t1Pos. t6Final equityReturn
100% of Equity100%5%$100,000$110,550$105,023+5%
Volatility Targeting62.5%3.1%$62,500$66,693$103,373+3.4%
Kelly20%1%$20,000$20,437$101,162+1.2%
ATR-Based12.5%0.6%$12,500$12,671$100,735+0.7%
Fixed Risk10%0.5%$10,000$10,110$100,591+0.6%
Signal Proportional6%0.3%$6,000$6,040$100,357+0.4%

Six stop-outs (−5% each). Every position shrinks with equity. Each per-trade loss is exactly the exposure fraction × the 5% stop — 5.0% for 100% of Equity, only 0.5% for Fixed Risk.

100% of Equity≈ 100% of equity
Entry 1: deploys $100,000 (100% of $100,000 equity)Entry 2: deploys $95,000 (100% of $95,000 equity)Entry 3: deploys $90,250 (100% of $90,250 equity)Entry 4: deploys $85,738 (100% of $85,738 equity)Entry 5: deploys $81,451 (100% of $81,451 equity)Entry 6: deploys $77,378 (100% of $77,378 equity)Final equity $73,509t1t6
Final equity
$73.5k
Total return
-26.5%
Stop / trade
5%
q₀ = ⌊E ÷ P⌋

Buys ~100% of current equity on every entry.

Volatility Targeting≈ 62.5% of equity
Entry 1: deploys $62,500 (62.5% of $100,000 equity)Entry 2: deploys $60,547 (62.5% of $96,875 equity)Entry 3: deploys $58,655 (62.5% of $93,848 equity)Entry 4: deploys $56,822 (62.5% of $90,915 equity)Entry 5: deploys $55,046 (62.5% of $88,074 equity)Entry 6: deploys $53,326 (62.5% of $85,322 equity)Final equity $82,655t1t6
Final equity
$82.7k
Total return
-17.3%
Stop / trade
3.1%
q₀ = ⌊(F/Fₛ)·(E·τ·M·IDM/16) ÷ (P·σ)⌋

Scales with forecast strength and how calm the instrument is.

Kelly≈ 20% of equity
Entry 1: deploys $20,000 (20% of $100,000 equity)Entry 2: deploys $19,800 (20% of $99,000 equity)Entry 3: deploys $19,602 (20% of $98,010 equity)Entry 4: deploys $19,406 (20% of $97,030 equity)Entry 5: deploys $19,212 (20% of $96,060 equity)Entry 6: deploys $19,020 (20% of $95,099 equity)Final equity $94,148t1t6
Final equity
$94.1k
Total return
-5.9%
Stop / trade
1%
q₀ = ⌊E·K ÷ D⌋

Risk fraction K is re-estimated from completed trades.

ATR-Based≈ 12.5% of equity
Entry 1: deploys $12,500 (12.5% of $100,000 equity)Entry 2: deploys $12,422 (12.5% of $99,375 equity)Entry 3: deploys $12,344 (12.5% of $98,754 equity)Entry 4: deploys $12,267 (12.5% of $98,137 equity)Entry 5: deploys $12,190 (12.5% of $97,523 equity)Entry 6: deploys $12,114 (12.5% of $96,914 equity)Final equity $96,308t1t6
Final equity
$96.3k
Total return
-3.7%
Stop / trade
0.6%
q₀ = ⌊E·r ÷ (k·ATR)⌋

Sizes off an ATR distance instead of the stop.

Fixed Risk≈ 10% of equity
Entry 1: deploys $10,000 (10% of $100,000 equity)Entry 2: deploys $9,950 (10% of $99,500 equity)Entry 3: deploys $9,900 (10% of $99,003 equity)Entry 4: deploys $9,851 (10% of $98,507 equity)Entry 5: deploys $9,801 (10% of $98,015 equity)Entry 6: deploys $9,752 (10% of $97,525 equity)Final equity $97,037t1t6
Final equity
$97k
Total return
-3%
Stop / trade
0.5%
q₀ = ⌊E·r ÷ D⌋

Risks 0.5% to a 5% stop → ~10% of equity.

Signal Proportional≈ 6% of equity
Entry 1: deploys $6,000 (6% of $100,000 equity)Entry 2: deploys $5,982 (6% of $99,700 equity)Entry 3: deploys $5,964 (6% of $99,401 equity)Entry 4: deploys $5,946 (6% of $99,103 equity)Entry 5: deploys $5,928 (6% of $98,805 equity)Entry 6: deploys $5,911 (6% of $98,509 equity)Final equity $98,213t1t6
Final equity
$98.2k
Total return
-1.8%
Stop / trade
0.3%
q₀ = ⌊(E·r ÷ D)·m⌋

Fixed-risk size dialed by confidence (m = 0.6 here).

Total equityPosition deployed at each entry (method color)Dashed line = $100k start
Show the numbers for this run
MethodExposureStop / tradePos. t1Pos. t6Final equityReturn
100% of Equity100%5%$100,000$77,378$73,509-26.5%
Volatility Targeting62.5%3.1%$62,500$53,326$82,655-17.3%
Kelly20%1%$20,000$19,020$94,148-5.9%
ATR-Based12.5%0.6%$12,500$12,114$96,308-3.7%
Fixed Risk10%0.5%$10,000$9,752$97,037-3%
Signal Proportional6%0.3%$6,000$5,911$98,213-1.8%

Simplification: the exposure fraction is held constant per method so it tracks equity cleanly. In practice it also moves with each method’s inputs — the stop distance (Fixed Risk), completed-trade statistics (Kelly), forecast, volatility and regime (Volatility Targeting), signal strength (Signal Proportional), and ATR and price (ATR-Based). Entry price is held at $100 and costs are excluded so the focus stays on sizing.

13References

Luo et al. — Seven Sins of Quantitative Investing, Deutsche Bank (2014).The one-day reversal look-ahead example in §3.
Bailey & López de Prado — The Deflated Sharpe Ratio, JPM 40(5) (2014).Test 1 and the chance benchmark in the MinervaScore.
Bailey, Borwein, López de Prado & Zhu — The Probability of Backtest Overfitting, JCF 20(4) (2017).Test 2 (PBO/CSCV); with the AMS paper, Test 4.
Bailey, Borwein, López de Prado & Zhu — Pseudo-Mathematics and Financial Charlatanism, Notices AMS 61(5) (2014).Why large searches produce winners by chance.
López de Prado — Advances in Financial Machine Learning, Wiley (2018), ch. 7 & 12.The held-back-data method and the purge/embargo gaps (§4); future data in adjusted prices (§2).
Bailey & López de Prado — The Sharpe Ratio Efficient Frontier, J. Risk 15(2) (2012).The MinTRL formula in Test 4.
Hansen — A Test for Superior Predictive Ability, JBES 23(4) (2005).The full Hansen SPA companion audit in Test 3.
White — A Reality Check for Data Snooping, Econometrica 68(5) (2000).White's Reality Check in Test 3.
Romano & Wolf — Stepwise Multiple Testing, Econometrica 73(4) (2005).StepM in Test 3.
Hansen, Lunde & Nason — The Model Confidence Set, Econometrica 79(2) (2011).The model confidence set screen in Test 3.
Benjamini & Hochberg — Controlling the False Discovery Rate, JRSS B 57(1) (1995).The FDR screen in Test 3.
Politis & Romano — A Circular Block-Resampling Procedure for Stationary Data (1992).The circular block bootstrap used by the predictive-ability gate.
Lipták — On the Combination of Independent Tests, MTA Mat. Kut. Int. Közleményei 3 (1958).The algebraic form of the weighted inverse-normal combination in §8.
Hartung — A Note on Combining Dependent Tests of Significance, Biom. J. 41(7) (1999).The lineage of the dependent-case denominator form in §8; Minerva uses it as a frozen population normalization, not as a combined hypothesis test.
Whitlock — Combining Probability from Independent Tests: Why Weighting?, J. Evol. Biol. 18(5) (2005).The rationale for the weighted inverse-normal combination in §8.
Harvey & Liu — Backtesting, JPM 42(1) (2015).Adjusting borderline results for search size.
Brown, Goetzmann, Ibbotson & Ross — Survivorship Bias in Performance Studies, RFS 5(4) (1992).§2.
Almgren & Chriss — Optimal Execution of Portfolio Transactions, J. Risk 3(2) (2001).The market-impact model (§5).
Kato — An Optimal Execution Problem with a Volume-Dependent Market Impact.The volume-dependent extension behind the participation cap (§5).
Lo — The Statistics of Sharpe Ratios, FAJ 58(4) (2002).The null sampling variance for DSR and the HAC Sharpe audit.