VOOZH about

URL: https://pypi.org/project/riskmodels-py/

⇱ riskmodels-py Β· PyPI


Skip to main content

riskmodels-py 0.3.10

pip install riskmodels-py

Latest release

Released:

Python SDK for the RiskModels API β€” decompose US equities into market/sector/subsector/residual variance shares and ETF hedge ratios

Navigation

Verified details

These details have been verified by PyPI
Maintainers
πŸ‘ Avatar for BlueWaterMacroCorp from gravatar.com
BlueWaterMacroCorp

Unverified details

These details have not been verified by PyPI
Project links
Meta
  • License: Other/Proprietary License (Proprietary)
  • Author: RiskModels
  • Tags ERM3 , equities , factors , hedging , risk
  • Requires: Python >=3.10
  • Provides-Extra: all , dev , dotenv , pdf , snapshots , viz , xarray

Project description

riskmodels-py

πŸ‘ PyPI version
πŸ‘ Open in Colab

Published on PyPI as riskmodels-py (import package riskmodels). Methodology / wiki: ERM3 L3 (aligned with API wiki_uri).

Try the Analysis Object Model without cloning: open the AOM quickstart (Colab) β€” install cell, API key (Secrets or paste), then rm / run examples. Same flows live in-repo as notebooks/quickstart.ipynb.

Thin surface walkthroughs (Colab): πŸ‘ Open in Colab β€” stocks (SDK)
Β· πŸ‘ Open in Colab β€” funds & 13F (HTTP)
β€” surface_stocks_sdk.ipynb (get_metrics, analyze_portfolio) and surface_funds_http.ipynb (funds search, GET /data/benchmark/…, 13F via quickstart_connect). For the full REST β†’ SDK β†’ AOM ladder, use riskmodels_quickstart.ipynb.

Python SDK for the RiskModels API: POST /decompose returns variance shares and ETF hedge ratios for any US equity, separating factor exposure from the residual bet so you can hedge what you don't want. ERM3 model; batch portfolio analysis included.

Install

pipinstallriskmodels-py

Since v0.3.4, the default install includes matplotlib and plotly so import riskmodels succeeds on a clean venv (snapshots/visuals pull them at import time). Heavy PDF/PNG exporters and Seaborn tooling stay behind extras:

pipinstallriskmodels-py[xarray]# optional xarray panel helpers
pipinstallriskmodels-py[viz]# Seaborn + Kaleido (static PNG/export paths)

Colab / notebooks: use riskmodels-py[viz] when you rely on Kaleido-backed PNG helpers (including plot_l3_year_end_stack, β‰₯0.3.3). Quickstart notebooks try PyPI first, then fall back to installing main from GitHub if the wheel is not uploaded yet. For a manual one-liner:

pipinstall-U"riskmodels-py[viz] @ git+https://github.com/BlueWaterCorp/RiskModels_API.git@main#subdirectory=sdk"

Maintainers: after adding new top-level SDK exports used in notebooks, publish the matching version to PyPI (sdk/pyproject.toml + twine) so the default pip install "riskmodels-py[viz]>=…" path works without the git fallback. Internal runbook: BWMACRO docs/RISKMODELS_PY_PYPI_PUBLISHING.md.

From this monorepo:

cdsdk&&pipinstall-e".[dev]"

Requires Python 3.10+.

Local env files (monorepo / Next.js parity)

Put your API key in .env.local (recommended) or .env:

  • Monorepo: RISKMODELS_API_KEY=rm_agent_... in the repository root .env.local (same file the Next.js app uses), and/or in sdk/.env.local if you only work under sdk/. Shell export values always win over files.

With pip install -e ".[dev]" or pip install "riskmodels-py[dotenv]", RiskModelsClient.from_env() loads .env then .env.local by walking up from the current working directory to the first folder that contains either file. Existing environment variables are never overwritten (shell exports and CI secrets win). Among files only, .env.local overrides .env for keys not already set.

Readme asset script: scripts/generate_readme_assets.py (run from repo root) also loads .env / .env.local from the repo root and from sdk/, so a key stored only in sdk/.env.local is picked up.

To call a local Next app (npm run dev), set RISKMODELS_BASE_URL=http://localhost:3000/api in .env.local (see repo root MAINTENANCE_GUIDE.md).

Quickstart

fromriskmodelsimport RiskModelsClient

client = RiskModelsClient.from_env() # RISKMODELS_API_KEY or OAuth client env vars; optional .env / .env.local (see below)
df = client.get_metrics("NVDA", as_dataframe=True)
pa = client.analyze({"NVDA": 0.5, "AAPL": 0.5}) # alias for analyze_portfolio
print(pa.portfolio_hedge_ratios["l3_market_hr"])
print(pa.to_llm_context())

Analysis Object Model (AOM) β€” v1

Canonical docs live in ../aom/. Preferred path: build a request with the fluent helper, then run (compile + execute in one call):

fromriskmodelsimport RiskModelsClient, rm, run
fromriskmodels.aomimport stock

client = RiskModelsClient.from_env()

req = (
 rm()
 .subject(stock("TSLA"))
 .scope(date_range_preset="ytd", as_of="latest")
 .return_attribution(resolution="full_stack", view="timeseries")
 .explain()
)

out = run(client, req)

Advanced: use compile_plan / execute_plan from riskmodels.aom when you need the plan object without HTTP (tests, logging, custom runners).

Namespaces + charts (v0.3+)

With pip install riskmodels-py[viz]:

fromriskmodelsimport RiskModelsClient

client = RiskModelsClient.from_env()

# Single- or multi-name L3 risk (Οƒ-scaled horizontal bars)
fig = client.stock.current.plot(
 style="l3_decomposition",
 sigma_scaled=True,
 tickers=["AAPL", "MSFT", "NVDA", "AMZN", "GOOG", "META", "TSLA"],
)
fig.show()

MAG7 β€” L3 explained risk (variance shares to 100%) β€” same chart as RM_ORG/demos/article_visuals.py β€œrisk DNA” variant (1): horizontal stacked bars, x-axis is fraction of variance, right-rail annotations use ER / systematic % (not Οƒ-scaled). The SDK Plotly figure defaults to theme="light" to match the article / matplotlib reference (white plot area, vertical x-grid, left y-spine, airy bar spacing). Pass theme="terminal_dark" to plot_l3_horizontal / save_l3_decomposition_png for a dark canvas. Use GOOG as the canonical Alphabet symbol.

πŸ‘ MAG7 L3 explained risk (latest snapshot)

fromriskmodelsimport RiskModelsClient, plot_mag7_l3_explained_risk, save_mag7_l3_explained_risk_png

client = RiskModelsClient.from_env()
fig = plot_mag7_l3_explained_risk(client) # or pass tickers=[...]
fig.show()

save_mag7_l3_explained_risk_png(client, filename="mag7_l3_explained_risk.png")
# client.visuals.save_mag7_l3_explained_risk_png(filename="mag7_l3_explained_risk.png")

MAG7 portfolio risk cascade (weights ∝ market cap) β€” fetch the MAG7 list, pull market_cap from each get_metrics snapshot, normalize to weights, then plot a variable-width stacked L3 decomposition (bars touch; width ∝ weight):

importpandasaspd
fromriskmodelsimport RiskModelsClient

client = RiskModelsClient.from_env()

mag7 = client.search_tickers(mag7=True)
caps: list[tuple[str, float]] = []
for sym in mag7["ticker"].astype(str).str.upper():
 snap = client.get_metrics(sym, as_dataframe=True)
 row = snap.iloc[0]
 cap = row.get("market_cap")
 if cap is None or (isinstance(cap, float) and pd.isna(cap)):
 continue
 caps.append((sym, float(cap)))

weights = pd.DataFrame(caps, columns=["ticker", "market_cap"])
weights["weight"] = weights["market_cap"] / weights["market_cap"].sum()
positions = weights[["ticker", "weight"]].to_dict("records")

fig = client.portfolio.current.plot(
 positions=positions,
 style="risk_cascade",
 sort_by="weight",
 include_systematic_labels=True,
)
fig.show()

# Optional: bundled PDF snapshot (premium endpoint; same weights)
# pdf_bytes = client.portfolio.current.pdf(positions=positions)

Portfolio risk snapshot PDF (POST /portfolio/risk-snapshot) β€” raw bytes without the visuals namespace:

frompathlibimport Path
fromriskmodelsimport RiskModelsClient

client = RiskModelsClient.from_env()
pdf_bytes, _lineage = client.post_portfolio_risk_snapshot_pdf(
 [("NVDA", 0.3), ("AAPL", 0.25), ("MSFT", 0.25), ("GOOGL", 0.2)],
 title="My sleeve",
)
Path("snapshot.pdf").write_bytes(pdf_bytes)

Stdlib-only example from repo root: python examples/python/portfolio_risk_snapshot_pdf.py (see docs/portfolio-risk-snapshot-runbook.md).

Publication PNGs (Kaleido)

With pip install riskmodels-py[viz] (Plotly + Kaleido), you can save finished charts in one or two lines. Defaults target ~1600Γ—1000 logical pixels with scale=3 for crisp PNGs; optional dpi maps to Kaleido scale as dpi / 96 (96 dpi baseline). Optional figsize=(width_px, height_px) overrides width / height.

fromriskmodelsimport RiskModelsClient, save_l3_decomposition_png, save_mag7_l3_explained_risk_png, save_portfolio_risk_cascade_png
fromriskmodels.visualsimport mag7_cap_weighted_positions

client = RiskModelsClient.from_env()

save_mag7_l3_explained_risk_png(client, filename="mag7_l3_explained_risk.png")

save_l3_decomposition_png(
 client,
 ticker="NVDA",
 filename="nvda_l3.png",
 title="NVDA β€” L3 risk decomposition",
 width=1600,
 height=1000,
 scale=3,
)

positions, weight_source = mag7_cap_weighted_positions(client)
save_portfolio_risk_cascade_png(
 client,
 positions=positions,
 filename="mag7_risk_cascade.png",
 subtitle=f"weights: {weight_source}",
)

# Equivalent facades on the client:
# client.visuals.save_l3_decomposition_png(filename="nvda_l3.png", ticker="NVDA")
# client.visuals.save_portfolio_risk_cascade_png(positions=positions, filename="mag7_risk_cascade.png")

# Optional: write NVDA + MAG7 L3 ER + MAG7 risk + MAG7 attribution PNGs to a folder (gallery helpers)
# from riskmodels.visuals import run_gallery_all
# run_gallery_all(client, output_dir="figures")

CLI (monorepo): from the repo root, with a key in .env.local or the environment:

pythonscripts/run_visuals_gallery.py-ofigures
# Regenerate the readme figure into sdk/images/:
# python scripts/run_visuals_gallery.py -o sdk/images --charts mag7-l3-er

Use --charts nvda / mag7-l3-er / mag7-risk / mag7-attribution for a single chart.

mag7_cap_weighted_positions uses market_cap from each get_metrics snapshot when enough values exist; otherwise it falls back to documented illustrative early 2026 cap-share weights (see MAG7_SNAPSHOT_DATE_DOC in riskmodels.visuals.gallery). save_portfolio_attribution_cascade_png needs the batch returns panel (the helper requests it automatically).

Weights are holdings-style fractions (sum to 1); analyze_portfolio renormalizes if a ticker fails batch resolution. Ticker aliases (e.g. GOOGL→GOOG) follow the usual ValidationWarning path.

Readable metrics snapshot (CLI): after pip install -e ".[dev]" from sdk/, run:

exportRISKMODELS_API_KEY=...
pythonexamples/quickstart.py

Optional: RISKMODELS_QUICKSTART_TICKER=AAPL. The script prints L3 hedge ratios, explained risk, optional market fields, and the ERM3 legend. Use format_metrics_snapshot(row) in your own code for the same text layout from a get_metrics dict row.

Metrics + macro factor correlation (one row)

ERM3 snapshot plus macro_corr_* columns (Pearson/Spearman vs bitcoin, VIX, etc.). macro_corr_* values are return correlations, not dollar hedges (l3_market_hr) or variance shares (l3_residual_er). Use return_type="gross" for total-equity co-movement with macro; use "l3_residual" for the idiosyncratic sleeve vs macro.

fromriskmodelsimport RiskModelsClient, to_llm_context

client = RiskModelsClient.from_env()
snap = client.get_metrics_with_macro_correlation(
 "NVDA",
 factors=["bitcoin", "vix"],
 return_type="l3_residual",
 window_days=252,
)
print(snap["macro_corr_bitcoin"].iloc[0], snap["l3_market_hr"].iloc[0])
print(to_llm_context(snap))

Raw macro factor series (no ticker)

get_macro_factor_series() calls GET /macro-factors β€” long table of factor_key, teo, return_gross for charts or offline checks. Requires the macro-factor-series scope on your API key (included in the SDK default scope string).

README and docs site PNGs (maintainers)

From the repository root (not sdk/), with a free-tier RISKMODELS_API_KEY:

exportRISKMODELS_API_KEY='paste-your-key-here'
pythonscripts/generate_readme_assets.py

Use single quotes around the key. If you add an end-of-line comment, it must start with # (ASCII). Otherwise put the comment on its own line above.

This calls MAG7 POST /correlation and get_rankings, then writes assets/*.png and mirrors the same files to public/docs/readme/ for the Next.js docs hub. Commit both trees so GitHub and the portal stay in sync.

Recursive Visual Refinement (MatPlotAgent)

Generate professional financial visualizations through automated Vision-LLM feedback:

fromopenaiimport OpenAI
fromriskmodelsimport RiskModelsClient

client = RiskModelsClient.from_env()
llm = OpenAI(api_key="...")

result = client.generate_refined_plot(
 plot_description="L3 risk decomposition stacked area chart for NVDA over 2 years",
 output_path="nvda_risk.png",
 llm_client=llm,
 max_iterations=5,
)

print(f"Generated in {result.iterations} iterations")
print(f"Saved to: {result.output_path}")

The generate_refined_plot method implements the MatPlotAgent Pattern:

  1. Execute: Runs generated matplotlib code in a subprocess
  2. Capture: Collects execution errors or output PNG
  3. See: Sends the image to a Vision-LLM (GPT-4o or Claude 3.5 Sonnet)
  4. Evaluate: LLM audits for overlapping text, legibility, legend accuracy, styling
  5. Refine: Iterates until "COMPLETE" or max iterations reached

Requirements: pip install openai matplotlib (or anthropic)

Financial Color Standards (enforced automatically):

  • Market Risk (SPY): Indigo (#4B0082)
  • Sector Risk: Green (#228B22)
  • Residual/Idiosyncratic: Gray (#808080)

Environment variables:

  • RISKMODELS_API_KEY β€” static Bearer token, or
  • RISKMODELS_CLIENT_ID + RISKMODELS_CLIENT_SECRET β€” OAuth2 client credentials (JWT ~15m),
  • RISKMODELS_BASE_URL (default https://riskmodels.app/api),
  • RISKMODELS_OAUTH_SCOPE (optional).

Agent-native helpers (vibe coding)

Use these so agents and humans never guess wire names or ERM3 semantics:

Tool Purpose
client.discover() Markdown or JSON digest (format="json", to_stdout=False): each method includes description, parameters (name, type, required, defaults, enums), returns, plus tool_definition_hints for Claude Desktop / MCP-style tool synthesis.
Ticker alias Curated remap (e.g. GOOGLβ†’GOOG) logs info and emits ValidationWarning (Warning: … Fix:) so agents refresh symbols.
to_llm_context(obj) One call β†’ Markdown tables + lineage + semantic cheatsheet + ERM3 legend (obj = DataFrame, PortfolioAnalysis, xarray.Dataset, or dict).
df.attrs["legend"] Short ERM3 text on every tabular result from the client (same as SHORT_ERM3_LEGEND).
df.attrs["riskmodels_semantic_cheatsheet"] Wire→semantic map + column hints + units (JSON + bullet list). Ground truth for field names.
df.attrs["riskmodels_lineage"] JSON string: model version, as-of, factor set, universe size when the API sent them.
df.attrs["riskmodels_kind"] What produced the frame (ticker_returns, portfolio_per_ticker, tickers_universe, …).
validate="warn" | "error" | "off" ER sum + HR sign checks; Error: / Warning: … Fix: strings for self-correction.
attach_sdk_metadata / ensure_dataframe_legend If you build a DataFrame manually, attach the same attrs so to_llm_context stays consistent.
build_semantic_cheatsheet_md() Standalone cheatsheet string for custom prompts.

Semantic names (always use in code and LLM explanations): l3_market_hr, l3_sector_hr, l3_subsector_hr, l3_market_er, … β€” not raw V3 keys like l3_mkt_hr. Batch Parquet/CSV wire columns l1/l2/l3 are renamed to those three L3 component HR series (not β€œL1/L2/L3 model levels”). Full reference (repo root):

Tip for agents: Prefer get_metrics(..., as_dataframe=True) so you get attrs; the plain dict return has no attrs.

Cursor: .cursorrules (math, naming, batch semantics).

PyPI distribution name vs import

  • Install from PyPI: pip install riskmodels-py (and optionally pip install riskmodels-py[xarray]).
  • Import in Python: from riskmodels import … β€” the distribution on PyPI is riskmodels-py; the package directory is riskmodels.

Core runtime dependencies are pandas, pyarrow, and httpx (HTTP). xarray is optional ([xarray] extra). The SDK does not depend on requests.

PyPI releases (maintainers)

Upload steps (version bump, build, twine, PyPI token format) are not in this public README. They are maintained in the private BWMACRO monorepo at docs/RISKMODELS_PY_PYPI_PUBLISHING.md β€” open that file from your internal BWMACRO clone.

Contributors

Named SDK contributors are listed in riskmodels/contributors.py and appear automatically in client.discover() (Markdown body and JSON spec key contributors), so anyone loading the capability digest β€” including coding agents β€” sees public credit.

License

Proprietary β€” same terms as RiskModels API access.

Project details

Verified details

These details have been verified by PyPI
Maintainers
πŸ‘ Avatar for BlueWaterMacroCorp from gravatar.com
BlueWaterMacroCorp

Unverified details

These details have not been verified by PyPI
Project links
Meta
  • License: Other/Proprietary License (Proprietary)
  • Author: RiskModels
  • Tags ERM3 , equities , factors , hedging , risk
  • Requires: Python >=3.10
  • Provides-Extra: all , dev , dotenv , pdf , snapshots , viz , xarray

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

riskmodels_py-0.3.10.tar.gz (34.0 MB view details)

Uploaded Source

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

riskmodels_py-0.3.10-py3-none-any.whl (33.4 MB view details)

Uploaded Python 3

File details

Details for the file riskmodels_py-0.3.10.tar.gz.

File metadata

  • Download URL: riskmodels_py-0.3.10.tar.gz
  • Upload date:
  • Size: 34.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for riskmodels_py-0.3.10.tar.gz
Algorithm Hash digest
SHA256 7148b680187778f498377a5457defac11d7c71054af863a39c6b56badd90f9f3
MD5 f775bf071d0452741e5d3ec125225c18
BLAKE2b-256 4d50fc36ea8e33881db67c1455ac67469e4319061aa75ffbb199aa251fb4527e

See more details on using hashes here.

File details

Details for the file riskmodels_py-0.3.10-py3-none-any.whl.

File metadata

  • Download URL: riskmodels_py-0.3.10-py3-none-any.whl
  • Upload date:
  • Size: 33.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for riskmodels_py-0.3.10-py3-none-any.whl
Algorithm Hash digest
SHA256 107bc160525c79ae69e60b73df16f684b5ebbf780924603f3fcd0f82bf645249
MD5 6a05bbebaae51299b1681ac98265b432
BLAKE2b-256 f2a79160b46842d274bb9de538c34aa1bd3d59597d4ffbad718ea98c76209766

See more details on using hashes here.

Supported by

πŸ‘ Image
AWS Cloud computing and Security Sponsor πŸ‘ Image
Datadog Monitoring πŸ‘ Image
Depot Continuous Integration πŸ‘ Image
Fastly CDN πŸ‘ Image
Google Download Analytics πŸ‘ Image
Pingdom Monitoring πŸ‘ Image
Sentry Error logging πŸ‘ Image
StatusPage Status page