DEV Community

finaltype
finaltype

Posted on Originally published at finaltype.github.io

"[Aug 2026] Going Live and Onboarding a Second Broker, With Quiet Bugs Along the Way"

This month's biggest progress was starting live trading and running a second broker in parallel, while I kept turning up bugs that had been failing quietly for days

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

A quiet regression, then a full audit right before going live

August started with wrapping up the alert system work carried over from the previous month.

Along the way I found that the paper-trading performance report didn't quite match the real account balance.

The cause was a calculation that didn't properly account for fees and taxes, and the very next day a cache-timing side effect from that fix combined with an old race condition into a small regression.

Trading halted safely and no bad orders went out, but it was a reminder of a lesson I'd already learned once: when you fix a module, restart every resident process that uses it.

Over the weekend I revisited three long-deferred strategy questions — changing the trading cadence, trading continuously through the day, and switching to the US market — and dropped all three.

It confirmed that doubling down on the current three-round batch execution and domestic-market focus was the right call, rather than starting something new.

While polishing the offline replay tool, though, I found and reversed three of my own earlier conclusions. One of them turned out to be a budget-calculation bug that happened to skip crash-day trades, making results look better than they actually were.

The core of that weekend was a full pre-launch audit.

The live order-routing path, which the docs said was already connected, was actually still pointing at paper trading. A safety test showed green, but the safety switch it was supposed to be checking was actually disabled.

Both were the kind of problem where "it runs, but nothing is actually being verified" — I wouldn't have caught either without this audit.

Went live, and dropped the approval step

After that audit, live trading began.

The first round went through Telegram approval as usual, but once the order was filled someone asked "why do we still approve every single one?" — and the approval step was removed on the spot.

Trades now proceed automatically once mechanically checkable conditions are met, with a notification always sent after the fact.

That same afternoon, a manual trade made to free up cash was misread by the system as an unauthorized fill, and the safety switch force-halted trading twice.

I built a formal procedure to declare manual trades to the system so the same thing wouldn't happen again.

Background on order execution and the safety layer(new tab) is covered in an earlier post.

A few days later I found the drawdown baseline had been wrongly set: the balance at the moment live trading started got stored as the "all-time high," which broke the intended rule that drawdown limits could be manually reset within the same day. I fixed it and set a policy so kill switches and circuit breakers auto-release on the next trading day.

That had to be settled before moving to unattended overnight operation.

The GPU verdict flipped twice, and verification tools exposed hidden gaps

In week three I swapped the graphics card for a different brand — a big change.

After the production rollout, the conclusion was "one new card does the work of two old ones," but while re-examining whether to buy yet another card, the verdict flipped twice in a single day.

I ended up buying nothing, then later reversed that too, deciding to add one card for experiments alongside the existing one instead.

That same week, wiring a newly built report-figure verification tool into production revealed formatting errors in more than half the tickers in every daily report.

Looking back 45 days, the same error had been there every single day — nobody knew until the tool existed.

A daily reproducibility gauge also died two nights running, because it judged "GPU is free" from a single instantaneous read while another overnight job was actually holding it. Switching to a direct occupancy check removed the failure point.

The safety layer on the live account caused two incidents of its own this week.

A daily trading-budget allocation rule kept pushing a small sell order to the back of the queue for days, which I fixed; and a drawdown guard reacting to momentary intraday dips wrongly blocked two legitimate buys, which I redesigned to react only on a close-to-close basis. In both cases the blocked orders were executed manually.

The blog's publishing infrastructure also changed significantly this week.

The reason devlogs had gone quiet for over ten days turned out to be a save step silently stuck waiting on a permission prompt, and I used the opportunity to move publishing off Tistory — whose write API had been broken for a long time — to GitHub Pages and Dev.to.

The theme of "finding quiet failure points and making them loud" repeated all week.

I resisted the temptation to shift an A/B test's adoption threshold toward a better-looking subsample and kept the full-sample criterion instead, added pre-limit timing alerts to the paper-trading auto-validation track(new tab)'s execution unit after two timeouts I'd only noticed after the fact, and added observation logging to a safety layer that couldn't distinguish "zero detections because nothing was wrong" from "the detector itself died."

The second broker went from live verification to parallel operation

Week four's biggest progress was integrating a new broker.

I built the new client with an interface identical to the existing one, so upstream code wouldn't need to change when swapping brokers later.

I manually verified the full buy → sell → cancel-unfilled cycle on a live account within small limits, then had another AI review it — it came back with "not ready to swap in yet," so I fixed nearly everything it flagged and re-verified.

The very next day I put this broker on top of the paper-validation track as a separate sleeve and started parallel operation, keeping the existing broker as primary.

Instead of creating a bot-only account, I chose to safely share the existing account between manual and automated trading.

More quietly-broken-for-days bugs kept surfacing this week too.

While doing a full reclassification pass over the backlog, I found a lookup function had been silently returning empty values for 8 days because a required library was missing.

A separate cache had been broken for three days from mismatched library versions across environments, and a repeated-run verification job had been marking itself "complete" when a previous run had actually died midway.

On the last day of the week I found a midnight-boundary bug in the overnight monitor's time comparison, leaving the entire second half of every night outside monitoring — the third recurrence of a monitoring-gap failure I'd seen before.

I also moved several manually-checked things over to automation or AI review this week.

I standardized a scheduling function so GPU experiments stop colliding with settlement windows, and turned a months-stalled, manually-checked adoption condition for a new AI model in the ensemble into an automatic sensor that only alerts once the condition is actually met.

Another AI's full review also caught a process-kill rule that matched targets by model name alone, which could have killed an experimental server sharing a name with production — I narrowed it to also check the port number.

The weeks-long local-model comparison wrapped up this week too, with a new candidate promoted to production. I kept the retired model logging silently at zero weight in the AI ensemble pipeline(new tab) to see how closely the two models agree before deciding anything further.

Two incidents collided on the last day

Two incidents collided on the final day of the month.

A resident process that computes rankings hadn't restarted after a recent code change, so it kept running the old version for days and silently failed to pick up a newly added model family in its scheduled updates.

It went unnoticed longer because a sibling process on the same system happened to have restarted recently, so the whole system didn't look stale. That same afternoon, an entire round on the paper-trading auto-validation track vanished without a trace.

Digging in, I found the broker's API had been returning the average fill-price field scaled down by a factor of 1000. That corrupted value had been accumulating in the ledger, and the day-start baseline-reset logic misread it as an external cash movement, contaminating the P&L baseline.

That inflated the computed intraday drawdown far beyond reality and triggered the kill switch on a false signal.

I worked around it by deriving the unit price from an uncorrupted field instead, and since correcting the ledger is irreversible, I consulted another AI beforehand for the exact sequence and expected values.

That advice caught that my original three-step plan wasn't enough, and after correcting in the order backup → ledger fix → time-series fix → baseline regen → kill-switch release, the resulting numbers matched the AI's pre-computed values down to the decimal.


Two threads ran through this month.

One was visible forward progress: actually going live, moving to approval-free automatic execution and unattended operation, and taking a second broker through live verification into parallel operation.

The other was a repeated pattern of finding things that had been quietly failing for days — sometimes weeks — scattered throughout that progress: a process that never restarted, an API field silently scaled down, a monitoring window that missed the second half of every night.

Running into that same "it runs, but nothing is actually being checked" failure mode all month long was a steady reminder that this system still isn't at a point where it can be fully trusted on its own.

Top comments (0)