Skip to main content

Python SDK for the RiskModels API (ERM3 factors, hedge ratios, explained risk)

Project description

riskmodels-py

PyPI version

Published on PyPI as riskmodels-py (import package riskmodels).

Python SDK for the RiskModels API (ERM3 factor model: hedge ratios, explained risk, batch portfolio analysis).

Install

pip install riskmodels-py
# Optional xarray panel interface:
pip install riskmodels-py[xarray]

From this monorepo:

cd sdk && pip install -e ".[dev]"

Requires Python 3.10+.

Local env files (monorepo / Next.js parity)

With pip install -e ".[dev]" or pip install "riskmodels-py[dotenv]", RiskModelsClient.from_env() loads .env then .env.local from the current working directory (walking up to the first directory 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.

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

from riskmodels import 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())

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

export RISKMODELS_API_KEY=...
python examples/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.

from riskmodels import 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))

README and docs site PNGs (maintainers)

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

export RISKMODELS_API_KEY='paste-your-key-here'
python scripts/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:

from openai import OpenAI
from riskmodels import 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.

Publishing to PyPI (maintainers)

Build and upload from this directory (sdk/, not packages/riskmodels/ — that layout was retired; see repo CHANGELOG.md).

  1. Bump version in pyproject.toml for every upload (PyPI rejects duplicate versions).
  2. Build and verify:
cd sdk
python3 -m pip install -U build twine
python3 -m build
python3 -m twine check dist/*
  1. TestPyPI (optional): python3 -m twine upload --repository testpypi dist/* — install with
    pip install --index-url https://test.pypi.org/simple/ riskmodels-py
  2. Production: python3 -m twine upload dist/* — use PyPI username __token__ and an API token as the password.

License

Proprietary — same terms as RiskModels API access.

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

riskmodels_py-0.2.4.tar.gz (58.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

riskmodels_py-0.2.4-py3-none-any.whl (52.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: riskmodels_py-0.2.4.tar.gz
  • Upload date:
  • Size: 58.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for riskmodels_py-0.2.4.tar.gz
Algorithm Hash digest
SHA256 9a1300740b7505b702848c1269dbb4ddcbae0edeae9f4b10ec7a214b7f258ab3
MD5 f1e4c905c1fc936d162b6207d555018e
BLAKE2b-256 450e65864298666a1bbf6f030d57e2c74dabe720d13200130675a5a063bebdf1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: riskmodels_py-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 52.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for riskmodels_py-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 134b4c9f678d256a94e0d185ee06c88fcaba47bac11c79f3da04d35dba713c4a
MD5 42b14918747750f89ad5ab4529102d44
BLAKE2b-256 de7e0dd67e656ae89cbe348758c7b8384d58ba93a1ae00b2d62492788f7218c5

See more details on using hashes here.

Supported by

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