Skip to content

[ARCH] User-facing broker selector and trading-mode indicator #96

Description

@Ibrahim-3d

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:

  1. Pick which broker is active for live trading.
  2. See at a glance whether the app is in Paper or Live mode, and which broker is wired up.
  3. 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

  • User can pick Paper or Live mode and persist selection
  • User can pick active broker when Live, with per-broker connection status visible
  • Status bar visible on every screen, color-coded, click-through to settings
  • Binance testnet toggle works and routes orders to testnet.binance.vision
  • All order/balance/position call sites route through get_active_broker() or paper account, never directly
  • Audit log shows mode + broker change events with correlation IDs
  • Confirm modal blocks accidental Live activation
  • Switching mode mid-session drains in-flight orders cleanly

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions