Bullish
Bullish turns a bearish database into decision KPIs and serves them to an LLM client over the Model Context Protocol: which sector, country or ETF is attractive, which stocks fit a preset such as quality on sale, whether a stock is fundamentally sound and only temporarily oversold, and whether the data is good enough to judge. Technical analysis (TA-Lib indicators and signals) is one block of those KPIs.
Nothing here is a forecast: every KPI carries an evidence tier (A academic, B practitioner, C heuristic) and every answer the date of the run it is based on.
Prerequisites
- A bearish database:
bearish run ./bear.db Belgium(prices, statements, analyst and ownership data), thenbearish macro,bearish link,bearish members,bearish fxfor the group-level KPIs. - TA-Lib: the
ta-libwheel bundles the C library on supported platforms; otherwise see the TA-Lib installation guide.
pip install bullishpy
What is computed
| Level | KPIs | Composite |
|---|---|---|
| Market regime (per region) | trend, breadth, volatility, credit spreads, curve, leading indicators, growth / inflation quadrant, factor leadership | rule-based risk-on / neutral / risk-off label |
| Sector and industry | cap-weighted relative strength, RRG quadrant, breadth, median growth and acceleration, revision ratio, beat rate, valuation vs history, 13F and insider flows, commodity tailwind | sector_score, industry_score |
| Country | the same market block plus CLI, PMI, forecasts, inflation and policy trend, real yields, BIS credit gap, debt, current account, confidence, uncertainty, FX vs base currency, terms of trade | country_score |
| ETF | expense ratio, AUM and flows, dollar volume, tracking difference / error vs the best-correlated index, premium to NAV, holdings concentration, risk-adjusted momentum, age | etf_vehicle_score; etf_score = 0.5 exposure attractiveness + 0.3 vehicle + 0.2 momentum |
| Equity | technical (every TA-Lib indicator and signal of bullish.analysis.indicators, dated signals as trading days since they last fired), momentum and risk, growth and acceleration, quality (ROIC, accruals, Piotroski F, Mohanram G, Altman Z, dilution), valuation vs peers and own history, revisions and surprises, 13F / insider / 13D / short interest / 8-K items, macro exposure |
presets emerging_leader, quality_compounder, value_with_catalyst, turnaround, dividend_quality, quality_on_sale |
| Stock verdict | fundamental checklist, oversold signals, drawdown nature (company-specific / sector / market), temporary-vs-structural evidence, recovery evidence | label: quality on sale, falling knife, sound not cheap, oversold unclear, avoid |
| Data coverage | statements, prices, expectations, ownership and reference per symbol | grade A / B / C / insufficient with the bearish command that fills the gap |
KPIs are ranked 0-100 inside their peer group (winsorised, direction-aware),
blocks average their KPIs and composites average their blocks; weights are
declared in bullish/scoring/presets.py and every block carries its rationale.
Values are stored point-in-time in the long kpi table and the score table,
so as_of questions are answered with what was known then.
Running it
# compute every KPI, score and grade for today (or a past date) and store them
bullish compute --db /path/to/bear.db [--as-of 2026-06-30] [--country USA --country DEU]
bullish compute --db /path/to/bear.db --symbol AAPL --symbol NVDA # a few names only
bullish compute --db /path/to/bear.db --profile # per-phase time and memory
# a monthly grid of past runs, then a rank backtest of a KPI or a preset
bullish history 2024-01-31 2026-09-30 --db /path/to/bear.db --step-months 1
bullish backtest mom_12_1 --db /path/to/bear.db --horizon-months 3
bullish backtest quality_on_sale --db /path/to/bear.db
# serve the MCP server (stdio for Claude Desktop / Claude Code, or streamable HTTP)
bullish mcp --db /path/to/bear.db
bullish mcp --db /path/to/bear.db --transport streamable-http --port 8765
Claude Desktop / Claude Code configuration:
{
"mcpServers": {
"bullish": {
"command": "uv",
"args": ["run", "bullish", "mcp", "--db", "/path/to/bear.db"]
}
}
}
Settings come from the environment or a .env file (BULLISH_DATABASE_PATH,
BULLISH_BASE_CURRENCY, BULLISH_PEER_GROUP, BULLISH_MIN_DOLLAR_VOLUME,
BULLISH_MIN_MARKET_CAP, BULLISH_ALLOW_SQL, ...), see bullish/config.py.
A run covers the equities that have at least BULLISH_MIN_PRICE_ROWS (default
60) price rows inside the lookback; everything else bearish knows is still
reachable through the coverage and scorecard tools. The per-symbol technical
signals run in BULLISH_WORKERS processes (default: all CPUs but one). Each
run stores its long kpi rows and one compressed wide frame (kpiwide), which
is what the MCP server reads, so a tool call costs milliseconds once warm.
bullish history loads the data once for the whole span and derives every
monthly run from it. docs/plans/2026-10-compute-performance.md has the
measurements behind these choices.
MCP tools
get_market_regime, rank_sectors, rank_industries, rank_countries,
rank_etfs, compare_etfs, screen_equities, explain_score,
get_equity_scorecard, assess_stock, get_kpi_series, get_smart_money,
get_technical_signals, get_filings, get_earnings_calendar, get_macro_snapshot,
get_commodity_snapshot, get_data_coverage, analyze_portfolio,
list_kpis, describe_kpi, list_composites, list_runs and, when
BULLISH_ALLOW_SQL=1, a read-only query. Resources expose the KPI
catalogue and the methodology of each composite; prompts cover a weekly
market review, a sector briefing, an ETF selection and a stock due diligence.
The plan behind this layer, with the literature it rests on, is in
docs/plans/2026-10-decision-kpis-and-mcp.md.
Development
Bullish uses uv for dependency management.
uv sync --all-groups # environment with the dev tools
uv run pytest # tests (tests/v2 run on a synthetic bearish database; test_benchmark bounds a 500-symbol run)
uv run nox -s linting # black, mypy (strict), ruff
The repository layout:
| Package | Role |
|---|---|
bullish.analysis |
TA-Lib indicator functions and the signal definitions |
bullish.data |
point-in-time loaders over the bearish tables |
bullish.kpi |
KPI registry, equity and group blocks, the run engine |
bullish.scoring |
percentile ranking, composites and presets, stock verdict, coverage grades, regime |
bullish.backtest |
rank information coefficient across stored runs |
bullish.database |
bullish's tables (kpi, kpiwide, score, kpirun) and the migration bridge with bearish |
bullish.mcp |
the MCP server and its service layer |
What Bullish is not
Not a trading platform and not real-time: it is a research layer for decisions over days to months, on data you own locally.
Metadata
Release files for bullishpy 0.96.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| bullishpy-0.96.0.tar.gz | 10.6 MB | Without provenance | Details for bullishpy-0.96.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| bullishpy-0.96.0-py3-none-any.whl | Python 3 | none | any | Details for bullishpy-0.96.0-py3-none-any.whl |
Total release size: 10.8 MB
Release files / bullishpy-0.96.0.tar.gz
| Download URL | bullishpy-0.96.0.tar.gz |
|---|---|
| Size | 10.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
14b562b6888d42e4d04cdec0537f6dde42dc4e786ba5717ccea77d09b1d243bc
|
|
BLAKE2b-256 checksum How to use checksums |
f54a128a4e19d87594148741d1518eb641a3baf442d9aea09ced9ae330442e8b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / bullishpy-0.96.0-py3-none-any.whl
| Download URL | bullishpy-0.96.0-py3-none-any.whl |
|---|---|
| Size | 147.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e5ab11490b958ff1781317f6db0134522c847ca22f7d9b79428747afe8913929
|
|
BLAKE2b-256 checksum How to use checksums |
7d6cfd4e20bcdd32e1d811ebca17888fe14dc45a7464b3fa2ac2b1dce1fb2991
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for bullishpy 0.96.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.