Skip to main content

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), then bearish macro, bearish link, bearish members, bearish fx for the group-level KPIs.
  • TA-Lib: the ta-lib wheel 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.95.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bullishpy 0.95.0
File Size Uploaded Provenance Actions
bullishpy-0.95.0.tar.gz 10.6 MB Without provenance Details for bullishpy-0.95.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bullishpy 0.95.0
File Interpreter ABI Platform Actions
bullishpy-0.95.0-py3-none-any.whl Python 3 none any Details for bullishpy-0.95.0-py3-none-any.whl

Total release size: 10.8 MB

Release files / bullishpy-0.95.0.tar.gz

Download URL bullishpy-0.95.0.tar.gz
Size 10.6 MB
Tags Source
SHA-256 checksum
How to use checksums
ae721ce3b5c8380ee59a11e325db848fcc81fd993b9c80ed3f39a9d4d8b2ea5c
BLAKE2b-256 checksum
How to use checksums
04c4379825f424a1983e3dd532476a18079a779265ad5b9f115380b0b1656cf0
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.95.0-py3-none-any.whl

Download URL bullishpy-0.95.0-py3-none-any.whl
Size 147.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1c5bb8112cb07b1fd241d58473577c39d98c831f7ae9e3c37a6bd2621e03398f
BLAKE2b-256 checksum
How to use checksums
762cdce49cb21b9fabc609674011a25128c98de4c0830adcd6865e8dc8e9a6ce
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.95.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.

Release history Release notifications | RSS feed

This release

0.95.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page