DEV Community

Anthony Zender
Anthony Zender

Posted on

I Was Building a Live Trading Bot and a Patented Wagering System. The Bug I Found Is Now Breaking AI Agents Everywhere.

This isn't a library I built to solve a theoretical problem.

It's a fix I built because real money was at risk.

The trading bot

I've been running a live QQQ/TQQQ momentum bot on Alpaca Markets. It reads 1-minute bars, scores market structure using VWAP, SMA8, SMA21, SMA34, and momentum signals, then enters leveraged positions in TQQQ (bull) or SQQQ (bear) based on that score.

The bot has retry logic built in. It has to — broker ACK timeouts are real. When you submit a market order and the network drops before confirmation comes back, you don't know if it filled or not. So the bot retries.

Here's the problem: if the first order actually filled but the confirmation timed out, the retry fires a second market order. On a 3x leveraged ETF, that's a doubled position you didn't intend. With real dollars on the line.

The bot already had a manual execution lock (EXECUTION_LOCK_SEC=15) and a JSON state machine to handle this. I built it by hand. It worked — mostly. But it was fragile, untested, and not something I'd want to hand to anyone else.

# The old pattern — retries up to 3 times
def place_order_with_retry(symbol, qty, side):
    last_err = None
    for attempt in range(1, EXIT_RETRY_COUNT + 1):
        try:
            return place_order(symbol, qty, side)  # fires twice if first timed out but filled
        except Exception as e:
            last_err = e
            time.sleep(EXIT_RETRY_SLEEP_SEC)
    raise last_err
Enter fullscreen mode Exit fullscreen mode

That place_order call has no memory. If attempt 1 filled and attempt 2 fires, you now own twice the position. The broker doesn't know you didn't mean it.

The wagering system

At the same time I was building the bot, I was designing PeerPlay — a patented P2P wagering exchange for skill-based video game tournaments (USPTO provisional 63/914,036).

PeerPlay has an escrow engine, a verification layer, and a settlement layer. The verification layer uses AI to confirm match results. When a verification agent times out and retries, the settlement layer can receive two confirmation signals for the same match. Two signals → two prize payouts. One tournament result, two winner transfers.

The patent protects the architecture. Nothing in the patent protects you from your own execution layer firing twice.

Same problem. Different domain.

The extraction

I realized the trading bot and PeerPlay had identical failure modes:

Agent/bot decides to act
    ↓
Network times out
    ↓
Agent/bot retries
    ↓
Side effect fires twice
Enter fullscreen mode Exit fullscreen mode

The fix in both cases is the same primitive: before you execute an irreversible action, check whether it already ran. If it did, return the original result. If it didn't, run it and store the result.

That's SafeAgent.

from settlement.settlement_requests import SettlementRequestRegistry

registry = SettlementRequestRegistry()

# Same request_id on retry → returns original receipt, never re-executes
receipt = registry.execute(
    request_id="trade:TQQQ:buy:2026-04-26T09:47:00",
    action="order_buy_TQQQ",
    payload={"symbol": "TQQQ", "qty": 10, "side": "buy"},
    execute_fn=lambda: place_order("TQQQ", 10, "buy"),
)
Enter fullscreen mode Exit fullscreen mode

First call executes the order and stores the receipt. Any retry with the same request_id returns the stored receipt — the broker is never called again.

Why this matters for AI agents specifically

The trading bot and PeerPlay are deterministic systems. They have retry logic because networks are unreliable. AI agents have the same problem but worse — they also have uncertain completion signals.

When Claude or any LLM agent calls a tool, it may:

  • Get a timeout and retry the same call
  • Receive an ambiguous response and call again to confirm
  • Run in a loop and re-trigger the same action
  • Get restarted mid-execution and replay from the last checkpoint

Every one of these scenarios can produce duplicate side effects. The agent frameworks (LangChain, CrewAI, n8n, OpenAI function calling) handle retries at the transport layer. None of them track whether the side effect already happened.

That gap — between the agent decision and the irreversible action — is where SafeAgent lives.

The state machine

SafeAgent doesn't just deduplicate by request_id. It enforces a finality gate:

OPEN → RESOLVED → IN_RECONCILIATION → FINAL → SETTLED
Enter fullscreen mode Exit fullscreen mode

Execution is only permitted from FINAL. If the agent's signals are ambiguous — conflicting tool responses, partial confirmations, uncertain outcomes — the state stays in IN_RECONCILIATION and the side effect is blocked until the outcome is clear.

This is what I needed for PeerPlay's verification layer. The AI model returns a confidence score. SafeAgent holds the settlement until that score clears a threshold. Below threshold: IN_RECONCILIATION. Above threshold: FINAL. Payout executes exactly once.

Where it fits in the MCP stack

If you're building agents on MCP, SafeAgent sits above your tool layer:

Claude / agent decision
    → SafeAgent finality gate
    → SafeAgent request-id dedup
    → MCP tool executes
    → Receipt stored (SQLite, survives restarts)
Enter fullscreen mode Exit fullscreen mode

It works with any MCP-capable host — Claude, Cursor, Windsurf, custom executors — without modifying the protocol.

As of today (April 26, 2026) SafeAgent is officially listed in the MCP registry:

io.github.azender1/safeagent v0.1.14
registry.modelcontextprotocol.io
Enter fullscreen mode Exit fullscreen mode

Install

pip install safeagent-exec-guard
Enter fullscreen mode Exit fullscreen mode

Python 3.10+ · Apache-2.0 · GitHub · Live demo

The trading bot integration example is in the repo at examples/safeagent_trading_integration.py — it shows the before/after pattern with real variable names from the QQQ bot.

The audit

If you're running agents or bots in production and want to know where your system can execute twice, I'm offering a focused duplicate execution risk audit for $499. Written report, every retry path, every side effect boundary, SafeAgent integration recommendations.

DM me or email azender1@yahoo.com.


Built by Anthony Zender, Dayton OH. Payroll tax accountant by day, agent infrastructure builder by night. USPTO provisional 63/914,036 — Zender Gaming Technologies LLC.

Top comments (0)