Quant Trading Bot Devlog

한국어로 보기

Wrapping Up Notification Cleanup, a Performance Calc Error, and a Regression

Five days across a weekend — I finished cleaning up the notification system, found that paper-account performance math didn't quite match the real balance, and a day later ran into a small regression from the fix

This is the English version of a post originally written in Korean for my algorithmic trading system devlog(new tab).

Writing again after a few days. The weekend was uneventful, and the three weekdays were filled with wrapping up cleanup work, a performance calculation error I found in the process, and a small regression the following day.

Finishing up the cleanup work

First, I redefined the standard for judging cash deployment. The old standard was "is cash within the target allocation range," but that turned out not to describe the real situation well. Now it directly counts "how many buy proposals got rejected" and "how much usable limit went unused."

The notification system cleanup also entered its final stage around this time. It now has an allowlist signature, alerts sent by severity tier, quiet handling when things are normal, a daily summary, and a weekly "still alive" check-in. This is an extension of an earlier post(new tab) about process separation and reporting.

Performance math didn't match the real balance

While reviewing the performance report for the fully automated verification track, I noticed the return shown in the report didn't quite match the real account balance. It turned out the report was calculated from an internally kept trade ledger rather than the actual brokerage account, and fees and taxes weren't being properly reflected — skewing it slightly better than reality. On top of that, unsettled trades at end-of-day close were getting logged under the wrong date.

I fixed three things right away: a calculation method that properly reflects fees and taxes, a daily cross-check between the internal ledger and the real account that alerts or blocks on mismatch, and a new performance path calculated from the real account. Background on this verification track itself is in a separate post(new tab).

The same day, I caught a small bug in the ranking calculation too. The staleness check on input data wasn't wired at the per-ticker level, so on certain days some tickers were silently dropped from the model input. Fixed.

A regression the next day, but it stopped safely

The next morning, one of the previous day's fixes had subtly changed the cache-invalidation criteria, creating a timing issue where the cache got refilled at the wrong moment. That collided with an old race condition elsewhere, triggering repeated heavy recalculations — made worse by old and new code running simultaneously during an incomplete deployment.

Fortunately, the end result was just that trading safely stopped — no bad orders went out. I traced it to four spots and fixed them, and it was a good reminder of a lesson learned before: when you fix code, restart every resident process that imports that module, all at once.

Also this week


Two of the five days were quiet, and the other three were about confirming and re-checking whether the numbers were actually correct. Not a flashy stretch, but the kind of check I think is necessary before widening the scope of live trading.