Everything you need to build your rules and understand what the bot does in your Interactive Brokers account. Read it once in full before activating your first rule; then use it as a reference.
An Interactive Brokers account with US options permissions. IBKR sets the permission level: buying options needs the basic level; spreads, the iron condor and selling uncovered options need a margin account and higher levels.
US options market data (OPRA) at IBKR. Without data the bot sees no prices and doesn't trade.
A Windows 10 or 11 computer, on and online during market hours (9:30 to 16:00, New York).
TWS or IB Gateway open and connected. We recommend a second IBKR username just for the bot, so you can log in from your phone without disconnecting it: the steps are in the ZeroTouch setup guide (/en/help).
Your ZeroTouch installation code (sent by email).
Install ZeroTouch Autopilot with the installer we sent you and open it.
In the Settings tab enter: the IBKR account (U… live or DU… paper), the port (IB Gateway: 4001 live / 4002 paper; TWS: 7496 live / 7497 paper), the Client ID (default 27; it must differ from any other program connected to the same TWS or Gateway) and your installation code.
Click Save and then Test connection: you'll get a test email.
Click Start. The top bar should read Connected and the New York time.
A call gains value when the price rises; a put gains value when the price falls. Buying an option: you pay a premium and the most you can lose is that premium. Selling an option: you collect the premium and take on the obligation; the loss can be much larger than what you collected if it isn't covered.
The strike is the exercise price. The expiration is the day the option expires. DTE is the days left until expiration. 0DTE = expires the same day (only on underlyings with daily expirations, such as SPY, QQQ or SPX).
Delta measures how much the option moves for each dollar of the underlying. In the wizard it's always written as a positive number, also for puts (a put with delta −0.30 is entered as 0.30).
| Delta you enter | Which option it is | How it behaves |
|---|---|---|
| 0.50 | At the money (ATM): the strike closest to the price | Balance between cost and movement |
| 0.55 to 0.80 | In the money (ITM) | Pricier, moves almost like the underlying |
| 0.15 to 0.45 | Out of the money (OTM) | Cheaper, moves less; if sold, more likely to expire worthless |
| 0.05 to 0.15 | Far out of the money | Very cheap; little movement |
If you collect more than you pay when opening, the position is a credit (for example a put credit spread). If you pay more than you collect, it's a debit (for example buying a put or a put debit spread). Profit and loss in % are measured on that opening credit or debit.
The bid is what buyers pay and the ask is what sellers want. The mid price is in between. The natural price is the one that fills for sure: sell at the bid and buy at the ask. The bot starts every order at the mid price and steps toward the natural price.
If you sold an option, IBKR may assign it (before or at expiration) and shares appear in your account. If you bought an option and it expires in the money, IBKR exercises it automatically and shares also appear: an exercised long put leaves you short 100 shares per contract; an exercised long call leaves you long 100.
The SPX, NDX and XSP indexes have no shares: they settle in cash at expiration and have no early assignment.
When you create a rule you choose a starting point: a template (put credit spread, iron condor, PMCC / diagonal, wheel) with default values, or 'Custom' to build it from scratch. On the Risk step the wizard tells you the name of the structure you built: use it to confirm it's what you wanted.
| Structure | Legs (in the wizard) | What it's for |
|---|---|---|
| Single long call or put | 1 leg: buy call (or put) by delta, for example 0.50 | Betting on a rise (call) or a fall (put) with maximum loss = the premium |
| Short put (uncovered) | 1 leg: sell put by delta, for example 0.30 | Collecting premium with a neutral or bullish view. The loss can reach the strike x 100 per contract |
| Vertical spread | leg1 by delta; leg2 'X from another leg', Reference pata1, value 5 (lower for puts, higher for calls). Same expiration | Capping the maximum loss. Buying the more valuable leg makes it a debit; selling it, a credit |
| Put credit spread (template) | Sell put delta 0.30 at 30–45 days; buy put 5 points lower | Neutral or bullish view with capped maximum loss |
| Iron condor (template) | Put credit spread + call credit spread, delta 0.16, 5-point wings | When you expect the price to stay in a range |
| Diagonal | leg1 buys by delta at more days (e.g. 30–60); leg2 sells by delta at fewer days (e.g. 0–7). Different expiration and strike | Selling short options against a long one that covers them |
| Calendar | Like the diagonal, with the same fixed strike on both legs | Profiting from the short option losing value faster |
| PMCC (template) | Buy call delta 0.80 at 300–540 days; sell call delta 0.30 at 25–45 days and roll it | Similar to a covered call, with less capital |
| Wheel (template) | Sell cash-secured puts; if assigned, sell covered calls on those shares | Collecting premium while buying shares at a price that works for you |
Starting point Custom, underlying QQQ. Legs: one leg, put, buy, by delta 0.50, minimum and maximum days 0. Entry: the day and time you want. Exit: for example 50% profit, 50% loss and Close at time 15:45 (so it doesn't reach expiration). Assignment: Close everything. Capital: 1 contract.
Leg1: put, buy, by delta 0.50, days 0 and 0. Leg2: put, sell, 'X from another leg', Reference pata1, value 5: for a put the bot places it 5 points lower, making a put debit spread (bearish). Leg2's days are turned off: it uses the same expiration as leg1.
Leg1: put, buy, by delta 0.60, days 30 to 60. Leg2: put, sell, by delta 0.30, days 0 to 0. In Rolls you can roll the long leg when it has, for example, 10 days left.
There are 9 steps. Each step is checked before moving on: an error won't let you continue; a warning (in yellow) is shown once and you can continue by clicking Next again. Every option with a default value has its explanation next to it.
Rule name, the ticker as it appears in IBKR (SPY, QQQ, AAPL, SPX…) and the template or Custom. An existing rule's structure isn't changed: for a different structure, create a new rule (you can use Duplicate).
Up to 4 legs. For each one: name, call or put, buy or sell, how the strike is chosen, value, minimum and maximum days to expiration, and quantity.
| Strike method | What the bot does | When to use it |
|---|---|---|
| By delta | Looks for the option with the delta closest to the one you asked for. With 0DTE delta jumps a lot from one strike to the next: if your target falls between two strikes, it takes the closest. If the chain doesn't reach (all far, more than 0.07 away), it doesn't open that day | Most cases: it follows the price on its own |
| % of price | Strike at that % of the underlying's price (0 = the closest to the price; negative = below; positive = above) | When you want a fixed distance in % |
| X from another leg | Same expiration as the Reference leg, X points lower (negative) or higher (positive) | The wing of a spread |
| Fixed strike | Always that exact strike | Rarely: if the price moves away, it stops making sense or isn't quoted |
Expiration: among the expirations that fall within your minimum and maximum days, the bot picks the one closest to the middle of the range. Example: 30 to 45 days → it looks for the one closest to 37.
Extra strikes (only for 'X from another leg'): if the exact wing strike isn't quoted, the bot waits up to 30 minutes and then may take at most that many strikes further away (default 1). If there's none either, it doesn't open that day.
Shows the structure's name (for a vertical spread it also says whether it's a credit or debit spread and bullish or bearish: check it, a flipped sign in the width gives the opposite strategy) and whether the loss is capped, can reach the strike x 100 (uncovered short puts) or is unlimited (uncovered short calls). With uncovered short calls you must confirm it explicitly to continue. The maximum loss in dollars is computed with real prices in the preview.
Days of the week, the New York time window in which it tries to open ('Open from', between 09:35 and 15:30, and 'Open until'), the minimum days between openings, and how many positions of this rule can be open at once. Moving-average filter (optional): only opens if the price is above (or below) its N-day average; 0 = no filter.
The bot opens only once per enabled day. From the 'Open from' time it tries to open. If at that moment it can't because it already has the maximum open positions (or the 'every N days' days haven't passed yet), it keeps watching and opens as soon as it can: for example, if a position closes at a profit at 12:10. But only until the 'Open until' time: after that time it doesn't open that day, even if a position closes. Empty = until 15:30. The templates come with 'Open until' 13:00; you can extend it.
If the 'Open until' time arrives with the maximum open positions, the Log says so: 'the opening time limit arrived … it won't open today'.
If the opening attempt fails (no contract met the rule, empty bid/ask, not filled, rejected by IBKR), it doesn't repeat it that day: it tries again on the next enabled day. If you edit the rule after a failed attempt, it tries again that same day with the new rule (not if it already opened a position).
Repeat during the day (from version 0.7.9, option rules with a signal): 'Repeat during the day' = how many entries the rule can make on the same day (1 = one, as always) and 'Minutes between entries' = the minimum time between them. After an entry, it enters again when the signal stops being met and is met again (for example, price goes back above -1% from the open and then falls again). If it's met again before the required minutes, that time doesn't count and it waits for it to trigger again. The maximum open positions still applies: to have 3 entries open at once, set the maximum to 3. The Log reports each step: 'entry 2 of 3 today', 'no longer met', 'triggered again but N min are left'.
When you activate a rule that won't open at that moment, the Log says why: it already tried today, the time limit passed, it isn't an entry day, it has the maximum open, or it's waiting for the 'Open from' time.
'Do not open while an opposite position is open on the same stock' (checked by default): with a TSLA put open, from any rule, a TSLA call rule doesn't open until the put closes, and vice versa. When the opposite position closes, it can open that same day if the signal is met and it's within the time window. Unchecked, it can hold both. Neutral structures (condor, butterfly) don't block.
A switch: 'Don't use a signal' (the rule opens by days and time window, as always) or 'Use an entry signal'. With a signal, you pick a prebuilt one or build your own, and the bot opens the first time it's met within 'Open from' / 'Open until'. Everything is explained in the «Entry signals» section.
The position closes on whichever comes first: % profit, % loss, N days before expiration or closing time. 0 (or empty) = that exit isn't used. With no exit at all, the position stays until expiration (or until the rolls).
You enter a New York time between 09:40 and 15:55 (for example 15:45) and choose when it applies:
| Option | What it does | What it's for |
|---|---|---|
| Every day (no overnight) | At that time it closes whatever is still open from the rule, every day | Never holding positions from one day to the next |
| Only on expiration day | On other days it does nothing; on the day any leg expires, at that time it closes the whole position | Not reaching expiration: avoiding exercise or assignment by IBKR (recommended for 0DTE) |
After the closing time the rule opens nothing more that day. 'Open until' must be at least 15 minutes before the closing time, so it doesn't open and close right away (without 'Open until', which means 15:30, the closing time must be 15:45 or later, up to 15:55). The closing order starts on that time's check (within 5 seconds) and is executed like any close: a limit order that moves toward the natural price in 4 steps of 10 seconds and, if it doesn't fill, at market. On early-close market days it moves up to 15 minutes before the close.
With open positions the bot checks every 5 seconds. Profit is measured at mid price (what you see in the Panel), wide quotes or not: as soon as it's reached, the closing order goes out from mid toward natural, but never worse than the price of your profit %, so it only fills at that profit or more. It doesn't go to market: if it doesn't fill, it stays at that price while the mid price stays above; if it falls, it's cancelled and the bot keeps watching. The loss stop is confirmed with 2 checks in a row (about 5 seconds) and isn't evaluated with a bid/ask wider than 30% of the mid price: so a stray quote doesn't take you out. Since version 0.7.17, a stop or trailing close goes straight to the natural price (bid) and, if it doesn't fill in 5 seconds, at market: in a fast drop, getting out fast is worth more than half the spread.
Below the loss % is 'FLEX stop: don't close at a loss before' (since Autopilot 0.6.2). With a New York time (for example 15:30), the loss stop does not close before that time, every day: if at the open the position is already below your stop (for example after an overnight drop), the bot doesn't close it and gives it time to bounce. From that time on, if the loss is still larger than the stop, it closes (with the same 15-second confirmation). Profit-taking, days to expiration and the closing time work the same. Empty = the stop works all day, as always.
| Example | Without FLEX stop | With FLEX stop 15:30 |
|---|---|---|
| You paid $3,000, 50% stop. It opens with the option at $1,000 and by 11:00 it's back to $3,400 | Closes at 09:30 at -$2,000 | Waits: at 15:30 it's in profit and doesn't close on the stop |
| You paid $3,000, 50% stop. It opens at $1,000 and at 15:30 it's still at $800 | Closes at 09:30 at -$2,000 | Closes at 15:30 at -$2,200 |
It goes between 09:31 and 15:55, needs a loss %, and if the closing time is 'every day' it must be before that time. On early-close days it doesn't go past the day's limit. While it waits, the Log writes once a day: 'FLEX STOP … is past the 50% stop, but it does not close before 15:30 (NY)'.
In rules where all legs are bought (long calls or puts) there are two more fields (since Autopilot 0.7.3): 'Trailing: activate at % profit' and 'Trailing: % drop from high'. When the position reaches that % profit, the bot tracks the highest value it reaches (at mid price) and closes it if it falls that % from that high. 0 in 'activate' = active from the open. 0 and 0 = no trailing.
| Example: you paid $1,500, trailing 100 / 50 | What the bot does |
|---|---|
| The premium rises to $2,400 (+60%) and comes back to $1,000 | Not activated (it didn't reach +100%): the rest of the rule applies |
| The premium reaches $3,000 (+100%) | It activates; the Log writes 'TRAILING … active' |
| It keeps going to $6,000 and drops to $3,000 (50% off the high) | Closes with about +$1,500; reason 'trailing 100% (maximo +300%)' |
It can be used together with the % profit (it closes on whichever comes first) or alone. The close is confirmed like the stop: 2 checks in a row (about 5 seconds), or on the first one if the value already dropped twice your % (with an 8% drop, if it already fell 16%). The order goes straight to the natural price (bid) and, if it doesn't fill in 5 seconds, at market (since version 0.7.17; before it was 15 seconds of confirmation and 4 steps of 10 seconds). In Results the reason counts as 'trailing'.
You see it in the Panel (since 0.7.4), Trailing column: 'waits for +100%' while it hasn't reached the activate %; 'ON +72% → +55%' when active (the highest profit it reached and the profit % where it closes). The Log writes when it activates, each new high in +25-point steps and, if you change the rule with the position open, the new values and the new closing point. The change applies on the next check: the high is kept and, if it was active, it stays active.
Price used to measure (stop only): Executable (default) measures with what it would cost to close at that moment; Mid price triggers earlier, but closing pays the bid-ask spread.
Near the profit target or the stop, the Log writes an EXIT line every minute with the % at mid, the executable % and each leg's bid/ask: so you always know why it closed or why not yet.
Rolling a leg = closing it and opening the same one further out in time, in a single order. You can roll at N days to expiration and, on short legs, at X% profit. If IBKR rejects the roll, the position stays as it was and it's retried the next day.
Minimum strike (wheel only): off by default. When on, the covered call is never sold below what the shares cost you.
| Option | What the bot does when shares appear from one of its legs |
|---|---|
| Close everything | Closes what's left of the position and sells or buys back the shares at market |
| Flatten and continue | Sells or buys back the shares and replaces the leg that left (PMCC, diagonals) |
| Wheel | Sells covered calls on the shares; if they're called away, goes back to selling puts |
| Only alert | Touches nothing: it alerts you and the shares stay in the account |
Shares appear in the account on the business day after expiration: the bot flattens them as soon as it sees them.
Fixed contracts: always that quantity per position. % of capital: opens as many units as fit with that % of the account value at risk (the combination's maximum loss), counting what this rule already has open. For structures with no maximum loss (something sold uncovered) the risk is estimated at 20% of the underlying's price x 100 per short contract: for those, use fixed contracts.
The rule in words: read all of it. 'Preview with today's chain' builds the order it would send today with real IBKR prices (strikes, expiration, delta, bid/ask, net, risk and units) without sending it. It also shows in dollars how much you make or lose per unit with your exit, and warns you if the stop is beyond the maximum loss (then it never triggers). The bot must be started and connected. Tick 'Activate the rule when saving' so it starts trading it.
The entry signal is optional and is chosen in step 5 of the wizard. Without a signal, the rule opens by days and time window, as always. With a signal, between 'Open from' and 'Open until' the bot checks the signal on every check (every 5 seconds while it waits for it) and opens the first time it's met. If it isn't met before 'Open until', it doesn't open that day and the Log says so.
The signal combines with any strategy: for example, 'RSI oversold' with a put credit spread, or 'Low volatility' with an iron condor. The signal decides when to open; the strategy, what to open.
The two prebuilt fade signals combine 'not exceeded', 'Pullback (%)' and 'Change since today's open (%)': the day's low (or high) holds for 30 minutes without being exceeded, price has already moved 0.4% away from that extreme and, in addition, the day is inside a band relative to the open: for the call, below the open but by no more than 0.75%; for the put, above the open but by no more than 1%. A new extreme resets the pullback to 0. You change the minutes, the % and the band.
Up to Autopilot 0.6.0 the prebuilt fade signals used dollars ($1 pullback and a first move of no more than $1.25). Rules saved with that signal don't change. That version can still be built by hand with 'Pullback ($)' and 'First move ($)': the first move discards an extreme if price had already gone further since it was set, so it doesn't enter when price comes back toward an extreme from hours earlier.
They are typical combinations, with starting values you can change. They are tools: they are not a recommendation and haven't been tested by ZeroTouch.
| Signal | Condition (starting values) | Often used to |
|---|---|---|
| RSI oversold | 5-minute RSI(14) below 30 | Look for a bounce after a fast drop |
| RSI overbought | 5-minute RSI(14) above 70 | Look for a pullback after a fast rise |
| Bullish moving-average cross | 9 EMA crosses above the 21 EMA (5 minutes) | Follow a trend change up |
| Bearish moving-average cross | 9 EMA crosses below the 21 EMA (5 minutes) | Follow a trend change down |
| Opening-range breakout up | Price above the 9:30-10:00 high | Follow the morning momentum |
| Opening-range breakout down | Price below the 9:30-10:00 low | Follow the morning momentum |
| Opening gap down | Open 0.3% or more below the previous close | Follow or fade a gap |
| Opening gap up | Open 0.3% or more above the previous close | Follow or fade a gap |
| Down day | Price 0.5% or more below the previous close | Enter on down days |
| Up day | Price 0.5% or more above the previous close | Enter on up days |
| Price above VWAP | Price above the day's VWAP | Filter in favor of buyers |
| Price below VWAP | Price below the day's VWAP | Filter in favor of sellers |
| Daily uptrend | Price above its 50-day average | Trade only with the trend |
| Daily downtrend | Price below its 50-day average | Trade only with the trend |
| Low volatility (VIX) | VIX below 20 | Sell premium in a calm market |
| High volatility (VIX) | VIX above 25 | Sell premium further out or buy protection |
| Fade of the day's high | The day's high hasn't been exceeded for 30 min or more, price has pulled back 0.4% or more from it, and the change since today's open is above 0% and at or below 1% | A put at the highs when the day is only slightly up from the open |
| Fade of the day's low | The day's low hasn't been broken for 30 min or more, price has bounced 0.4% or more from it, and the change since today's open is at or above -0.75% and below 0% | A call at the lows when the day is only slightly down from the open |
With 'Add condition' you build up to 6 conditions and choose whether all or any must be met. Each condition comes from this menu:
| Condition | What you choose | How it's measured |
|---|---|---|
| RSI | Timeframe (1, 5, 15 min or daily), period, below/above, value | Wilder's RSI on closed bars |
| Moving-average cross (EMA) | Timeframe, fast and slow average, crosses above/below, above/below | 'Crosses' is met on the bar of the cross; 'above/below' looks at the position |
| Price vs moving average | Timeframe, period, above/below | Intraday: EMA; daily: simple average of previous closes |
| Opening range | Minutes (5 to 120), breaks the high/low | High and low from 9:30; only after those minutes |
| Opening gap (%) | At or above / at or below X% | The day's open vs the previous close; once a day |
| Day change (%) | At or above / at or below X% | Current price vs the previous close (includes the gap) |
| Another ticker's day change (%) | Ticker (e.g. QQQ), at or above / at or below / below / above X% | The same, but for another ticker: to look at the market. Example: a TSLA put with 'QQQ below 0.5' doesn't open while QQQ is up 0.5% or more. Price once a minute |
| Change since today's open (%) | At or above / at or below / below / above X% | Current price vs today's open (first 1-minute bar). Two conditions make a band: '>= -0.75' and '< 0' |
| Price vs VWAP | Above/below | The day's VWAP from 1-minute bars |
| VIX | Below/above a value | VIX price (needs the CBOE indexes package at IBKR) |
| Price | Below/above a value | The underlying's current price |
| Near ($) the day's high/low | Near the high or the low, X dollars or less | Distance between the current price and today's high (or low) |
| Day's high/low not exceeded (min) | The high or the low, N minutes (1 to 300) | How long since price last made a new high (or low) for the day |
| Pullback ($) from the day's high/low | From the high or from the low, X dollars or more | How far price moved away from today's high (or low): if it makes a new extreme, the pullback goes back to 0 |
| Pullback (%) from the day's high/low | From the high or from the low, X% or more | Same as the dollar one, but in % of the extreme: the same number asks for the same move on stocks of different prices (0.4% is ~$0.88 on a $220 stock and ~$2.88 on a $720 one) |
| First move ($) off the day's high/low | Off the high or off the low: never moved more than X dollars | That this is the first time price moves off the extreme: if since it was set price already went further than X, that extreme is discarded until a new one is made |
Price conditions (range breakout, day change, price vs VWAP or vs an average, price) compare the current price with the level, without waiting for the bar to close. RSI and crosses use closed bars: a bar in progress changes several times a minute and would give signals that later disappear.
The bot uses IBKR 1-minute bars, closed ones only (a bar in progress doesn't count); 5 and 15-minute bars are built by joining the 1-minute ones from 9:30. RSI, crosses and 1/5/15-minute averages also use the previous day's bars, so they have data from the open. The gap, the opening range and VWAP use only today's. Bars are requested from IBKR once a minute per underlying.
In the Log: while the rule is waiting, 'SIGNAL …: not met yet (detail). It keeps watching until HH:MM' (once a day); when it's met, 'SIGNAL …: met (detail)' and it opens; if it isn't met in time, 'SIGNAL …: it wasn't met today before HH:MM'. The preview says whether the signal is met at that moment.
With the stocks module, the wizard has one more starting point: 'Stocks'. The rule buys shares (long) of the ticker you choose, with the same entry conditions as option rules (days, time window, moving-average filter, signals). Not for indices (SPX, NDX, XSP). Short selling comes as another module.
With 'Stocks' the wizard offers three templates or 'Free' (since Autopilot 0.7.2). Each one sets the entry and the exit; everything can be changed afterwards.
| Template | Entry | Exit |
|---|---|---|
| RSI(2) bounce with trailing | Daily RSI(2) below 5 and price above the 200-day average; buys from 10:00 to 10:30 | SL 6%, trailing 4% from +4%, sells after 10 days at 15:50 |
| RSI(2) bounce with fixed TP | The same entry | TP 5%, SL 5%, sells after 5 days at 15:50 |
| Daily 9/21 moving-average cross | The 9-day EMA crosses above the 21-day (daily closes); buys from 10:00 to 10:30 | SL 8%, trailing 6% from +6%, sells after 30 days at 15:50 |
They come from QuantConnect backtests (2019–2026, 1-minute bars, IBKR commission and slippage) on two different groups of stocks.
A fixed number of shares, a dollar amount (it buys the whole shares that fit at the purchase price) or a % of the account value. The purchase is a limit order from the mid price that moves toward the ask in 6 steps of 20 seconds; if it doesn't fill, it doesn't buy and retries at the next entry.
As soon as the purchase fills, the bot leaves the sell orders placed at IBKR, in an OCA group (when one executes, IBKR cancels or reduces the others) and GTC (they carry over from day to day). They work even with the computer off or without internet.
| Exit | Order at IBKR | Comment |
|---|---|---|
| TP +X% | Limit sell | At the TP price or better |
| SL -X% | Stop (or stop limit outside regular hours) | Always in place, except with SL FLEX |
| Trailing X% | Trailing stop | Follows the high. With 'from +Y%' the program places it when the position reaches +Y% (it must be open that day) |
| SL FLEX from hh:mm | Day stop, active from that time | Not in place overnight: each day the program places it in the morning (it must be open that day). Optional: a wider safety stop, always in place |
| Forced exit | Sent by the program | Every day at a time (no overnight) or after N calendar days at a time: cancels the protection and sells (limit at the bid; market after 20 s; from 15:55 to 15:58 straight to market) |
Outside regular hours (optional per rule): the TP and stops also execute in pre and post market, as a limit with a margin (1% by default). Liquidity may be low outside regular hours.
A stock position can stay open for weeks. On the Dashboard it shows as '+N TICKER (shares)', with its value, the result and the days since the purchase. 'Close now' cancels the protection and sells.
If you sell the shares in TWS, the bot marks the position 'closed outside the bot' and cancels its protection orders (so it doesn't end up short). If you sell part of them, the position continues with the rest and its protection is redone for that quantity. If you cancel a protection order in TWS, it alerts you and does not place it again.
Shares from these rules are kept apart from option rules: an assignment is still detected by the change in shares without counting the stock rules' shares, and your own shares are not touched.
This section puts in order how to enter a rule with a signal and the most common mistakes. The numbers in the examples show how to enter it: they are not a recommendation and haven't been tested by ZeroTouch for your account.
For example: “I buy 1 AMD call 1 to 3 days to expiration, delta 0.50, when the day's low has held for 30 minutes, price has bounced 0.4% from that low and the day is below the open but by no more than 0.75%. I enter between 11:00 and 13:00. I close at 75% profit or 30% loss, otherwise at 15:45 on expiration day.” If you can't write it this completely, it isn't ready to be entered yet.
Call or put, buy or sell: a long call is bullish and a long put is bearish. In a spread, step 3 says whether it's a credit or a debit and bullish or bearish: it has to match what you intended (a flipped sign in the width gives the opposite strategy). Strike by delta follows the price (0.50 = near the money). The minimum and maximum days to expiration (for example 1 to 3) pick the expiration closest to the middle of that range.
'Open from' and 'Open until' are the window in which the signal can open. If the idea only holds at one moment of the day, the window has to be short: for an opening gap you look at at 9:45, set 'Open from' 09:45 and 'Open until' 09:50. With a long window, the signal can be met hours later for another reason and open something that wasn't your idea.
The bot opens once per enabled day. 'Maximum open positions' and 'Minimum days between entries' limit how often it enters. If you have a call rule and a put rule on the same stock, decide whether you want 'Do not open while an opposite position is open' (checked by default): checked, while one is open the other waits.
Unit. Each condition's name starts with its unit: 'Pullback ($)' asks for dollars and 'Pullback (%)' for a % of the day's high or low. The same number is not the same thing: 0.4 in (%) is about $0.88 on a $220 stock; 0.4 in ($) is 40 cents. To use the same rule on stocks of different prices, use (%).
Side. After choosing the type, check the comparison. For a call on a bounce off the low, every extreme condition has to say 'low' (not broken, pullback from the low); for a put at the high, 'high'. Mixing sides gives a signal that is almost never met or that enters the wrong way. When you change the type, the wizard keeps the side you had, but check it anyway.
Band. Two 'Change since today's open (%)' conditions with 'all conditions' make a band: '>= -0.75' and '< 0' = the day is below the open, but by no more than 0.75%. For the put, '> 0' and '<= 1'. Don't confuse it with 'Day change (%)', which is measured against the previous close and therefore includes the gap.
'All conditions' requires all of them at the same time; 'any of the conditions', any one. For a signal with confirmation it's almost always 'all'.
| Condition | Comparison | Value |
|---|---|---|
| Day's high/low not exceeded (min) | Low | 30 |
| Pullback (%) from the day's high/low | From the low | 0.4 |
| Change since today's open (%) | At or above | -0.75 |
| Change since today's open (%) | Below | 0 |
That is how the example in point 1 is entered (it's the 'Fade of the day's low' prebuilt signal). For the put at the high: high, from the high, above 0 and at or below 1.
The profit % and the loss % are measured on what you paid (or received) when opening. With 1 to 3 day expirations, decide whether you want to hold overnight: 'Close at time' with 'Only on expiration day' keeps the position open on the previous days and closes it at that time on the day it expires; 'Every day' closes it each day. In a position where everything is bought, a stop of 100% or more doesn't act before expiration.
To start, fixed contracts: you know exactly how much goes in. With '% of capital' the quantity changes with the account value.
The summary states the rule in words and has to say the same as your sentence from point 1. That's where the typical mistakes show: 'call' where you meant 'put', 'from the high' where you meant 'from the low', dollars where you meant %, a stop different from what you intended. The preview builds the order it would send today with real prices and says whether the signal is met at that moment.
Activate it first on an IBKR paper account (starts with DU). In the Log, the SIGNAL lines say what's missing for it to be met. OPENING alerts say what it bought or sold (“buy 1 call AMD 540 expiring …”), how much it paid or received and the maximum risk; CLOSE alerts give the result in dollars (PROFIT or LOSS) and the reason.
Each rule is independent: with several active they can open on the same day and add up risk. Add up the maximum loss of all those that can be open at the same time and make sure your account can bear it. Use an IBKR account only for Autopilot (see “Your account: what the bot touches and what it doesn't”).
A combination can be tested with historical options data, for example on QuantConnect. It's best to set aside one period to build the rule and a later one to verify it: a rule fitted to a single period often doesn't repeat. A past result doesn't ensure the future.
With open positions or orders in progress it checks every 5 seconds (exits, rolls and orders), with real-time prices. With nothing open it checks every 30 seconds (entries).
It sends new orders between 09:35 and 15:55 New York time (on early-close days, until 5 minutes before the close). Exception: a profit-target or stop close goes out from 09:30, as soon as the market opens, on the same check in which it's met (if the position comes from the previous day, a strong open can be taken right away; with a FLEX stop, the stop waits until its time). At that time bid/ask spreads are often wide: if they exceed 30% of the mid price, the bot waits for them to normalize.
Each order is a single combo order with all the legs. It starts at the mid price and steps toward the natural price: an opening in 6 steps of 20 seconds (2 minutes); a close or roll in 4 steps of 10 seconds. Exception: a stop or trailing close starts at natural and goes to market after 5 seconds.
An opening never goes to market: if it doesn't fill at the natural price, it's abandoned and retried on the next enabled day. A close or roll that doesn't fill at the natural price goes to market (in under a minute). From 15:55 to 15:58 every close (stop, time, days, Close now) goes straight to market, and a limit close that is still unfilled switches to market; from 15:58 nothing is sent. On early-close days: 5 and 2 minutes before that close.
On expiration day, a position made only of bought legs, all at least 2% out of the money and with no buyer (bid 0 or 0.01), is not closed by stop, time or days: it is left to expire worthless (closing it would only cost commission and there is no possible assignment). In the Log: 'SE DEJA VENCER …' (left to expire).
There are never two live orders at the same time for the same thing. Orders are day orders: at the close the ones still live are cancelled; a pending close or roll continues the next day.
If an order partially fills, the filled part is recorded as a position and the order continues with the rest.
If IBKR rejects an order (margin, permissions, etc.), the reason is recorded in the Log exactly as IBKR gives it.
This section explains, for each situation, when the bot finds out and how long execution can take. Read it before using Autopilot with real money.
| Situation | When the bot detects it | How it sends the order | How long it can take |
|---|---|---|---|
| Entry (between 'Open from' and 'Open until') | On the first check from that time: up to 30 s later (5 s if positions are already open). If it couldn't open, as soon as it can, until 'Open until' | Limit at mid price stepping toward natural in 6 steps of 20 s | Up to about 2 minutes. If it doesn't fill, it doesn't open that day (never at market) |
| Entry with a signal | On the check in which the signal is met, within the time window (check every 5 s while waiting for it) | Same as any opening | Price conditions (breakout, change, VWAP, average, price): up to 5 s. RSI and crosses: at the bar close + up to 5 s. Plus up to about 2 minutes of order |
| Profit target | On the next check (every 5 s), from 09:30 | Limit stepping toward natural in 4 steps of 10 s and, if not filled, at market | Usually under 1 minute |
| Loss stop | 2 checks in a row (about 5 s), from 09:30 (with a FLEX stop, from its time) | Limit at natural (bid) and, if not filled in 5 s, at market | About 5 s of confirmation + 5 to 10 s of order |
| Trailing (options) | 2 checks in a row (about 5 s) once activated; on the first one if it already dropped twice your % | Limit at natural (bid) and, if not filled in 5 s, at market | Up to 5 s of confirmation + 5 to 10 s of order |
| Close at days to expiration | On the first check of that day | Same as the profit target | Under 1 minute |
| Time exit (Close at time) | On that time's check (within 5 s) | Same as the profit target | Under 1 minute |
| Roll | On the check after it's met | A single order; 4 steps of 10 s and then at market | Under 1 minute. If IBKR rejects it, it's retried the next day |
| Assignment or exercise | When IBKR shows the shares (usually the next business day) | Shares at market (per the step 8 option) | At the market open |
| From 15:55 to 15:58 | — | Opens nothing; closes go straight to market | Seconds |
| After 15:58 | — | Sends no orders | Whatever wasn't closed by the rule reaches expiration |
The stop and the trailing wait 2 checks in a row (about 5 seconds) so a stray quote doesn't take you out, and their order goes out at natural to fill right away. Even so, in a very fast drop the closing price can be worse than your rule's level.
Exits aren't evaluated while any leg has a bid/ask wider than 30% of its mid price (it sometimes happens at the open or in illiquid options): the bot waits until it normalizes.
Each open leg uses one IBKR real-time market data line. IBKR gives 100 lines by default: plenty for most, but keep it in mind with many 4-leg rules open at once.
The times in this table are the program's operating targets; they may vary slightly with your computer, your connection, the market data and IBKR's systems.
| Strategy | What to keep in mind about timing |
|---|---|
| 0DTE (single long option, vertical spreads) | Price moves very fast: the seconds between the condition and the fill matter. If neither profit nor loss is hit and you didn't set a closing time, the position reaches the close and expires: use 'Close at time' (for example 15:45) or choose the step 8 option carefully |
| Credit spreads and iron condor (30–45 days) | Exits are measured with 'Executable' (the cost to buy back). With wide bid/ask the bot waits; the stop doesn't trigger on a stray quote |
| PMCC and diagonals | Rolls go in a single order. If IBKR rejects a roll, the position stays as it was and it's retried the next day |
| Wheel | Shares from an assignment appear the next day; the covered call is sold on the check after they appear |
| SPX, NDX and XSP indexes | They settle in cash at expiration: no shares and no early assignment |
Dashboard: account value, open P&L, what was closed today (like IBKR's «Realized P&L», with the total since the first trade as a reference), active rules, open positions and today's closed ones. The Results tab shows the history: by day (with the cumulative) and by rule, for today, the week, the month or all. With the 'Close now' button you close the selected position (it asks for confirmation; the order starts at mid, moves toward natural and ends at market); that rule won't open again that day. If you close a position from TWS, the bot treats it as closed ('closed outside the bot') and sends no share orders. It updates every few seconds and instantly with each opening, close or roll; a rule you save or activate is picked up by the bot right away.
| Column | What it is |
|---|---|
| Result | What the trade made at the execution prices, before commissions. Open ones are valued at each leg's mid price. IBKR shows its «Unrealized P&L» with its own reference (mark) price and with commissions added to the cost: that's why it can differ by a few dollars; compare with the Net column |
| Commissions | As reported by IBKR for that position's orders (opening, close and rolls). They arrive a few seconds after each execution: until then it shows «-» |
| Net | Result minus commissions |
| Open price | The net per unit at opening: positive = debit (you paid), negative = credit (you received) |
| Amount | What you paid (debit) or received (credit) at opening, for all units |
| % P&L | The result over what was paid or received: it's the number the bot compares with your profit and loss % |
| TP / SL | At how many dollars of result it closes for profit and for loss, per the rule's % |
| Trailing | '-' no trailing; 'waits for +100%' until it reaches the activate %; 'ON +72% → +55%' active: the highest profit it reached → the profit % where it closes |
| DTE | Days to expiration of the leg that expires first (0 = expires today) |
Results (since 0.6.4): at the top, how many closed, won and lost trades the period has. By rule: closed, won, lost, % won, losses by stop and by time/expiration, average win and loss in %, return % (net over what was paid or received) and net, sorted by net: so you see which rule earns most and which loses. The «Losses of the period» table shows each losing trade with open, close, duration, reason, % P&L, the most in favor and against while it was open and the underlying at entry and exit; double-click for the detail with the legs and the signal that opened it. «Export closed (CSV)» saves all of the period's trades to analyze them.
Rules: New rule, Edit, Duplicate, Activate / deactivate and Delete. When you select a rule you see it in words below and, if it has errors, which ones. Clicking the Name, Underlying or Status header sorts the list (again, reversed), and 'Hide inactive' hides inactive rules (those that still have open positions stay visible). The order and the checkbox are saved.
| Action | What happens |
|---|---|
| Deactivate | Opens no new positions, but the open ones keep being managed (exits and rolls) until they close |
| Edit with open positions | You can change entry, exit, rolls and capital; not the legs, until they close |
| Delete | Only a rule with no open positions |
| Pause (Settings) | Doesn't open, close or manage; only checks the account and reports. Positions stay as they are |
Log: everything the bot does (orders sent, repriced, filled, rejected, openings, closes, rolls, assignments, expirations, pauses and errors). It's also kept in %APPDATA%\ZeroTouchAutopilot\eventos.log and sent to ZeroTouch so we can see what happened if there's a problem.
The bot only manages the positions and orders it opened. Your own options, shares and orders are left alone.
If the account has more contracts of the same kind than the bot's, the extra ones are ignored and you're alerted once.
On an assignment of one of the bot's legs, only the change in shares that assignment produced is flattened, not the shares you already had.
On start, the bot cancels only its own pending orders.
While the computer is off, offline or the program is closed, the bot doesn't manage anything: positions stay at IBKR as they are, with no exits or stops.
When it's back, it reconnects, checks the account and continues. If an opening filled while the program was closed, it adopts it as a position; if something closed or expired in the meantime, it records it.
The ZeroTouch panel keeps the periods without signal during market hours: that shows whether the program was running.
If the program wasn't running at the close on the day legs expired (since 0.6.7): to know whether they expired in the money it uses that day's closing price from IBKR; if IBKR doesn't provide it, it goes by the account's shares (no new shares means they expired out of the money). It never uses the next day's price. If it asks you for a decision about shares, «apply» only works with the shares that actually changed in the account: it never buys or sells shares that aren't there.
| Email alert | Who sends it | When |
|---|---|---|
| No connection to IBKR: the bot cannot manage your positions | The program (0.6.7) | More than 5 minutes without IB Gateway / TWS, or with IB Gateway disconnected from IBKR's servers, with open positions |
| URGENT: positions expire today and the bot has no connection | The program (0.6.7) | From 3:15 pm if it is still disconnected and legs expire that day |
| The program did not check for X minutes / was not running at the close | The program (0.6.7) | When it comes back after 5 minutes or more without running (computer asleep), or the next day if it wasn't running at the close with positions |
| Your Autopilot is not responding and has open positions | The ZeroTouch server | 15 minutes without signals during market hours with open positions (computer off or asleep, no internet): the program can't alert, the server does |
| URGENT: your Autopilot is still not responding | The ZeroTouch server | From 3:15 pm if there are still no signals |
Autopilot is licensed by modules: options and stocks (long). Each module sets how many rules of its kind you can have active at once: 1, up to 5 or unlimited. The counter is on the Rules tab and on the Dashboard ('Active rules: options 3 of 5 · stocks 1 of 1').
With two modules, the most expensive one is full price and the other gets the additional-module discount. The discount you had when you signed up stays; discounts do not stack.
From My account you add a module or more rules (you pay the part for the days left in the period and it activates on payment) or remove a module or lower the rules (applies from the next renewal; on the annual plan, not mid-year). The program picks up the change on its own, without reinstalling.
The free trial lasts 30 days and is requested for the IBKR paper account (the one starting with DU) or for the real account. If you requested it for paper and set a real account (U…), the program doesn't start and explains how to continue: log in to IB Gateway with Paper Trading, enter the DU… account and port 4002 (or request the trial for the real account). Each IBKR account gets one trial. To continue after the 30 days, get a license with the same email and keep using the same rules.
If the license expires (after the grace period), the bot stays paused until payment is recorded.
| What you see in the Log | What it means | What to do |
|---|---|---|
| TRAILING … active / new high / the rule changed | The option trailing activated, reached a new high or took the rule's new values | Nothing: it's informational. The closing point is in the line and in the Trailing column |
| This is a TRIAL version… | The code is a trial and the account set is a real one (U…) | Log in to IB Gateway with Paper Trading, enter the DU… account and port 4002; for the real account, get a license |
| NO CONTRACT | No contract meets the rule today (expiration, delta or quote) | Check days and delta in the preview; retried on the next day |
| NO WING | The wing strike isn't quoted, not even within the extra strikes | Raise 'extra strikes' or use another width |
| NO BID/ASK | Some leg has no bid/ask at that moment | Nothing: retried on the next enabled day |
| NO CAPITAL | Not even one unit fits with the chosen % of capital | Raise the % or use fixed contracts |
| NOT FILLED | The opening didn't fill even at the natural price | Nothing: retried on the next enabled day |
| Order rejected by IBKR | IBKR didn't accept the order (margin, permissions, data) | Read the reason and check it at IBKR |
| ROLL NOT DONE | The roll couldn't be done | The position stays as it was; retried tomorrow |
| More active rules than your license allows | You have more active rules than your plan allows | Deactivate one or upgrade the plan |
| SHARES … without an assignment of the bot's | Shares that aren't the bot's changed | Nothing: the bot doesn't touch them |
| The bot is waiting for your decision: … | The account's shares changed differently from what the bot's legs explain | Check at IBKR. If the account has no new shares, choose «leave it»; «apply» never trades shares that aren't there |
| Rule with crossed call/put: does not open | The name or the signal doesn't match the leg type | Edit the rule and fix the Type in step 2 |
| No connection to IBKR / URGENT | The bot can't trade and there are open positions | Check IB Gateway / TWS and internet, or close manually at IBKR |
| The program did not check for X minutes | The computer went to sleep, the internet dropped or IB Gateway froze | Check the positions; set Windows so it never sleeps |
| Prices: … no complete price from IB (yellow on the panel) | IBKR isn't sending bid and ask for that contract. Most common cause: the IBKR phone app, TWS or the Portal open with the bot's same username (while another session is open, IBKR cuts the bot's prices) | Close that other session (Log out). If it lasts 2 minutes, the bot reconnects to IB on its own (like Stop / Start) |
| Data: IBKR did not answer the … bars | IBKR didn't send that ticker's bars within 15 seconds | Nothing: that ticker's rules wait and they are requested again in 1 minute; the rest keeps going. If it repeats, check there's no other session open with the same username |
No. It executes the rules you define; the outcome depends on the strategy, the parameters and the market.
Check the Log: it gives the reason (day or time outside the rule, maximum open positions until the 'Open until' time, 'every N days', moving-average filter, no contract, no bid/ask, not filled or rejected by IBKR).
Yes: in step 5, 'Use an entry signal'. Pick a prebuilt signal or build your own; the rule opens the first time it's met within the time window. See «Entry signals».
0.50 is the strike closest to the price (ATM). For one just in the money, 0.55. You can also use '% of price' at 0.
Yes: entry, exit, rolls and capital. Not the legs, until the positions close. The bot picks up the changes on the next check, without restarting.
Yes. The bot only touches its own. Avoid manually trading the same contracts the bot has open.
IBKR exercises it automatically and shares appear the next day. With 'Close everything' the bot flattens them; with 'Only alert' they stay in the account. To keep it from getting there, set 'Close at time' in the exit.
In the 'When to close' step, enter a time in 'Close at time' (for example 15:45) and choose 'every day (no overnight)'. At that time the bot closes whatever is still open from that rule, and opens nothing new that day.
In the program's Log tab: 'Send log to support' for a problem or question, and 'Suggestion or bug' to tell us an idea or something the program did differently from what it says. It's sent with the program's log (account numbers are masked) and you follow it in My account, at zerotouchbots.com.