A fill from a completely different stock, placed nine days earlier, had gotten glued onto the wrong sell order — and I also retired a registry entry that had been alarming pointlessly for over a month.
This is the English version of a post originally written in Korean for my algorithmic trading system devlog(new tab).
The ledger and the broker kept disagreeing
One of my paper accounts(new tab) had a reconciliation(new tab) gap between the internal ledger and the actual broker balance that just wouldn't close.
A few days earlier I'd written this off as a temporary false alarm that resolved on its own.
Looking again, that call was wrong. The gap had never actually shrunk, and the account had been sitting frozen for days, unable to buy or sell anything because of a safety trip.
A fill from a different stock, nine days old, got glued on
Tracing it to the end, the root cause was a flaw in the external paper-trading server this account talks to.
On busy days, part of its order-history response gets truncated, and order numbers reset back to small values every new day.
Our own code, when looking up a specific order number, scans backward through recent days — but never checked whether the stock symbol or trade direction actually matched.
As a result, while confirming the fill for a sell order on one stock, it pulled in the fill from a buy order on a completely different stock, placed nine days earlier, just because the order numbers happened to collide. The quantity recorded was also far larger than the original order.
That mistake inflated the ledger's cash balance well beyond reality. The reconciliation monitor caught the gap, blocked new buys, and safely liquidated everything the account was holding. From that point on, the account sat idle — unable to trade — for days without anyone noticing the real cause.
Why none of the safeguards caught it
There was already a guard that rejects fills whose price is way off from the order price. This time the fill price happened to land within a plausible range by order of magnitude, so it passed.
There was no check comparing filled quantity against the original order quantity. Nor was there any check that the stock symbol itself matched.
None of the three layers of defense were actually looking at whether the symbol and direction lined up. I've designed a guard to close that gap, but I'm holding off running the actual ledger correction until I get sign-off.
A dead alert, retired the same day
Separately, on the same day, I retired a registry entry that had been firing an alert every single day for over a month.
This entry had originally been a one-shot check meant to run once and be done. Later it got registered as a "runs daily" job, but never actually got wired into the scheduler.
The account it was supposed to evaluate is structurally incapable of ever passing that check — so the alert had been firing pointlessly every day, toward a condition it could never clear. I pulled it out of the registry entirely and cleaned up the related tests.
Quiet isn't the same as resolved
The lesson I re-learned here: an alert going quiet doesn't mean the underlying cause got fixed.
A few days ago I'd looked at the surface fact — "no block triggered this round" — and concluded the problem had resolved itself. In reality, the account simply couldn't buy anything in the first place, so there was nothing left to block.
Quiet on the surface and actually resolved turned out to be two different things.
What's next
The ledger correction itself is waiting on sign-off.
Once approved, I'll strip out the misattributed fill and prioritize shipping the symbol/direction guard described above.
Top comments (0)