Skip to main content

Safety

Guards designed to keep an off-script command from doing damage. All of these are state that lives in the CLI, not the exchange.

GuardScopePersistence
SimulationAll write-ops on every accountPersistent (per CLI install)
FatfingerSingle-order size cap, per symbolPersistent
BudgetCumulative notional cap on new exposureCap persistent; spend per-session
WhitelistSymbols that survive close longs/shorts/allPersistent

Simulation

Aliases: sim, dry-run.

simulation # show status
simulation on # enable
simulation off # disable
simulation status # same as bare form
sim on
dry-run off

When ON, every write-op (place / cancel / close / move / bump) short-circuits at simulationGate(ctx) before any exchange call. Reads (positions, orders, margin, etc.) are unaffected.

Persisted to ~/.tealstreet/simulation.json. Source: SimulationCommand.ts.

Use simulation when porting a new alias or recipe. Confirm the chain prints the right intent before you flip simulation off.


Fatfinger

A per-symbol cap on individual order size, in contracts. Checked just before placeOrder on:

  • buy, sell
  • scale, swarm
  • chase
  • twap

Reduce-only orders are skipped — closing a position cannot blow it up.

FormEffect
fatfingerList all configured limits
fatfinger <contracts>Set on focused symbol
fatfinger 0.5 BTCUSDTSet on named symbol
unfatfinger <symbol>Remove for one symbol
unfatfinger allRemove every limit

Persisted to ~/.tealstreet/fatfingers.json. Source: FatfingerCommand.ts, TradingBaseCommand.ts:enforceFatfinger.


Budget

An opt-in, off-by-default cumulative cap (in USD notional) on exposure-increasing orders placed this session. Where fatfinger caps a single order, budget caps the running total — useful for a hard ceiling on how much you can open in a sitting.

budget # show the cap and how much is spent
budget $5000 # set a $5000 cap (also: budget 5000)
budget off # disable (also: budget 0)
budget reset # zero the spent accumulator, keep the cap
FormEffect
budgetShow cap + session spend
budget $5000Set the cap (USD)
budget offDisable
budget resetReset the spent accumulator

The cap persists across sessions (~/.tealstreet/budget.json); the spent total is per-session and resets on restart, on budget reset, and whenever you change the cap. Each exposure-increasing order (buy/sell/scale/swarm) charges its USD notional against the total and is blocked once spent + order > cap. Reduce-only / close / cancel never count — the budget gates new exposure, not exits. Known limitation: twap / chase task-spawners are not yet budget-counted (their slices fire in a worker outside the command's state).

Persisted to ~/.tealstreet/budget.json. Source: BudgetCommand.ts, TradingBaseCommand.ts:enforceBudget.


Whitelist

Symbols you don't want a global "close all" to touch. Applies to:

  • close longs
  • close shorts
  • close allpos / close all

Per-symbol close calls (close BTCUSDT, close long) ignore the whitelist — the guard is only for the global variants.

FormEffect
whitelistList
whitelist BTCUSDTAdd (uppercased before store)
unwhitelist BTCUSDTRemove
unwhitelist allRemove every entry

Persisted to ~/.tealstreet/whitelist.json. Source: WhitelistCommand.ts.


Combining guards

These layer. Simulation short-circuits before fatfinger checks; fatfinger fires before the exchange call.

simulation on
buy 99999 BTCUSDT # blocked by simulation — no fatfinger needed

simulation off
fatfinger 0.5 BTCUSDT
buy $5000000 BTCUSDT # blocked by fatfinger

whitelist BTCUSDT
close longs # touches every long except BTCUSDT

Symbol resolution fails closed

buy / sell reject an explicit symbol token that doesn't resolve to a market on the connected exchange instead of silently routing the order to the focused symbol:

buy $100 XBTUSD # error: Unknown symbol "XBTUSD" (on an exchange with no XBTUSD)
buy $100 # OK — no symbol given, uses the focused symbol
buy $100 BTCUSDT # OK — explicit, resolvable symbol

This catches typos like trading the wrong contract on a multi-variant exchange (e.g. XBTUSD vs XBTUSDT). Omitting the symbol entirely still falls back to the focused symbol by design. Source: BaseBuySellCommand.ts.


Degraded-connection lock

When an account's private data stream goes stale (the connection was up and has lost its heartbeat), commands that open or increase exposure are blocked — your position/order snapshot can't be trusted, so firing new orders blindly is unsafe:

buy $100 # error: connection degraded — refusing to open exposure
scale buy $1000 into 10 # blocked
twap buy $500 into 5 over 30 # blocked (won't start the task)

buy $100 reduce # OK — reduce-only reduces risk
close BTCUSDT # OK
cancel # OK
nuke # OK

Risk-reducing actions (close, cancel, nuke, and any reduce-only order) stay allowed so a degraded connection can never trap you in a position you can't exit. The lock fails open — if the private stream was never up or the exchange doesn't report health, it doesn't block. Run health to see connection status. Source: BaseCommand.healthGate.