Mastodon

Bumps and Bruises: Trading Bot Errors Nobody Warns You About (Part 2)

Last Updated 09/20/26

In Part 1, I walked through the smaller trading bot errors. The overnight protection gap, the day every score tied, the data that was quietly overwritten, and the bug that turned out to be a single word. Those were the papercuts. Annoying, instructive, survivable. This is the one I promised you at the end of that post. The longer day.

This is the trading bot error where my bot locked itself out of its own broker and left ten open positions sitting there with no active protection while it tried to figure out how to get back in.

If you only read one post in this series, make it this one. The others were typos and edge cases, the kind of thing you fix in an afternoon and laugh about later. This one was structural. It was the kind of trading bot error that looks completely fine right up until the exact moment it doesn’t, and then it stops looking fine in a hurry. It didn’t come from a bad line of code. It came from a decision that seemed smart, seemed clean, and quietly wired a single point of failure straight through the middle of the thing that was supposed to keep me safe.

Let me back up and show you how I built the trap, because the trap is the interesting part.

One Login to Rule Them All

Here was the setup. My bot isn’t one program. It’s a few of them working together. One piece scans the market. Another manages open positions and their stops. Others handle the overnight and after-hours work. Separate jobs, each with a narrow responsibility, each running on its own schedule. That design is deliberate and I still stand by it. Small programs that do one thing are easier to reason about, easier to test, and easier to fix at two in the morning than one giant program that does everything.

Every one of them needed to talk to my broker. And to talk to a broker’s API, you have to authenticate. You prove who you are, get a token back, and then attach that token to every request you make afterward so the server knows the calls are really coming from you.

So I did the obvious thing. One login. One authentication token. Every process shared it. It felt clean. Efficient, even. Why authenticate five separate times when you can authenticate once and pass the token around to everybody? It was less code, fewer credentials sitting in memory, one thing to refresh instead of five. Every instinct I had said this was the tidy, professional way to do it.

You can probably already see where this is going. I could not, at the time. When you build something yourself, you fall in love with the parts that feel elegant, and elegance has a way of hiding the exact place where everything is about to go wrong.

What “Talking to a Broker” Actually Means

It’s worth slowing down on the authentication piece, because it’s the hinge the whole story turns on, and it’s the part most people building their first bot never think about until it bites them.

When you place a trade by hand, you log into an app, tap a few buttons, and the app quietly handles the boring machinery of proving you’re allowed to do that. A bot doesn’t get to tap buttons. It talks to the broker over an API, which is a set of web addresses the broker exposes so that software, not a human, can ask questions and give instructions. “What’s my balance?” “What positions do I hold?” “Place this order.” Each of those is a request fired off over the internet, and each one has to carry proof of identity, because the broker is absolutely not going to move money around for an anonymous stranger.

That proof is the token. You send your credentials once, the broker hands back a token, and from then on the token is your badge. Every request wears it. Lose the badge, or get it revoked, and the door locks. The broker simply stops recognizing you, no matter how legitimate your intentions are.

Here’s the part that matters. The token doesn’t care which of my programs is holding it. It isn’t five badges for five employees. It’s one badge, and I’d handed the same one to every process and told them all to walk through the same door with it. As long as the door stayed open, that was fine. The trouble starts the moment somebody upstream decides to lock it.

The Rate Limit

Every broker API has a rate limit, a ceiling on how many requests you’re allowed to make in a given window of time. It isn’t there to punish you. It’s there to protect the broker’s own servers from being buried under traffic, and to keep any one account from hogging resources that everybody shares. It’s a completely reasonable thing for them to enforce. It is also, if you’re not paying attention, an extremely easy thing to trip.

Go over the ceiling and the server stops being polite. It doesn’t slow you down gently or send a friendly heads-up. It hands you back an error, the infamous 429, “Too Many Requests”, and simply stops answering until you back off. That’s the whole mechanism. You knocked too many times, so now the door won’t open at all for a while, and the length of “a while” is entirely up to them.

I knew rate limits existed. I’d read about them. I’d have told you, confidently, that of course I respected them. What I underestimated was how easy it is to trip one when several processes are all hammering the same endpoints, on the same token, at overlapping times. Individually, each job was reasonable. None of them was greedy on its own. But they didn’t run on their own. They ran together, and the broker doesn’t see five well-behaved programs. It sees one token making a flood of calls, because to the broker, the token is the account. Individually, each job was a person knocking politely. Together, they were a crowd pounding on the same door at once. And one afternoon, the crowd tripped the ceiling.

The broker stopped answering.

Locked Out of My Own Account

Here’s where the one-login decision came back to collect.

Because every process shared the same token, when that token got rate-limited, they didn’t fail one at a time. There was no graceful cascade, no line of dominoes I could watch fall and interrupt. They failed all at once, together, in the same instant, because they were all leaning on the same single point of failure. The scanner went down. The overnight jobs went down. And the piece whose entire job was to watch my open positions and manage their stops, that went down too. Same token. Same lockout. Same moment.

My bot was still running. This is the part that still gets me. Every process was alive, doing its loop, making its calls, behaving exactly like a healthy system. It just couldn’t see or touch the account it was supposed to be managing. It was, functionally, blind. Awake, active, busy, and completely unable to do the one thing it existed to do.

At that moment I had ten open positions. Ten. Real money, in real trades, exposed to a market that does not pause because your software is having a bad afternoon. And for a window of time I did not enjoy, the system responsible for protecting those positions could not read them, could not check them, and could not have placed or adjusted a single order if it had needed to. The protection wasn’t disabled. Nobody flipped it off. It was locked outside the building with everyone else, standing in the parking lot, holding a badge that had stopped working.

I want to be honest about the feeling, because the numbers don’t capture it. There is a specific kind of helplessness in watching a screen full of activity and knowing that none of it is reaching the place it needs to reach. The logs scroll. The processes hum. And you sit there doing the math on ten positions that, for these few minutes, have nothing standing between them and whatever the market decides to do next. I got lucky on the market’s mood that day. I don’t get to count on luck, and neither do you.

Lesson: Shared infrastructure fails together. If one login protects everything, one failure exposes everything. The convenience of a single shared credential is real, right up until the credential is the thing that breaks, and then the convenience becomes the blast radius. Isolate the thing that keeps you safe from the things that don’t.

The Worst Part Wasn’t the Lockout

You’d think being locked out would be the scary part. It wasn’t. Being locked out is a problem, but at least it’s a problem with a shape. The genuinely frightening thing was quieter.

The scary part was that the bot didn’t know it was blind. It wasn’t throwing a giant alarm that said “you currently have zero protection on ten positions.” It wasn’t panicking. It was quietly making calls, quietly getting rejected, and quietly trying again, over and over, with the mild persistence of a program that has no idea anything is wrong. From the outside, it looked busy. Logs were scrolling. Processes were running. Every surface-level sign of health was present and accounted for. If you’d glanced at it, you’d have said it was working.

Busy is not the same as working. That sentence cost me an afternoon of stomach acid to learn. A system that fails loudly is annoying. It pages you, it wakes you up, it ruins your dinner, but it tells you. A system that fails silently, while looking completely healthy, is dangerous, because you don’t go looking for a problem you don’t know you have. The failure doesn’t announce itself. It just sits inside the appearance of normal, waiting for you to notice on your own, and hoping you notice before the market does.

Lesson: The most dangerous failure is the one your system can’t tell you about. Build it so it screams when it’s blind, not so it whistles while it drowns.

Why Silent Failures Are So Common

I’ve come to believe silent failures aren’t rare bad luck. They’re the default, and you have to actively build your way out of them.

Here’s why. When you write software, you naturally spend your attention on making the good path work. You test that a valid order gets placed. You test that a real signal gets acted on. You watch the happy path succeed a hundred times and you feel good. What you rarely do, what almost nobody does early on, is sit down and deliberately ask, “How would this thing tell me if it had gone completely deaf?” That question isn’t fun. It doesn’t produce a feature. It produces a smoke detector, and smoke detectors are boring right up until the night they aren’t.

A bot that just does its loop will happily do its loop into a wall. It doesn’t have feelings about being rejected by the broker. A 429 isn’t painful to a program. It’s just another response to log and move past. The machine has no instinct for “this is bad and getting worse,” because you didn’t give it one. That instinct is something you have to build in on purpose, and it’s the least glamorous code you will ever write. It’s also, I’d now argue, the code that actually keeps you in the game.

The Fixes

None of these are clever. That’s the point. Every fix here is boring, and boring is exactly what this part of the system needed. Cleverness is what got me into this. Boring is what got me out.

Separate authentication for the process that matters. The component that watches and protects positions no longer shares a token with the loud, request-hungry jobs. It authenticates on its own, holds its own badge, and lives its own life. If the scanner stampedes into a rate limit now, it takes itself down, and only itself. The safety net keeps breathing. The whole disaster came from coupling the thing that keeps me safe to the things that generate the most noise, so the fix was simply to uncouple them. One failure should never again be able to reach across and blind the watchman.

Respect the rate limit instead of daring it. The calls are spread out and paced now, with proper backoff when the broker pushes back. Backoff just means that when the server says “too many,” the bot doesn’t immediately try again like a toddler mashing a doorbell. It waits, and if it gets pushed back again, it waits longer. You don’t beat a rate limit by hitting it harder. You never did. You beat it by not needing to hit it that hard in the first place, and by treating the broker’s ceiling as a rule to design around rather than a dare to test.

Reconcile against reality, every time. Before any process places or changes an order, it re-checks the broker’s actual state first. This one is a discipline, not a feature. What the bot thinks is true and what the account actually holds are two different things, and only one of them is allowed to be in charge. Memory drifts. State goes stale. The number in a variable is a rumor. The number at the broker is the fact. So the fact wins, every single time, no exceptions. The broker is the source of truth. Always. A bot that trusts its own memory over the broker’s ledger is a bot writing itself a future incident report.

And eventually, better infrastructure. This whole episode was one of the bigger reasons I later moved the bot onto an API built from the ground up for exactly this kind of automated, always-on use. Some tools are designed for humans clicking buttons a few times a day. Some are designed for machines that never sleep, that make calls around the clock, that need predictable limits and honest error signals to behave against. They are not the same tool, and trying to run the second kind of workload on the first kind of tool is a slow way to collect afternoons like the one I just described. It matters more than I expected. I thought infrastructure was a detail. It’s the floor everything else stands on.

What I’d Tell Someone Building Their First Bot

If you’re standing where I stood, excited about the strategy, ready to let a machine run it for you, here’s what I wish someone had grabbed me by the collar and said before that afternoon.

Assume every external thing you depend on will fail at the worst possible time, and build like you believe it. Your internet will drop. Your broker’s API will hiccup. A token will expire mid-loop. None of this is exotic. All of it is Tuesday. The question isn’t whether it happens. It’s whether your bot notices and does something sane when it does.

Give the safety-critical part of your system its own everything. Its own connection, its own credentials, its own reasons to fail. The piece that protects your money should be the most stubbornly independent thing you own, because the entire point of a safety net is that it holds when other things are falling.

Make silence loud. Decide, on purpose, what “healthy” looks like, and then build something that yells the moment reality stops matching it. A bot that can’t tell you it’s blind will let you find out the expensive way. Every serious operator I’ve talked to has some version of a dead-man’s switch, a thing that trips if the all-clear ever goes quiet. Build yours before you think you need it, because the day you need it is the day you can’t build it.

And respect the boring work. The scoring and the signals are the fun part, the part you’ll want to talk about. But the boring reliability work is the part that lets you keep running long enough for the fun part to matter. Nobody brags about their backoff logic. Backoff logic is also the reason some bots survive their first bad afternoon and others don’t.

What These Trading Bot Errors Taught Me

I got into this to build a strategy. The interesting part, the scoring, the signals, the theory, is the reason anyone starts. It’s the reason I started. But the thing that keeps a bot alive long enough to actually run that strategy has almost nothing to do with the strategy itself.

It’s authentication. It’s rate limits. It’s reconciliation. It’s knowing, in your bones, that your system can be completely broken while looking completely fine, and building it so that it can never quietly lie to you about being okay.

The trading bot errors that scare me now aren’t the loud ones, the crashes, the stack traces, the alarms. Those are gifts. Those tell you exactly where to look. The ones that scare me are the quiet failures that hide behind a system that looks like it’s working, the ones that let ten positions sit unwatched while the logs scroll on, serene and useless. Autonomy isn’t the thing you build first. It’s the thing you earn, slowly, after all the unglamorous reliability work is done and you’ve finally taught the machine to raise its hand when it’s lost. I didn’t know that when I started. I know it now, because there was an afternoon where ten positions taught me, and the tuition was higher than I’d like to admit.

Part 3 exists, by the way. There’s always a Part 3. But that’s a story for another day.

Steve is the founder of Bot and Bull. He reviews and evaluates the tools featured on this site and only recommends what he genuinely believes in. No press releases, no paid placements.


Found Bot and Bull useful? A quick review helps others decide whether this site is worth their time, and it takes about a minute. Review us on SmartCustomer →


Disclaimer: Everything in this post is shared for educational and informational purposes only and is not financial, investment, or trading advice. I am not a licensed financial advisor, broker, or tax professional. Automated trading carries real risk, including the possible loss of your capital, and the tools or platforms mentioned may not be suitable for your situation. Do your own research, and consider speaking with a licensed professional, before making any financial decision.

Leave a Comment