Skip to main content
Glama
wanxinwanxin

riskprism

by wanxinwanxin
README.md
# riskprism

**Decompose US equity portfolio risk into its factor spectrum.**

**Explorer:** https://risk-prism-production.up.railway.app ·
**Agent model card:** [/model.md](https://risk-prism-production.up.railway.app/model.md)

An open-source, Barra-style fundamental factor risk model built to be
**usable by AI agents out of the box**: a Python library, an MCP server, and
weekly-published model artifacts covering most liquid US common stocks.

- **9 style factors** (size, value, growth, momentum, beta, volatility,
  liquidity, quality, leverage — value, quality and leverage are
  multi-descriptor composites, volatility is beta-orthogonalized residual
  volatility) + **30 industries** (Fama-French scheme) + a market factor
- **Free, redistributable data chain**: fundamentals and SIC codes from SEC
  EDGAR (public domain), prices from pluggable providers
- **Hybrid distribution**: precomputed artifacts (exposures, factor
  covariance, specific risk) are published on a weekly schedule, *and* the
  full pipeline is open so anyone can reproduce or extend them

> **Disclaimer**: research software, provided as-is. Nothing here is
> investment advice.

## Hosted API (no key, no signup)

The live deployment serves a JSON API over the newest weekly build —
interactive docs at
[/api/docs](https://risk-prism-production.up.railway.app/api/docs):

```bash
curl -s -X POST https://risk-prism-production.up.railway.app/api/v1/portfolio-risk \
  -H 'content-type: application/json' \
  -d '{"weights": {"AAPL": 0.4, "MSFT": 0.4, "XOM": 0.2}}'
```

Endpoints: `GET /api/v1/meta` · `GET /api/v1/factors` ·
`GET /api/v1/assets/{ticker}` · `GET /api/v1/funds/{ticker}` (ETF
look-through) · `GET /api/v1/coverage?tickers=…` ·
`POST /api/v1/portfolio-risk` · `POST /api/v1/stress-test` ·
`GET /api/v1/registry` (catalog of published builds). Same surface
as the MCP server; self-host it with `pip install ".[api]" && riskprism-api`
(artifacts auto-download from the latest release at boot). Details in
[docs/API.md](docs/API.md).

## For AI agents (MCP)

Hosted — no install, serving the newest weekly build:

```json
{
  "mcpServers": {
    "riskprism": {
      "type": "http",
      "url": "https://risk-prism-production.up.railway.app/mcp"
    }
  }
}
```

Or local, from the installed package and downloaded artifacts:

```json
{
  "mcpServers": {
    "riskprism": {
      "command": "riskprism-mcp",
      "env": { "RISKPRISM_ARTIFACTS": "/path/to/artifacts" }
    }
  }
}
```

Tools exposed: `get_model_info`, `get_portfolio_risk`, `get_etf_risk`,
`get_factor_exposures`, `stress_test`, `check_coverage`,
`list_model_versions`. Weights are portfolio weights (shorts negative);
volatilities are annualized decimals.

ETFs and mutual funds work through holdings look-through: a fund ticker
resolves to its latest SEC N-PORT filing, and the risk math runs on the
constituents the model covers (docs/DECISIONS.md §17). When the model
covers less than half of a fund's holdings — bond funds, international
funds — no estimate is given, by policy.

## Get the latest model (no key, no signup)

```bash
pip install riskprism
python -c "from riskprism.registry import download_artifacts; download_artifacts()"
```

This resolves the newest `model-*` release and unpacks its artifacts
into `./artifacts` (any historical build downloads by tag the same way).

## For humans (Python)

```python
from riskprism import RiskModel

model = RiskModel.load("artifacts")
report = model.portfolio_risk({"AAPL": 0.4, "MSFT": 0.3, "XOM": 0.3})
print(report["total_vol"], report["factor_var_contributions"])

model.stress_test({"AAPL": 1.0}, {"market": -0.10, "momentum": -0.05})

# ETF look-through (fetches N-PORT holdings from SEC EDGAR):
# export RISKPRISM_EDGAR_UA="your-project (you@example.com)"
from riskprism import fund_risk, portfolio_risk_lookthrough

fund_risk(model, "IVV")                                   # one fund
portfolio_risk_lookthrough(model, {"VTI": 0.7, "AAPL": 0.3})  # mixed
```

## Build the model yourself

```bash
pip install -e ".[dev]"
export RISKPRISM_EDGAR_UA="your-project (you@example.com)"   # SEC fair-access policy
riskprism-build --max-names 3000 --out artifacts             # yahoo prices, no key needed
riskprism-build --prior artifacts_prev --out artifacts       # append new weeks to a prior build
riskprism-build --provider tiingo ...                        # licensed data, needs TIINGO_API_KEY
```

The weekly GitHub Action runs exactly this and publishes the artifact
directory; see `.github/workflows/build-model.yml`.

## The explorer

A zero-backend static site (served on Railway, re-rendered by each weekly
build) for exploring the model: cumulative factor returns, factor vol and
correlations, a client-side portfolio risk sandbox with stress-test
sliders, per-stock factor profiles, and a visual methodology walkthrough.
All math runs in the browser on the embedded artifacts.

Agents get a plain-markdown mirror of every build at **`/model.md`**
(indexed by `/llms.txt`): model card, factor definitions, correlations,
and the full coverage list — no DOM parsing required.

Render everything locally:

```bash
riskprism-site --artifacts artifacts --out site   # index.html + model.md + llms.txt
```

## Model summary

| Component | Choice |
|---|---|
| Horizon | Medium — weekly formation, daily estimation (annualized outputs) |
| Estimation | Daily cross-sectional WLS (√cap weights) against Friday-formed exposures, cap-weighted industry constraint |
| Factor covariance | EWMA on daily factor returns — vol half-life 84d, correlation 252d (~730 effective observations) — with Newey-West variance adjustment, correlation regularization, PSD repair, and a Volatility Regime Adjustment multiplier |
| Specific risk | EWMA residual vol (NW-adjusted) blended with a structural (characteristic-based) prior by history length, Bayesian-shrunk toward size-decile means (q=0.1), with its own VRA multiplier |
| Universe | Estimation: price ≥ $2, ADV ≥ $1M, 26w+ history · Coverage: everything alive ≥ $1, priors fill the gaps |
| History | Capture-forward: weekly builds append to the prior release; delistings imputed, survivorship bias decays out |
| Validation | Recomputed from full history every build: bias statistics, Mincer–Zarnowitz, realized-vol ratios — on market/style/industry/random baskets, six real factor ETFs, and portfolios optimized against the model itself |

Full methodology in [docs/METHODOLOGY.md](docs/METHODOLOGY.md); design
decisions and their rationale in [docs/DECISIONS.md](docs/DECISIONS.md).

## License

MIT for code. Published model artifacts are derived data built from SEC EDGAR
(public domain) and third-party price providers — see docs/DECISIONS.md for
the data-licensing discussion.

TDQS

A3.6/5.0

Scored across 7 tools

Disambiguation4/5

Most tools target distinct actions: check_coverage checks ticker coverage, get_factor_exposures returns per-asset exposures, get_portfolio_risk returns a full portfolio report, and stress_test applies factor shocks. However, get_model_info also reports asset coverage count, which slightly overlaps with check_coverage, and get_portfolio_risk duplicates some get_factor_exposures output. Descriptions clarify boundaries, so misselection is unlikely.

Naming Consistency5/5

All names use snake_case with a verb_noun pattern (check_coverage, get_factor_exposures, list_model_versions, etc.). stress_test is the only minor deviation from the get_* prefix but still fits the verb_noun convention. Consistent and predictable throughout.

Tool Count5/5

Seven tools is well-scoped for a risk-model analytics server. Each tool addresses a distinct capability—coverage, exposures, metadata, versions, portfolio risk, ETF look-through, and stress testing—without redundant endpoints.

Completeness4/5

Core workflows are covered: coverage checks, model metadata/versions, per-asset exposures, portfolio/ETF risk, and stress testing. Minor gaps include no direct factor covariance/correlation retrieval or historical backtesting, though these are mostly available indirectly or outside the stated scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues