Monitoring Multiple Tickers at Once | Toss Dev #2-2

A day after splitting out the buy-decision logic into strategy.py, the next roadmap item was up: teaching the bot to watch more than one stock at a time.

The Problem: A Bot That Could Only Watch One Stock

Toss Securities is a Korean brokerage, and its API — like most retail brokerage APIs — returns prices in Korean won and expects a single account/token session per app. My auto_trader.py was built around a single TARGET_SYMBOL string in config.py. That was fine until it wasn’t: if consecutive errors crossed a threshold, the whole engine shut down, because the original design assumed there was only ever one symbol to lose.

The Redesign: TARGET_SYMBOL Becomes TARGET_SYMBOLS

TARGET_SYMBOL (a single string) became TARGET_SYMBOLS (a list). Each symbol now gets its own ThresholdBuyStrategy instance and its own consecutive-error counter, so one symbol’s problems can’t bleed into another’s.

The bigger change was the failure policy itself. Previously, hitting the error limit killed the whole engine. Now, only the offending symbol gets dropped from the watch list — everything else keeps running. That’s a real availability win, but it comes with a tradeoff: a symbol can silently drop out and nothing screams about it yet. Alerting is on the list for later.

Token expiry stayed a shared, account-level concern rather than a per-symbol one — the moment it’s detected, the bot re-authenticates and re-fetches every symbol.

class SymbolWatcher:
    def __init__(self, symbol, strategy, max_error_count=5):
        self.symbol = symbol
        self.strategy = strategy
        self.error_count = 0
        self.max_error_count = max_error_count
        self.active = True

    def handle_error(self):
        self.error_count += 1
        if self.error_count >= self.max_error_count:
            self.active = False  # only this symbol drops out

For testing, I registered four placeholder tickers — Samsung Electronics (005930), SK Hynix (000660), Kakao (035720), and Naver (035420). These are illustrative examples, not actual holdings.

Validation: Mock Simulation, Then a Real Local Run

First pass was a mocked simulation with no real API calls — three scenarios (“buys immediately,” “keeps failing on network errors and gets dropped,” “watches normally and eventually buys”) run concurrently across placeholder symbols, confirming they didn’t interfere with each other.

Second pass was an actual local run: four placeholder symbols registered, auto_trader.py running for real, cycling through all four every 5 seconds as expected.

All 38 existing pytest tests passed with no regressions, and safety-net values like DRY_RUN=True and TARGET_BUY_PRICE=1 were untouched.

The Gotcha: TARGET_STOCKS vs. TARGET_SYMBOLS

After bumping the symbol list to four entries, the bot still only watched one. Turned out config.py had two similarly-named variables: TARGET_STOCKS, used only by a separate price-lookup script (get_price.py), and TARGET_SYMBOLS, the one auto_trader.py actually reads. The wrong one had been edited.

Fixing the right variable solved it immediately. The names were close enough to cause real confusion, so renaming one of them for clarity is now a roadmap note for later.

What’s Next: A Plugin Interface for Strategies

The last item in Phase 2 is designing a plugin-style interface so indicator-based strategies (moving averages, RSI, etc.) can be added without touching the core engine. Having per-symbol strategy instances already in place should make that transition smoother.

FAQ

What happens if one symbol keeps failing while others are fine?

Only the symbol that crosses the error threshold gets dropped from the watch list. The rest keep monitoring normally — the engine no longer shuts down entirely.

Can different symbols run different buy strategies?

Structurally yes, since each symbol gets its own strategy instance. This round only validated running the same strategy across multiple symbols in parallel.

Is token expiry handled per symbol too?

No — it’s treated as an account-wide issue. As soon as it’s detected, the bot re-authenticates and re-fetches all symbols.

4 thoughts on “Monitoring Multiple Tickers at Once | Toss Dev #2-2”

  1. Pingback: [Toss Auto-Trading Dev Journal #9] Why I Locked Down the Data Persistence Design Before Writing a Single Line - Orbit - Space & ETF Investing

  2. Pingback: Wiring the Trading Engine Into SQLite Logging | Toss Auto-Trading Dev Journal #11 (Phase 3-3) - Orbit - Space & ETF Investing

  3. Pingback: Backtesting on Just a Price List | Toss Auto-Trading Dev Journal #13 (Phase 4) - Orbit - Space & ETF Investing

  4. Pingback: Candle API Pagination for Historical Backtesting | Toss Auto-Trading Dev Journal #14 - Orbit - Space & ETF Investing

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top