Automatically trades Bitcoin via the Coinbase Advanced API.
- Uses Coinbase Advanced API market data + account data.
- Generates buy/sell signals from EMA trend + RSI momentum.
- Accounts for net fees by:
- Reading your Coinbase Advanced Trade
SPOTmaker/taker fee tier. - Previewing order commissions before execution.
- Requiring expected edge to clear fee + profit thresholds.
- Reading your Coinbase Advanced Trade
- Supports guarded commands for convert and short/close-position actions.
- Includes walk-forward backtest command for config evaluation.
- Supports optional auto-actions in loop mode (
auto_actions):- auto short open
- auto short close-position
- auto convert
- Writes graph-ready analytics to
tradebot_metrics.json:equity_curve: time series for realized/unrealized/net PnL.trades: normalized trade events with side, size, fees, and realized PnL.
- Profit is never guaranteed.
- Default mode is
paper(simulated trading only). - Live execution is blocked unless all are true:
config.mode = "live"- CLI uses
--execute-live - Environment variable
TRADEBOT_ENABLE_LIVE=true
- Max order USD cap.
- Max total position USD cap.
- Max daily buy USD cap.
- Max daily short-open USD cap.
- Minimum USD reserve.
- Daily realized loss stop.
- Optional daily realized profit lock (
daily_profit_target_usd). - Max trades per day.
- Cooldown between trades.
- Product allowlist.
- Convert pair allowlist.
- Shorting disabled by default and limited by notional + leverage caps.
tradebot/bot implementation.config.example.jsonsafe default settings.tradebot_state.jsonruntime state (created automatically).tradebot_metrics.jsonanalytics output for charting (created automatically).
Requirements:
- Python 3.11+.
- Node.js 18+ (used only for ES256 JWT signing helper).
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item config.example.json config.jsonSave your Coinbase API key JSON in a file named cdp_api_key.json in the project root folder.
Optional GUI dependencies:
pip install -r requirements-gui.txtGUI loop updates use Streamlit fragments, so only live runtime sections rerun.
Run one cycle (paper mode):
python -m tradebot --config config.json runRun continuously:
python -m tradebot --config config.json run --loopLaunch optional GUI dashboard:
python -m tradebot --config config.json guiGUI options:
--host(default127.0.0.1)--port(default8501)--no-browserto run headless
GUI notes:
Run One Cycle Nowin the GUI calls the samerun_cyclelogic as CLIrun.- GUI includes Start/Stop loop controls (websocket event-driven; no manual loop interval).
- When GUI loop is ON, a cycle is run when new websocket market data arrives.
- If websocket data is unavailable, GUI loop falls back to conservative polling.
- Backtest panel can include a synthetic scenario suite to test bull/bear/chop/volatility regimes.
- Live execution from GUI still requires:
mode = "live"in config- explicit GUI live checkbox + confirmation
TRADEBOT_ENABLE_LIVE=true
- GUI reads/writes the same runtime files:
tradebot_state.jsontradebot_metrics.json
Loop output behavior:
- In
--loopmode, TradeBot suppresses duplicate console lines. - A new line is printed only when cycle output changes (new signal/action-relevant information).
Auto actions in loop:
- Set
auto_actions.enable_auto_short,auto_actions.enable_auto_close_position, and/orauto_actions.enable_auto_converttotruein config. - Auto actions still obey live-execution safety gate and guardrails.
- Auto short-open and auto-convert also obey
guardrails.cooldown_seconds. - Auto checks are throttled by:
auto_actions.short_check_interval_secondsauto_actions.close_check_interval_secondsauto_actions.convert_check_interval_seconds
Real-time checks:
- Set
loop_secondsto1.0for one decision cycle per second. - Websocket market-data feed is enabled by default:
websocket.enable: truewebsocket.market_data_url: wss://advanced-trade-ws.coinbase.comwebsocket.channel: ticker(orticker_batch)websocket.stale_seconds: max age before REST fallbackwebsocket.ping_interval_seconds/websocket.ping_timeout_secondswebsocket.max_reconnect_seconds
price_refresh_secondscontrols cache/REST fallback behavior when websocket data is stale.- Keep
granularityatONE_MINUTE(strategy candles are still 1-minute bars). - Use:
candles_refresh_secondsto control how often candle history refreshes (example:10).fees_refresh_secondsto control how often fee tier refreshes (example:300).
- Spot execution mode:
execution.prefer_maker_orders: trueenables post-only maker orders for spot BUY/SELL.execution.maker_price_offset_bpscontrols post-only limit offset.execution.maker_max_order_wait_secondscontrols stale-pending warning threshold.execution.max_spread_bpsblocks spot entries/exits when bid/ask spread is too wide.- In maker mode, bot output may remain
HOLDwhile pending fills are being reconciled.
- Enable sub-minute signal overlay:
strategy.enable_subminute_signals: truestrategy.subminute_window_seconds(recent tick window, e.g.90)strategy.subminute_min_samples(minimum ticks needed)strategy.subminute_min_signal_strength_bps(micro-signal threshold)
- Regime adaptation (optional but enabled by default):
strategy.enable_regime_adaptationstrategy.regime_volatility_lookbackstrategy.low_volatility_bps/strategy.high_volatility_bpsstrategy.trend_regime_threshold_bpsstrategy.low_vol_threshold_multiplierstrategy.trend_threshold_multiplierstrategy.choppy_threshold_multiplierstrategy.high_vol_threshold_multiplier
Show status:
python -m tradebot --config config.json statusConvert (preview only unless live + --execute-live):
python -m tradebot --config config.json convert --from-currency USD --to-currency USDC --amount 25Short open (guarded, derivative products only):
python -m tradebot --config config.json short-open --product-id BTC-PERP --base-size 0.001 --leverage 1Close derivative position:
python -m tradebot --config config.json close-position --product-id BTC-PERPRun walk-forward backtest:
python -m tradebot --config config.json backtest --lookback-candles 3000 --train-candles 600 --test-candles 180 --step-candles 90Run backtest with synthetic scenario suite:
python -m tradebot --config config.json backtest --lookback-candles 3000 --train-candles 600 --test-candles 180 --step-candles 90 --include-scenarios --scenario-length 1800Run synthetic scenarios only (skip historical download):
python -m tradebot --config config.json backtest --scenarios-only --scenario-length 1800 --train-candles 600 --test-candles 180 --step-candles 90Scenario suite includes deterministic market regimes:
bull_trend_pullbacksbear_trend_bouncessideways_chopbreakout_then_reversalvolatility_spike_regime
tradebot_metrics.json has two chart-friendly arrays:
equity_curve: one point per cycle (ts,price_usd,realized_pnl_usd,unrealized_pnl_usd,net_profit_usd).trades: one point per executed trade (side,price_usd,base_size,quote_notional_usd,fee_usd,realized_pnl_usd).
Guardrail note:
- Set
guardrails.max_trades_per_dayto0to disable trade-count limiting. - Set
guardrails.daily_profit_target_usdto a positive number to stop opening new buy/short/auto-convert risk once realized daily PnL reaches that target.
Runtime output note:
- Each
runcycle now includes:price_source(websocket,cache,rest,cache_fallback)signal_source(candleorsubminute)spread_bps,max_spread_bpssignal_threshold_bps,signal_volatility_bps,signal_regimecandle_signal,candle_signal_reasoncandle_threshold_bps,candle_volatility_bps,candle_regimesubminute_signal,subminute_signal_reason,subminute_ticks(when sub-minute is enabled)subminute_threshold_bps,subminute_volatility_bps,subminute_regime(when sub-minute is enabled)pending_order_id,pending_order_status,pending_order_side(when maker order is awaiting fill)daily_buy_used_usddaily_buy_limit_usddaily_buy_remaining_usddaily_short_open_used_usddaily_short_open_limit_usddaily_short_open_remaining_usdso you can monitor progress toward the daily spend cap in real time.
- Spot execution quality checks may return HOLD reasons:
spread too wide for entry (...)spread too wide for exit (...)
statusnow includes websocket health/connection details underwebsocket.- Terminal output is colorized by default (
use_color_output: truein config). Disable withuse_color_output: falseor environment variableNO_COLOR=1. Additional color cues:- signal/action fields and signal source (
candlevssubminute) - trend/RSI/edge and fee fields
- auto-action reason fields (
auto_close_reason,auto_short_reason,auto_convert_reason) Daily spend colors: daily_buy_remaining_usd: green when available, yellow when low, red at0.daily_buy_used_usd: yellow as it accumulates, red when cap is reached.daily_short_open_remaining_usd: green/yellow/red by remaining short-open budget.daily_short_open_used_usd: yellow while opening shorts, red at cap.
- signal/action fields and signal source (
- Keep
modeaspaperuntil logs look stable for multiple days. - Use very low limits first (
max_order_usd,max_position_usd,max_daily_loss_usd). - Only then set:
$env:TRADEBOT_ENABLE_LIVE="true"and use run --execute-live.
This software is intended for educational use only and does not constitute financial advice. The author assumes no responsibility for any financial gains or losses resulting from its use.