Allow the rounding a broker's own printed figures propagate

A real Scalable export refused to import at record 148: "buy gross -808.5599
does not equal quantity 6 times price 134.76, which is -808.56". Six NVIDIA
shares settled at 808.5599 against a printed price of 134.76, because the fill
was 134.759983 and the export printed the price to two places. One
ten-thousandth out, and the whole file was rejected.

The check held a gross to its own stated precision, which is only half the
story: the price is rounded too, and the file never says by how much. So the
allowance is now half a unit of the gross's stated precision plus one part in a
hundred thousand of the gross, compared against a product kept exact at 1e-16
rather than rounded first.

Measured over the complete export - 88 security rows - exactly one deviates at
all, by one part in eight million, eighty times inside the new bound. What the
bound still refuses is unchanged in kind: a price taken from the wrong share
class, and the misplaced decimal separator the check exists for, which misses
by four orders of magnitude. What it now accepts is the broker's own rounding,
including a whole cent once a gross stated to the cent passes about five hundred
euro, where a genuine one-cent error cannot be told from that rounding anyway.

The row is kept as a regression test alongside four grosses that must still be
refused: a cent, a euro, a wrong instrument's price, and a factor of ten.
This commit is contained in:
Lars Nolden
2026-09-12 12:20:19 +02:00
parent da817078f4
commit 635c11be56
4 changed files with 99 additions and 36 deletions
+17 -8
View File
@@ -443,17 +443,26 @@ The share column is signed only for corporate actions and depot transfers. Buys
and sells are unsigned and take their direction from the type. Both conventions
are resolved at import, once.
Every security row is checked against shares times price, to the precision the
export stated the amount at and no further. One export prints the exact product
to nine places, and the check is then exact. Another prints the notional rounded
to cents, where demanding exactness rejects every trade whose product does not
land on a whole cent - measured on a real export, 29 of 59 of them. One unit of
the stated precision is still four orders of magnitude tighter than the
misplaced decimal separator this check exists to catch.
Every security row is checked against shares times price, allowing for the
rounding the export's own printed figures propagate. Both ends are rounded and
neither states by how much: one export prints the notional to the cent, so
0,426581 shares at 63,06 settle as 26,90 where the product is 26,90019786;
another prints a price to fewer places than the fill actually had, settling six
NVIDIA shares at 808,5599 against a printed 134,76 whose product is 808,56.
The allowance is half a unit of the gross's stated precision plus one part in a
hundred thousand of the gross. Measured over a complete real export of 88
security rows, exactly one deviates at all, by one part in eight million.
What that still refuses: a price taken from the wrong share class, and the lost
decimal separator the check exists for, four orders of magnitude out. What it
accepts: the broker's own rounding, including a whole cent once a gross stated
to the cent passes about five hundred euro, where a real one-cent error cannot
be told from that rounding.
It cannot catch a separator lost uniformly across a row: 1 x 25,795 and
1 x 25795 both satisfy it. A price cross-check against an outside provider is
the only remedy and is deliberately not implemented.
the only remedy and is deliberately not implemented. A spreadsheet round-trip
is what strips those separators, so import the broker's original file.
Rejected whole, with the record number: an unknown status, an unknown type, a
classifying column that disagrees with its type, an account type other than the