An exchange IP block turned a data library's import step into a process-killing crash, and the same day also saw a new research hypothesis go from preregistration to merge.
This is the English version of a post originally written in Korean for my algorithmic trading system devlog(new tab).
What happened when exchange access got blocked
Around midday, one of the trading rounds suddenly crashed.
Tracing it back, the Korea Exchange (KRX) had blocked the connecting IP. But the real problem wasn't the trading logic — it was in a third-party data library.
That library tries to log in to the exchange the moment it's imported. Normally that returns a clean JSON response, but once the connection is blocked, it instead gets redirected to an HTML login page.
The library tried to parse that HTML as JSON and threw an exception, which took down the entire import step with it — and that's what killed the trading round.
Tracing the cause and fixing it
Earlier that morning, a batch backfill of foreign-investor flow data had logged in to the exchange repeatedly, which plausibly triggered the block.
That said, this is only a timing correlation — the actual cause-and-effect was never confirmed.
The fix direction was clear: wrap the library's login function so that any exception (bad response, block, timeout) gets downgraded to a normal "login failed" state instead of propagating.
That way, a crash turns into just that day's exchange data being empty, while the rest of the trading logic keeps running. Fortunately, the live account's buying was already held by a separate safety mechanism(new tab) at the time, so this didn't translate into any actual loss.
The block hadn't fully lifted a day later, so retrying against the exchange was held off — retrying risks extending the block — with a one-time check planned for the next morning.
Same day, a new research hypothesis went from preregistration to merge
In the afternoon, a completely different task: a new research hypothesis using foreign-investor flow data.
The catch was that the historical window of this data had already been looked at once in a separate analysis. Reusing the same window and calling it a "confirmed" result wouldn't be statistically trustworthy.
So the hypothesis was locked into a document first (preregistration), with a minimum sample condition for detecting a statistically meaningful difference fixed in advance — if that bar isn't cleared, the verdict itself doesn't get opened. Changing the bar after seeing the results is off the table.
The implementation was handed to AI, and an independent code review was requested from a separate AI.
The review raised several points, all of which were addressed and merged the same day. That said, the code has only been run against synthetic test data so far — validation against real data is deferred to next month. No resident process imports this code yet, so today's merge had zero effect on live trading.
Also today: a Monday false alarm and six resident restarts
A monitoring check on technical-analysis data had a recurring false alarm: updates stop over the weekend, and Monday morning triggers a "no update in a long time" alert.
The fixed time threshold didn't account for weekends and market holidays. It now scales the allowed gap by the number of non-trading days, and whether it recurs next Monday will decide if the fix actually worked.
After market close, six resident processes were restarted together to pick up today's fixes. A prepared restart script made the restart itself go smoothly.
Top comments (0)