How Bots Trade: The Life of a Bot Trade

Last updated July 11, 2026

This is the white paper on what your bot is actually doing all day: the clock it runs on, every gate an entry attempt has to pass, how it works an order into a fill, what it checks on your open trade twice a second, and exactly what happens in the moments after a stop is breached.

The clock everything runs on

While the market is open, tradeSteward's trading engine evaluates your bots on a steady heartbeat:

  • Entry attempts can begin every 10 seconds. On each 10-second beat, every bot that is scheduled to trade right now is examined against the full gate list below, and any bot that passes starts working an entry order.
  • Open trades are checked about every half second. Trade management runs continuously, evaluating profit targets, stops, exit times, and order health on roughly a 0.5-second cycle per open trade.

Two practical consequences fall out of this. First, an entry time of 10:30:00 means your bot's attempt begins on the first beat inside its window. The fill lands seconds later, after the order works. Second, nothing about your open trade waits for you: by the time you've seen a move on your screen, the engine has already evaluated it several times.

  Everything in this article happens only while the market is open. Outside market hours the engine stands down, and bots configured for the extended session are checked on a slower beat.

Opening a trade: the gate list

Before your bot sends an order, the attempt must pass every gate below, in order. Failing most gates just ends this attempt. The bot is re-examined on the next 10-second beat. A few gates, marked here, end the bot's trading for the whole day.

  1. Schedule. The bot is enabled, today is one of its entry days, and the current time is inside its entry window. If the bot uses entry-time randomization, its randomized start for today applies.
  2. Account switches. Your global bots toggle is on, the trading account is enabled, and nothing has halted trading on the account (for example, an account protection trip).
  3. Already in, or too soon. The bot isn't already in a trade it shouldn't stack on, and any entry delay since its last close has elapsed.
  4. Daily limits: these end the day when hit. Max trades per day, max profit-target hits per day, max concurrent trades, and max stops per day. When one of these trips, the bot logs it and stops trying until tomorrow, because no later attempt could change the answer.
  5. Multi-Entry cap. An entry of a Multi-Entry bot also honors the bot's Max Open Positions cap across all its entries.
  6. Dependencies. All four dependency rules are evaluated: don't open if a dependency is open, don't open if it has traded today, only open if it is open, only open if it has traded today.
  7. Entry filters. Every configured entry filter must pass: details in the next section, because the failure behavior is worth understanding.
  8. Custom endpoint. If the bot has a custom filter endpoint configured, tradeSteward calls it and honors its yes/no answer.

Only after every gate passes does the engine fetch quotes, build the order, and start working the entry.

How entry filters decide, and when they give up

Entry filters are checked at the last possible moment (after scheduling, limits, and dependencies) so they always judge the market as it is right now, not as it was when the window opened. What happens when a filter fails depends on what the filter measures:

Filter kindOn failureWhy
Gap filters (underlying gap %, VIX gap %)Done for the dayThe opening gap is fixed the moment the market opens. If it fails at 9:30, it fails at 2:00. Retrying is pointless, so the bot logs it and stands down until tomorrow.
Everything else (intraday move, net change, value min/max, moving averages and crossovers, RSI, opening-range breakout on the underlying or VIX)Retry next beatThese values move all day. The bot quietly re-checks on every 10-second beat, and the moment the filter passes inside the entry window, the entry proceeds.

This is why a bot with an intraday filter can enter at 10:47 on a window that opened at 9:45: it wasn't late, it was waiting for the filter to come true. The Bot Activity log records the filter evaluations, so you can see exactly which condition held an entry back.

Fresh quotes or no trade

Every entry decision and every price the engine works from starts with a live quote for each leg, and the engine is deliberately picky about them:

  • Stale is the same as missing. A quote more than a few seconds old is discarded. The engine re-requests it in quick succession; if a usable quote still hasn't arrived, the attempt is aborted and logged as a delayed quote rather than trading on old numbers.
  • No bid yet, no trade yet. An option that hasn't ticked yet today (no real bid or ask) is treated as having no quote at all.
  • Wide spreads get patience, then a decision. If a leg's spread is too wide to price honestly, the engine re-checks about once a second for up to 15 seconds. If it's still bad, the entry attempt is abandoned and you're notified, rather than filled into a market that would cost you the spread.

Working the entry order

The first order goes in at the trade's net mark: the midpoint of each leg's bid and ask, netted across the legs. From there, your Entry Speed setting decides how patient the engine is:

Entry SpeedAttemptsEach attempt rests
Turbo62 seconds
Fast38 seconds
Normal215 seconds
Slow230 seconds
Turtle260 seconds

Each attempt works like this: the order rests at its limit while the engine polls its status every few seconds. If it hasn't filled by the end of the rest period, the engine cancels it, re-fetches quotes, recomputes the mark, and resubmits, stepping the price one increment further toward the other side of the market on every attempt. Fast speeds cross the spread quickly and prioritize getting in; slow speeds insist on price and accept that they'll miss some entries.

The attempt cycle ends one of four ways:

  • Filled: the trade is open, and management takes over.
  • Partially filled: the filled contracts become a live, managed trade immediately; the engine keeps working the remainder on subsequent beats.
  • Out of attempts or out of window: a scheduled entry gives up when its entry window closes and logs that no entry was made. (Launch Now, webhook, and launch-on-stop entries aren't bound to the window and keep trying.)
  • Rejected: most commonly buying power. The engine checks buying power before sending, but if the broker rejects the order anyway, the attempt stops and you're emailed.
  If you cancel a bot's working entry order at your broker, the engine notices, logs that the order was canceled outside of tradeSteward, and abandons the attempt. It will not fight you for control of the order.

Managing the open trade

From the moment a trade fills (after a short settling period of about 15 seconds so broker records catch up), every half-second management pass walks the same checklist, in this order:

  1. Expiration. Expired legs are recognized and handled: AM-settled index options on the morning of expiration, PM-settled at their expire time.
  2. Exit time. If the trade has reached its configured exit DTE/DIT and exit time, it's closed.
  3. Manual instructions. A pending Close Trade or Reduce Trade Size you've queued is executed.
  4. Close dependencies. If the trade is set to close when another bot opens or closes, that condition is evaluated.
  5. Profit target. Evaluated and, when armed, rested at the broker (next section).
  6. Stop. Broker-resting stops are validated; algo stops are evaluated against live quotes; trailing stops update their high-water mark and check their giveback.

One refinement worth knowing: a trade whose protection is already fully resting at the broker (a working stop order, a working profit-target order, or no stop configured at all) doesn't need a half-second cadence, so the engine gives it a lighter check-in roughly every 15 seconds instead. Anything time-critical (a trailing stop, a pending manual close, a close dependency) keeps the full-speed cadence.

Profit targets: armed, rested, and re-checked

A profit target becomes a real limit order resting at your broker, but not necessarily at the moment the trade opens. By default, the engine waits until the trade has captured about 40% of the distance to your target, then submits the resting order. That keeps your working-order count down on trades that never get close, while making sure the order is sitting at the broker (fillable even in a fast market) well before the target is reached. You can tune or disable this arming threshold with the Profit Target Trigger preference in User Preferences.

Once rested, the order is validated on the regular check-in: if it's missing or no longer working, including if you canceled it at the broker, the engine re-places it from the bot's current settings. If you remove the profit target from the bot, the engine cancels the resting order to match.

Broker-resting stops: validated, and rescued

A stop set to rest at the broker gets the same treatment: the engine confirms on its check-ins that the stop order is actually working, and re-places it from your current stop settings if it isn't. Two edge cases get special handling:

  • The market beat the order there. If price has already blown through your stop level before a resting stop could be placed (or re-placed), the engine doesn't rest an order that would sit un-triggerable. It takes over on algo, exits the trade at market immediately, and emails you that it intervened.
  • The resting stop filled. The engine recognizes the fill, reconciles the trade as stopped, and, where the account's remaining legs need it, closes out anything the stop order didn't cover.

Delta-based stops can't be expressed as a broker resting order, so they always run on algo.

Stops on algo: confirm, then close

An algo stop is tradeSteward watching your stop level against live quotes on the half-second cycle and executing the close itself when it's breached. It happens in two distinct stages, both governed by your Stop Speed.

Stage 1: confirmation

A single half-second blip through your stop level shouldn't liquidate a position. So when the stop level is first breached, the engine starts a confirmation sequence: it re-samples the trade at fixed intervals and requires a set number of confirming hits within a set number of samples before the stop is considered real.

Stop SpeedHits requiredSample windowSeconds between samples
Lightning112
Turbo242
Fast238
Normal2320
Slow2430
Turtle3560

Lightning fires on the first breach with no confirmation. Turtle wants three confirmations a minute apart. It will ride out a two-minute spike that would have stopped a faster setting. There's also a No Check mode that skips confirmation and limit-order attempts entirely and goes straight to a market order, and a Custom mode where you set the hits, window, and spacing yourself.

Stage 2: the close

Once confirmed, the engine works the exit like an entry in reverse, but priced to get out rather than to get a bargain: the first closing order is placed partway into the spread (not at the mid), and each retry cancels, re-quotes, and walks the price further toward the far side. Stop Speed sets the pace here too:

Stop SpeedEach attempt restsLimit attempts before market order
Lightning1.5 seconds5
Turbo3 seconds5
Fast8 seconds4
Normal15 seconds4
Slow20 seconds4
Turtle60 seconds4

If every limit attempt goes unfilled, the engine cancels the working order and sends a market order so the exit is guaranteed. A stopped trade does not stay open because the market wouldn't meet a limit. (The one exception: brokers that prohibit market orders on multi-leg option orders get a maximum-aggression limit order instead.) Partial fills along the way are banked as closing trades, with only the remainder re-worked.

  If you cancel the engine's closing order at your broker mid-stop, the engine logs it and stands down. It treats the cancel as you taking the trade over manually. From that point the exit is yours to manage.

Trailing stops

Trailing stops ride on the same machinery with one addition: the engine tracks the trade's best profit on every half-second pass. Once profit reaches your trigger, the trail arms (you'll see it in the Bot Activity log); from then on, if profit gives back more than your trail amount from its high-water mark, the stop fires and the two-stage confirm-and-close sequence above takes over, using the trailing stop's own speed setting.

Around the edges

  • Wide spreads on the way out. Your Wide Spread Patience preference (in User Preferences) controls how long the engine tolerates an unpriceable spread before acting anyway on a management or stop decision. Set to unlimited, the engine will keep waiting rather than force an exit through a market that can't be priced fairly.
  • Bidless long legs. A long option with no bid can't be sold for anything, so a stop skips it (unless you've enabled selling no-bid longs) and closes the legs that have a market; see Bidless Long Credit Recovery for reclaiming the remainder.
  • The closing bell. Entry gates, profit-target evaluation, and stop monitoring all respect market hours: a confirmation sequence or closing cycle that runs into the close stops there and is logged accordingly.
  • After a stop. If the bot has Launch on Stop configured, the stop's completion is what schedules the follow-on bot's entry, honoring any configured delay.
A Bot Activity log showing one trade's full lifecycle: filter evaluations, the entry fill, the profit target resting, a trailing stop arming, and the stop-close sequence
The whole lifecycle is visible in the Bot Activity log: gate evaluations, the entry attempts, resting orders, and the stop sequence, each with a timestamp.

If you want to watch any of this happening on a live trade, the Bot Activity log is the engine's own narration: every gate decision, attempt, and order event in this article shows up there as it happens.