Horizon includes a real-time TUI (Terminal User Interface) dashboard built with Textual. It displays P&L, positions, orders, risk status, fills, and feeds in a 2x3 grid layout.
Enable the Dashboard
hz.run(dashboard=True, ...)
Or from the CLI:
python -m horizon run strategy.py --dashboard
Panels
The dashboard displays 7 panels in a 2x4 grid:
| Panel | Content |
|---|
| P&L | Realized, unrealized, total, and daily P&L with equity sparkline |
| Positions | Market, side, size, entry price, P&L color-coded (up to 10) |
| Orders | Open orders with side, price, size, market (up to 10) |
| Risk | Position count, order count, kill switch status, uptime |
| Fills | Recent fills with side, size, price (last 10) |
| Feeds | Feed names, bid/ask spread, staleness indicator |
| Alerts | Recent alerts (stale feeds, lifecycle events, state changes) |
Keybindings
| Key | Action |
|---|
q | Quit the strategy |
k | Toggle kill switch on/off |
p | Pause/Resume strategy execution |
How It Works
The dashboard runs the strategy loop inside the Textual app’s timer:
- A
set_interval(interval) timer fires each cycle
- Each tick: poll fills → update P&L → run pipeline → process results → update panels
- Positions are snapshotted to the database every 50 ticks
- All 6 panels are refreshed after each tick
The dashboard uses the same _build_context(), _run_pipeline(), and _process_result() functions as the console mode. Same strategy logic, different display.
The dashboard requires textual>=0.40. If not installed, Horizon falls back to console mode with a warning message.
Dashboard vs Console Mode
| Feature | Console | Dashboard |
|---|
| Strategy execution | Same | Same |
| Status output | Every 10 cycles to stdout | Real-time panels |
| Kill switch | Not accessible | Press k to toggle |
| Pause/Resume | Not available | Press p to toggle |
| Quit | Ctrl+C | q or Ctrl+C |
| Feed display | Logged at debug level | Live panel with staleness |
| Alerts | Logged to console | Dedicated alerts panel |