Hey everyone, it's your resident 38-year-old 'oji' here, tinkering with AI agents and automated trading bots in the evenings and on weekends.
Today, I want to share a story about a quiet, unassuming bug in my self-built investment screener. It's a classic case where not a single line of code was wrong, yet the overall system continued to behave in an unintended way.
The Discovery: A Hunch About the 'Exclusion List'
I run a personal automated stock screener. It pulls data for all listed stocks, filters them based on my custom criteria, and narrows down potential candidates for monitoring. Pretty standard stuff.
Within this script, there was a static list of specific stock tickers to be mechanically excluded. For example, companies whose industry doesn't align with my strategy, or ones I'd previously researched and decided weren't a good fit.
# johnny_screen.py (conceptual code illustrating the problem)
# This list was not maintained
KNOWN_EXCLUSIONS = [
'6641', # Nissin Electric Co., Ltd. (Delisted 2023-04-27)
'9161', # ID&E (Found from logs, also delisted)
# ... many more defunct tickers mixed in
]
def screen_stocks(stocks):
# Exclude stocks whose ticker is in KNOWN_EXCLUSIONS
return [s for s in stocks if s.ticker not in KNOWN_EXCLUSIONS]
As you can see, the code is incredibly simple. Any ticker in KNOWN_EXCLUSIONS is simply filtered out from the screening process.
Recently, while reviewing some of the screener's logic, this list caught my eye. "Hmm, when was the last time I updated this list?" I wondered.
To be honest, I hadn't touched it much since I first created it. It was working, no errors, so I didn't give it a second thought. And that, my friends, was the quiet beginning of a silent bug.
The Cause: Tickers Delisted 2 Years Ago Were Still in the List
I had a bad feeling, so I started looking up each ticker code in the list. And boy, did I find some.
"I don't recognize this stock..." I thought, only to Google it and find it was delisted in 2023.
"And this one... oh wow, it was acquired and delisted more than two years ago!"
The list contained multiple tickers of "zombie companies" that had long since vanished from the market. In hindsight, this was quite problematic.
Here's how the script behaved:
- It fetches a list of all currently listed stocks (around 4000).
- For each stock, it checks if its ticker is in the
KNOWN_EXCLUSIONSlist. - Naturally, delisted tickers are not present in the comprehensive list from step 1.
- Therefore, the
if s.ticker not in KNOWN_EXCLUSIONScheck would never encounter an issue with these zombie tickers.
The code never threw an error. Nothing appeared in the logs. It just diligently performed a pointless check every single day, trying to avoid non-existent enemies.
This is the definition of a "silent bug." The logic itself is correct, but the data or configuration it relies on becomes stale due to real-world changes, leading the entire system into an unintended and inefficient state. Running automated systems, you sometimes fall into these traps.
The Fix and the Lesson: Configuration Files Have an 'Expiration Date'
The solution was simple. First, I manually went through the list and removed all delisted tickers.
But that alone isn't a fundamental fix. If I forget about this list again, in two years it'll be full of new zombies.
So, I decided to build in a mechanism to periodically check the validity of this "exclusion list." Specifically, I added a simple script that runs before the main screener. It checks if each ticker in KNOWN_EXCLUSIONS actually exists in the current list of listed stocks. If a ticker doesn't exist, it logs a warning.
This experience boiled down to one key lesson:
"Code might be right, but data rots."
Especially static configuration files that depend on external environments (like corporate mergers, acquisitions, or delistings in this case) will definitely become a cancer in your system if left unattended.
"It worked once, so it's fine" is not enough. There's no guarantee that configuration will remain "valid" a year or two down the line. I needed to adopt the mindset that configuration files, too, have an "expiration date."
When building automated systems, you need to design not only the logic but also the mechanisms for how to maintain the "freshness" of the settings and data it depends on, or how to detect when they've gone stale. Think of it as a self-diagnosis feature.
There might be similar, silently rotting configuration files lurking in systems at your workplace, forgotten by everyone. Sometimes, taking a look might lead to interesting discoveries.
Oji @oji_ai_dev
Top comments (0)