Audits › Controls › Global circuit breaker
Brakes and stops · control 4 of 21
Global circuit breaker: does your trading bot have it?
Is there a kill switch that stops the whole bot after a daily loss, a drawdown, or a number of consecutive failures?
Why it matters
Without it, a streak of errors empties the account while the user sleeps. A 3Commas customer described grid bots losing about 10,000 USD overnight before positions could be closed by hand.
How to check it in the code
- Search for breaker, kill, halt, max_daily_loss, max_drawdown, consecutive.
- Confirm the breaker is checked before every order, not only inside one strategy.
- Confirm that tripping it also cancels open orders or at least stops new ones.
This is what the audit does for every bot in the list, on public code, without installing or running anything. Verdict values: present, partial, absent, not applicable, not verified. See the method.
Results across audited bots
Across 10 audited bots: 4 present, 3 partial, 3 absent, 0 not applicable, 0 not verified.
| Bot | Verdict | Evidence | Note |
|---|---|---|---|
| HKUDS/Vibe-Trading | Partial | agent/src/live/halt.py: global/per-broker filesystem sentinel HALT, checked via halt_flag_set() before every order (fail-closed). GET /search/code?q=drawdown+repo:HKUDS/Vibe-Trading and q=max_daily_loss+repo:HKUDS/Vibe-Trading both returned total_count:0 | The kill switch is MANUAL only (tripped by CLI/frontend/file touch via trip_halt(by=...)). No automatic trigger on daily loss, drawdown, or consecutive failures was found. |
| hummingbot/hummingbot | Partial | hummingbot/core/utils/kill_switch.py, class ActiveKillSwitch.check_profitability_loop() | Stops the whole bot (trading_core.shutdown()) once profitability crosses a configured +/- threshold; it is opt-in (PassThroughKillSwitch is a no-op default) and based on % profitability, not on drawdown or a count of consecutive failed orders. |
| Drakkar-Software/OctoBot | Absent | GitHub code search (GET /search/code) for 'circuit_breaker', 'daily_loss', 'max_drawdown', 'kill_switch' scoped to repo:Drakkar-Software/OctoBot returned 0 real matches (2026-09-17). | No global loss-based or consecutive-failure-based kill switch was found anywhere in the codebase under any of the common names. |
| freqtrade/freqtrade | Present | freqtrade/plugins/protections/{iprotection.py, cooldown_period.py, max_drawdown_protection.py, stoploss_guard.py, low_profit_pairs.py} at commit 3774521e7028fa666770e7c7a8da323af5c4cefa (contents API listing, 2026-09-17) | Opt-in Protections system (must be added to strategy.protections). max_drawdown_protection.py stops new entries after account drawdown; stoploss_guard.py stops after N consecutive stop-losses. It blocks NEW entries only -- it does not force-close already open positions. |
| jesse-ai/jesse | Absent | jesse/config.py (searched full file: no daily-loss, drawdown or consecutive-failure threshold key) + jesse/services/failure.py (the only global stop is register_custom_exception_handler / terminate_session, triggered solely by an uncaught exception/crash, not by a loss or drawdown metric) | No proactive P&L-based or failure-count-based freeze exists in the audited code; only a crash-triggered hard stop. |
| chrisleekr/binance-trading-bot | Present | docs/concepts/notifiers.md (daily-loss-halt, loss-guard-halt rows); docs/operations/kill-switch.md ("automatic entry breakers" paragraph) | Daily-loss circuit breaker, loss-streak guard, and drawdown guard all trip automatically and pause new buys on their own; kill-switch.md explicitly states these are "a separate mechanism from the kill switch", i.e. automatic, not manual. |
| alsk1992/CloddsBot | Present | src/trading/safety.ts tripBreaker() halts trading on daily loss limit (default $500 or 5%) and max drawdown (default 20%); separate market-condition circuit breaker in src/execution/circuit-breaker.ts and src/risk/circuit-breaker.ts per docs/RISK_MANAGEMENT.md (volatility/liquidity/loss/consecutive-failures/spread trip conditions). | Two independent circuit breakers (result-based and market-feature-based) are both wired into the unified risk engine. |
| Lumiwealth/lumibot | Absent | GET /search/code?q=circuit_breaker+OR+kill_switch+OR+max_daily_loss+repo:Lumiwealth/lumibot -> total_count: 0 (2026-09-17). GET /search/code?q=drawdown+repo:Lumiwealth/lumibot -> 70 hits, dominated by docs/TEARSHEET_METRICS.md (a post-hoc backtest reporting metric, not a live trading halt). | |
| YizhiSong/FriesTrader | Present | risk_rules.json loss_limits: daily 5% / weekly 10% of net_deposits_usd; scripts/pnl_pct.py computes the breach; PHASE_B_TASK.md (commit 458413627, diff on pnl_pct call) explicitly fails safe: 'if the script fails to run or any of the calls above can't be determined cleanly, fail safe: treat as breached'. | Halts new entries/top-ups account-wide on breach, but does not force-close existing positions -- stop-loss/take-profit remain the only exit mechanism and are explicitly exempt from the halt (by design). |
| c9s/bbgo | Partial | pkg/risk/circuitbreaker/basic.go (MaximumConsecutiveLossTimes, MaximumTotalLoss, HaltDuration); pkg/risk/circuitbreaker/errorbreaker.go; pkg/risk/riskcontrol/circuit_break.go | Three well-built halt mechanisms exist (consecutive-loss/total-loss breaker, error-rate breaker, 24h PnL breaker), but each is opt-in and must be instantiated per strategy; there is no bot-wide default breaker. |
If your bot does not have it
The watchdog enforces daily loss, drawdown, position size and heartbeat limits from outside the bot, with a read-only key, whatever the bot's own code does.