A local, keyboard-driven Bloomberg-style market terminal for your shell.
Project description
bbterm
A local, keyboard-driven market terminal — a Bloomberg-style TUI you run in your own terminal. Price charts, a watchlist, statistics, and SEC EDGAR fundamentals and filings, all backed by a local cache so it's fast, works offline once data is fetched, and costs almost nothing to run.
Built with Textual (TUI), plotext (terminal charts), DuckDB (local cache), and Databento for market data.
Features
- Hybrid command bar — press
:to type a command. A bare ticker loads a symbol (AAPL); verbs run actions (ADD,DEL,GP,DES,FA,FIL,?). - Candlestick + volume chart (
GP), withcto toggle a line view and1–6for time ranges (1D / 5D / 1M / 6M / 1Y / 5Y). - Statistics panel (
DES) — last, 52-week high/low, 1M and YTD returns, average volume, and day range, all computed from cached price bars. - Fundamentals (
FA) — revenue, net income, EPS, assets, cash flow and more from SEC EDGAR, each with its fiscal year and year-over-year change. - Recent filings (
FIL) — the company's latest 10-K / 10-Q / 8-K filings with dates and links, from SEC EDGAR. - Persisted watchlist —
ADD/DELedit it and the change is saved. - Local cache — market bars and EDGAR data are cached in DuckDB; each paid record is bought once, and EDGAR data is reused for 24 hours.
Architecture
UI widgets never fetch data — they render what the DataService returns. The
service is an async, cache-through layer over a DuckDB store, fetching only the
date ranges it's missing. Data providers sit behind small Protocols:
- Databento — primary historical bars (when
DATABENTO_API_KEYis set). - yfinance — free fallback for bars/quotes when no Databento key is present.
- SEC EDGAR — fundamentals and filings (free, official, no API key), accessed with the standard library only.
All parsing and number-crunching lives in pure, unit-tested modules
(commands.py, data/stats.py, data/fundamentals.py); widgets stay dumb.
Requirements
- Python ≥ 3.11
- A Databento API key is optional — without it, bbterm runs on the free yfinance fallback. EDGAR needs no key.
Install
From PyPI (recommended):
pipx install bbterm-tui # or: pip install bbterm-tui
The installed command and import name are bbterm (only the PyPI package is
named bbterm-tui). To enable the Databento provider: pipx install "bbterm-tui[databento]".
To install the latest unreleased main instead, via
pipx:
pipx install git+https://github.com/sgjlee0520/bbterm.git
The core install runs on the free yfinance + SEC EDGAR path. To enable the
Databento provider (requires a DATABENTO_API_KEY):
pipx install "git+https://github.com/sgjlee0520/bbterm.git#egg=bbterm[databento]"
Contributors (editable, from a clone):
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]" # add ,databento to work on the Databento provider
Configure
Settings come from environment variables or a .env file in the project root:
| Variable | Default | Purpose |
|---|---|---|
DATABENTO_API_KEY |
(unset) | Enables Databento as the bar provider |
BBTERM_DB_PATH |
data/market.duckdb |
Local cache database path |
BBTERM_COST_CAP_USD |
1.0 |
Per-request Databento cost ceiling |
BBTERM_DATASET |
EQUS.MINI |
Databento dataset |
Run
bbterm-sync # optional: pre-cache recent daily bars for your watchlist
bbterm # launch the terminal
Keys & commands
| Input | Action |
|---|---|
: |
Focus the command bar (Esc / Enter to leave) |
<ticker> |
Load a symbol |
ADD <sym> / DEL <sym> |
Edit the watchlist (saved) |
GP / DES |
Chart / statistics |
FA / FIL |
Fundamentals / recent SEC filings |
c |
Toggle candlestick / line chart |
1–6 |
Time range (1D / 5D / 1M / 6M / 1Y / 5Y) |
r |
Refresh · q Quit · ? Help |
A beginner-friendly guide is in docs/manual/bbterm-guide.tex
(build the PDF with pdflatex bbterm-guide.tex).
Tests
python -m pytest
Tests make no network calls and spend no Databento credits; live API access is
exercised only by the manual scripts under scripts/.
Notes
- yfinance is an unofficial data source intended here as a free development fallback only.
- SEC EDGAR requests send a declared
User-Agentwith a contact address, as the SEC requires.
License
bbterm is licensed under the GNU Affero General Public License v3.0 or later
(AGPL-3.0-or-later). See LICENSE. Copyright © 2026 sgjlee0520.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bbterm_tui-0.1.1.tar.gz.
File metadata
- Download URL: bbterm_tui-0.1.1.tar.gz
- Upload date:
- Size: 42.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15f42205eeaccecd735cbde73a0624d578cf812ca6378473d3e238020f968fab
|
|
| MD5 |
a0c71905215d0745d23519dab857b0f3
|
|
| BLAKE2b-256 |
e07843ad7aa4d818a0d126a76729460df1d981b1e890b7513d2a151a06d66048
|
Provenance
The following attestation bundles were made for bbterm_tui-0.1.1.tar.gz:
Publisher:
release.yml on sgjlee0520/bbterm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bbterm_tui-0.1.1.tar.gz -
Subject digest:
15f42205eeaccecd735cbde73a0624d578cf812ca6378473d3e238020f968fab - Sigstore transparency entry: 1882014932
- Sigstore integration time:
-
Permalink:
sgjlee0520/bbterm@543f9771dd72d6f3ff9ef27347d9b8d1dbd707c1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/sgjlee0520
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@543f9771dd72d6f3ff9ef27347d9b8d1dbd707c1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bbterm_tui-0.1.1-py3-none-any.whl.
File metadata
- Download URL: bbterm_tui-0.1.1-py3-none-any.whl
- Upload date:
- Size: 37.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36a7525a1bc135b25121944225546e0c0eed4d1cc4730bb14e439a4828ce71a8
|
|
| MD5 |
cc4116c1f0beeaefc555e56adad254f1
|
|
| BLAKE2b-256 |
53123f05aded6e3aae871f4588ee02370401e9413f76a6df16701fee65b7b06d
|
Provenance
The following attestation bundles were made for bbterm_tui-0.1.1-py3-none-any.whl:
Publisher:
release.yml on sgjlee0520/bbterm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bbterm_tui-0.1.1-py3-none-any.whl -
Subject digest:
36a7525a1bc135b25121944225546e0c0eed4d1cc4730bb14e439a4828ce71a8 - Sigstore transparency entry: 1882015275
- Sigstore integration time:
-
Permalink:
sgjlee0520/bbterm@543f9771dd72d6f3ff9ef27347d9b8d1dbd707c1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/sgjlee0520
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@543f9771dd72d6f3ff9ef27347d9b8d1dbd707c1 -
Trigger Event:
push
-
Statement type: