BL-IN-002: Gross, Not Net

BIJECTIVE LABS


BIJECTIVE LABS . SEP 7, 2026


BL-IN-002: Gross, Not Net

Status: RELEASED

Classification: PUBLIC

Revision: 1

Date: 2026-09-07

Incident date: 2026-06-07 Class: K1, a cost term absent from the measurement path Rule produced: R-01


1. What was believed

By early June the programme had produced a series of verdicts. One of them read: T1.5, marginal pass, expected value +1.38 basis points per trade at a 7 basis point fee.

That figure had been used to justify continuing a line of work. The strategies looked marginal rather than broken, which supported the prevailing theory that the problem was either signal quality or instrument selection, and that better work on either would eventually push a strategy into positive territory.

Nobody suspected the measurement.


2. The trigger

The question came from outside the engineering track, and it was the right question:

Is it our strategy that cannot beat costs, or is there a gap in our code that makes every strategy fail?

That is a question about the measurement rather than about the market, and it had not been asked before.


3. The investigation

Six steps, one day.

Grep the shadow-tracking code for any fee, cost, or spread term. Zero matches.

Read the realised profit and loss function directly.

Recompute the historical T1.5 verdict with the missing terms restored.

Pull the stored shadow trades and re-tabulate them layer by layer.

Check the universe selector for a spread gate. There was none.

Confirm the data source was live mainnet rather than a demo feed, so that the spread figures being used were real.


4. The finding

The realised return function computed this:

realized_bps = (exit_mid - entry_mid) / entry_mid * 10000 * direction

Mid price at exit, minus mid price at entry, expressed in basis points. No fee. No spread. No slippage. No funding.

Every strategy verdict the programme had issued was a gross number wearing the label of a net one.

Restoring the terms to the T1.5 verdict:

TermValue
Fee assumed in the original verdict7.0 bps
Actual taker round trip, 0.055 pct per side11.0 bps
Fee understatement4.0 bps
Spread, unmodelled entirelyapproximately 3.0 bps
Reported expected value+1.38 bps
Corrected expected value-5.6 bps

The strategy was not marginal. It was negative by a wide margin, and had been the whole time.

A layer-by-layer tabulation of 28 stored shadow trades shows the shape of the error. The sample is too small to carry a verdict and is reproduced here only because it demonstrates the method:

LayerMean realised
Gross, as the shadow tracker reported it+24.76 bps
Less fee at 11.0 bps+13.76 bps
Less fee and full spread at 2.99 bps+10.77 bps

Fourteen basis points of the reported figure were costs that had never been subtracted.


5. Why it survived review

Three things kept it invisible.

The variable was named realized_bps. Realised, in trading, means after the fact and after costs. The name asserted a property the code did not implement, and every reader downstream inherited the assertion.

The number was plausible. A gross mid-to-mid return on a short-horizon microstructure strategy produces figures in the same range a net return would occupy if the strategy were working. Nothing looked absurd.

The failure was uniform. Because every strategy was measured the same way, the comparisons between them were internally consistent. The programme could rank strategies correctly against each other while being wrong about all of them in the same direction.

That third property is the one worth carrying away. A systematic measurement error does not present as noise. It presents as a coherent world in which everything is slightly disappointing.


6. What it cost

Not quantified in the archive, and the honest answer is that it cannot be.

Every verdict issued before 2026-06-07 was computed gross. That does not mean every verdict was wrong; most of the strategies were negative enough that costs would not have saved them. It means no verdict from that period can be trusted without recomputation, and the programme treated them accordingly.

No capital was at risk. Everything in that window was shadow.


7. The fix

The strategy logic itself was independently re-verified and found correct. The take-profit, stop, confluence, and cooldown paths all did what they claimed. The defect was entirely in measurement.

Five actions came out of it, in the order they were ranked:

  1. Build a net analyser for shadow trades, and convert every existing verdict from gross to net.
  2. Add a maximum spread gate to universe selection.
  3. Reduce the universe rotation interval from 24 hours to four to six.
  4. Only after net expectation is shown at or above breakeven, revisit the frequency caps and measure net expectation multiplied by frequency.
  5. Remain in shadow against live mainnet data until net expectation is positive on at least 500 trades.

Item four is worth noting for what it declines to do. There was an argument on the table that if per-trade edge were genuinely positive, the frequency caps should be removed rather than tightened, which is correct as arithmetic. The response was to make that action conditional on the net measurement landing first. Sequencing a correct argument behind a measurement it depends on is the discipline this incident produced.


8. The rule

What was wrong is that we judged viability from the gross number. From now on every verdict must be net.

This became R-01, the first rule in the register, and the cost identity in BL-D-011 section 4 is its formal statement. Every figure in this record is net of fee, spread, slippage, and funding accrual where the position spans a settlement, and every gross figure is labelled as gross.


9. What the source does not settle

The decision record cites the defective function at lines 100 to 103 of the strategy source. In the current repository the same computation sits at lines 106 to 110, unchanged in logic. The file has shifted since the record was written, and no commit hash is given, so the exact change that introduced the omission cannot be pinned from the document alone.

The 28-trade tabulation is explicitly labelled as too small for a verdict, and no later document confirms whether the 500-trade net-positive threshold in action five was ever reached. On the evidence of the Kill Ledger, it was not.


10. Cross-references

BL-D-011 section 4, the cost identity. BL-D-004 section 2.1. BL-D-009 rule R-01. BL-D-010 section 2.4. Ledger rows T1.5, DA-B, PS-A.


Copyright (c) 2026 Bijective Labs. All rights reserved.