Quant Trading Bot Devlog

한국어로 보기

"[Oct 14] A Real-Account Manual Intervention, Patched With Eight Safeguards in One Day"

A buy block on a live account left cash piling up, so I traded manually through the broker app — and closed every gap that surfaced along the way, same day.

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

A buy block on the live account let cash pile up

On one sleeve of my live account(new tab), a loss-limiting safeguard tripped and blocked buys only.

It's designed as a one-day de-risking measure that lifts automatically the next day. But with no buys going out that day, cash kept climbing every time a sell settled.

Cash built up to a notably high share of the account by that point. Leaving it there would have wasted the whole day, so I lifted the block myself and ran a manual trading round.

Some of the orders the system placed got rejected by the turnover limit, and one failure didn't even leave a reason in the logs. I ended up filling the gap by trading directly through the broker's app, but there was no procedure for booking those manual fills into the ledger — so for a while, the broker account and the internal ledger diverged noticeably. A manual booking script later closed that gap down to nearly nothing.

Turning the manual intervention itself into something worth monitoring

I had another AI review the whole incident and surface every gap the manual intervention had exposed.

Eight came back, and I implemented and shipped all of them the same day.

One was a bug where the system misread a manually started round as a "scheduled automatic run." I fixed it by cross-checking timer records against service state to tell manual intervention apart correctly.

I also fixed the missing-reason problem for failed orders. Now the broker's rejection reason gets logged, and a single alert goes out per round if any order fails.

I added a guard that requires an explicit override flag before a manual order can go out close to market close — it's blocked by default otherwise.

I also built a standard procedure for booking manually executed app trades into the ledger. It used to run through a throwaway script; now a single formal command declares the fill.

The three kinds of intervention — lifting the block, running a manual round, and trading through the app — all now land in the audit log, and the daily report flags any day that had manual intervention. I rewrote the runbook to match the exact steps I actually followed.

Finally, I noticed that the turnover limit meant for automated trading actually got in the way during a manual catch-up like this, so I added an option to adjust that limit specifically for manual rounds. Other safeguards — per-position limits, the kill switch — stay untouched.

Also closed out today

A multi-day experiment came back inconclusive, so I closed it out rather than letting it drag on.

One account sleeve had been running in a limited pilot state for a while; this incident gave the final push to retire it officially.

I tried adding email as a second alert channel alongside Telegram, but decided the existing Telegram alerts were already enough and reverted it.

Why this matters

Today's incident wasn't really about a human stepping in to unblock and patch things manually — that part is expected to happen occasionally.

The real problem was that it didn't leave a proper trail. Afterward, I had to piece together why it happened, what got rejected, and how far the ledger and the real account had drifted apart.

All eight safeguards built today point the same direction: make the moment a manual intervention happens automatically log and alert itself, instead of leaving that to be reconstructed later.