Context
The codebase supports multiple brokers via pt_exchange_abstraction.py and ExchangeFactory.register_exchange() (Robinhood, Binance, Kraken, KuCoin, plus ccxt-backed exchanges). We are not replacing Robinhood; we are giving users the ability to pick the broker they already use.
What's missing is a clear user-facing mechanism to:
- Pick which broker is active for live trading.
- See at a glance whether the app is in Paper or Live mode, and which broker is wired up.
- Persist that selection across restarts.
This mirrors the existing paper-mode visibility pattern but extends it to broker choice.
Goal
A dedicated Trading Mode settings panel plus a always-visible status indicator. No order, balance fetch, or position call may bypass the active-broker selector.
Scope
Settings panel (in pt_settings_manager.py and a new Settings tab section)
- Trading Mode radio group:
Paper Trading (default) | Live Trading
- Active Broker radio group (enabled only when Live):
Robinhood | Binance | Kraken | KuCoin
- Each broker row shows: connection status (
Connected as: ****<last 4> / Not configured)
- Each broker row has a
Test connection button
- Binance row adds a
Testnet toggle (uses testnet.binance.vision base URL)
- Confirm switch to Live modal: explicit
Yes, I understand real money is at risk checkbox before activating Live mode
Persistent settings keys (new)
trading.mode enum: paper | live (default paper)
trading.active_broker enum: robinhood | binance | kraken | kucoin | null (null = paper only)
trading.binance_testnet bool (default true when first enabling Binance)
Always-visible status bar widget (pt_hub.py)
A new widget in the main window header, distinct colors:
[PAPER] green background when paper
[LIVE: Binance (testnet)] amber background when live + testnet
[LIVE: Binance] red background when live + real money
[LIVE: Robinhood] red background when live + Robinhood
Clicking the widget opens the Trading Mode settings panel.
Backend routing
- Add
get_active_broker() -> AbstractExchange to pt_settings_manager.py (or a thin pt_broker_router.py). Looks up persisted broker, instantiates via ExchangeFactory, returns it.
- Audit and update every order/balance/position call site in:
pt_trader.py
order_execution_engine.py
dca_automation.py
advanced_order_automation.py
conditional_order_logic.py
pt_paper_trading.py (paper mode shortcut)
- Paper mode: route to
PaperTradingAccount. Live mode: route to get_active_broker(). Never bypass.
Tests
- Settings round-trip (encrypt/decrypt mode + active broker)
get_active_broker() returns correct concrete class
- Switching mid-session does not lose in-flight orders (drain queue before swap)
- UI test: status-bar color/text matches persisted state
Security/audit
- Log every Trading Mode change via
pt_security_logger.log_config_change() with correlation ID
- Log every Active Broker change with
correlation_context() so audit trail links the switch to subsequent orders
Out of scope
Acceptance criteria
Why this blocks Binance live
PR #92 implements the Binance REST surface, but until this issue lands there is no way for a user to actually choose Binance as their broker without code changes. Merging Binance live without the selector risks orders going to the wrong venue.
Related
Context
The codebase supports multiple brokers via
pt_exchange_abstraction.pyandExchangeFactory.register_exchange()(Robinhood, Binance, Kraken, KuCoin, plus ccxt-backed exchanges). We are not replacing Robinhood; we are giving users the ability to pick the broker they already use.What's missing is a clear user-facing mechanism to:
This mirrors the existing paper-mode visibility pattern but extends it to broker choice.
Goal
A dedicated Trading Mode settings panel plus a always-visible status indicator. No order, balance fetch, or position call may bypass the active-broker selector.
Scope
Settings panel (in
pt_settings_manager.pyand a new Settings tab section)Paper Trading(default) |Live TradingRobinhood|Binance|Kraken|KuCoinConnected as: ****<last 4>/Not configured)Test connectionbuttonTestnettoggle (usestestnet.binance.visionbase URL)Yes, I understand real money is at riskcheckbox before activating Live modePersistent settings keys (new)
trading.modeenum:paper|live(defaultpaper)trading.active_brokerenum:robinhood|binance|kraken|kucoin| null (null = paper only)trading.binance_testnetbool (defaulttruewhen first enabling Binance)Always-visible status bar widget (
pt_hub.py)A new widget in the main window header, distinct colors:
[PAPER]green background when paper[LIVE: Binance (testnet)]amber background when live + testnet[LIVE: Binance]red background when live + real money[LIVE: Robinhood]red background when live + RobinhoodClicking the widget opens the Trading Mode settings panel.
Backend routing
get_active_broker() -> AbstractExchangetopt_settings_manager.py(or a thinpt_broker_router.py). Looks up persisted broker, instantiates viaExchangeFactory, returns it.pt_trader.pyorder_execution_engine.pydca_automation.pyadvanced_order_automation.pyconditional_order_logic.pypt_paper_trading.py(paper mode shortcut)PaperTradingAccount. Live mode: route toget_active_broker(). Never bypass.Tests
get_active_broker()returns correct concrete classSecurity/audit
pt_security_logger.log_config_change()with correlation IDcorrelation_context()so audit trail links the switch to subsequent ordersOut of scope
Acceptance criteria
testnet.binance.visionget_active_broker()or paper account, never directlyWhy this blocks Binance live
PR #92 implements the Binance REST surface, but until this issue lands there is no way for a user to actually choose Binance as their broker without code changes. Merging Binance live without the selector risks orders going to the wrong venue.
Related