My trading bot started with a short, hand-picked watchlist: stocks I knew and liked. When I widened it to scan a much bigger slice of the market, I braced for the bot to start trading constantly.
It didn't. Trade count barely moved. What changed was the quality of what it picked, and the reason is in how the shortlist gets built:
def shortlist(universe, rules, max_picks):
"""Wide net, fine mesh: check everything, keep only what clears every rule."""
passed = []
for symbol in universe:
bars = get_daily_bars(symbol)
if bars is None:
continue # missing data is a skip, not a guess
if all(rule(bars) for rule in rules):
passed.append((score(bars), symbol))
passed.sort(reverse=True)
return [symbol for _, symbol in passed[:max_picks]] # an empty list is a valid answer
Three things this shape gets right:
-
The universe grows,
max_picksdoesn't. A bigger list means more candidates competing for the same few slots, so the bar effectively goes up, not down. - Every symbol gets the same rules. The thousandth stock is judged exactly like the first. No fatigue, no favorites.
- Empty is allowed. On a weak day, nothing clears every rule and the bot does nothing. That's the feature, not a bug.
The trap is the opposite move: loosening the rules so a bigger list produces more trades. That's how you turn a wide net into a lot of mediocre positions.
The full story, including the day the bot flagged a company I'd never heard of, is here: How I expanded my trading bot's watchlist.
If you're earlier in the journey, Part 1 is how I built a trading bot with no coding background.
Educational only, not financial advice.

Top comments (0)