← Back to list

Claude Is Not a Risk Model. Here’s How to Give It One.

I asked Claude a simple question:

Kevin Meneses González in InsiderFinance Wire · 2026-07-05 09:00 · 50 claps · 8.3 min read
#claude-code #stocks #risk-management #stocks-to-watch #trading
Open on Medium ↗
Wiki topics: LLM · Large Language Models BIZ · Business Strategy

Claude Is Not a Risk Model. Here’s How to Give It One.

I asked Claude a simple question:

Set up the RiskModels.app MCP server, pull the latest ERM3 decomposition for CRM, and explain which risk layers dominate.

That prompt changes the whole workflow.

Without a real risk model, Claude can only summarize what it knows about Salesforce: cloud software, SaaS multiples, tech-sector sentiment, maybe market beta.

With **RiskModels** connected, Claude can query structured ERM3 data directly: market risk, sector risk, subsector risk, residual stock-specific risk, and ETF hedge ratios.

That is the difference between an AI finance chatbot and an AI finance workflow.

If you’re:

  • building AI-powered portfolio tools,
  • designing financial research assistants,
  • or trying to make LLM-based analysis actually defensible, this matters.

What Claude Can Do Without RiskModels

There’s a version of AI finance that’s everywhere right now.

You connect Claude or another LLM to a news feed, maybe some Yahoo Finance data, and ask it to “analyze” a portfolio. The model responds with a fluent, structured answer.

The problem is what’s underneath that answer.

LLMs don’t hold a time-safe, quantitative view of a stock’s residual risk, sector exposure, hedge ratios, or benchmark-relative structure. They generate text that resembles financial analysis — because they were trained on financial text.

When things go wrong in a portfolio, you need decomposable risk. You need to know: did a sector bet cause my loss? A stock-specific bet? Market drift?

An LLM generating plausible prose doesn’t tell you that. It can’t.

Most people discover this too late — after building something that looks like it works, but can’t survive a drawdown.

What Changes With RiskModels MCP

RiskModels connects Claude to a structured equity risk model.

Instead of guessing, the agent can read:

  • market risk,
  • sector risk,
  • subsector risk,
  • residual stock-specific risk,
  • ETF hedge ratios,
  • and the recommended hedge level.

Install the RiskModels MCP server:

RISKMODELS_API_KEY=your_api_key_here npx -y riskmodels@latest install

Then ask Claude:

Use RiskModels to decompose CRM. Explain the result like a quantitative portfolio analyst. Which risk layer dominates, what ETF hedge isolates residual risk, and what would this mean for an AI portfolio assistant?

Now the LLM is not inventing finance commentary from memory. It is operating over a real, time-stamped risk model.

The Reframe

The issue isn’t that LLMs are bad at finance.

The issue is that LLMs are interfaces, not models. They’re extraordinarily good at reasoning about structured inputs. What they lack — by design — is the underlying quantitative infrastructure.

An equity risk model is exactly that infrastructure.

What Comes Back

riskmodels.app exposes ERM3, an equity risk model built around orthogonal risk decomposition.

Most institutional risk models are powerful, but they are usually expensive, complex, and not designed as lightweight API infrastructure for LLM and agent workflows.

RiskModels ERM3 takes a different path.

Every stock is decomposed into four orthogonal risk layers:

  • Market — share of variance explained by broad-market exposure, paired with an SPY hedge ratio
  • Sector — share of variance explained by sector exposure, paired with a sector ETF hedge ratio
  • Subsector — share of variance explained by granular industry exposure, paired with a subsector ETF hedge ratio when available
  • Residual — stock-specific risk not explained by market, sector, or subsector layers

Each layer exposes **er (explained-risk contribution) and `hr`** (dollar-ratio hedge ratio: dollars of ETF per $1 of stock).

In this context, **er means explained risk — not expected return**. Values usually behave like variance fractions, and at L3 the four er values sum to approximately 1. Negative hedge ratios are normal when orthogonalization produces offsetting ETF legs.

These layers are designed not to double-count the same risk. The result is a decomposition that an LLM can reason from: structured JSON, time-stamped data, and ETF-denominated hedge ratios.

The useful part is that this is not prose. It is a structured API response that an app, notebook, agent, or LLM workflow can consume directly.

Here’s the actual ERM3 decomposition for CRM (Salesforce) as of July 1, 2026

{
  "symbol": "BW-BBG000BN2DC2",
  "ticker": "CRM",
  "teo": "2026-06-30",
  "periodicity": "daily",
  "metrics": {
    "vol_23d": 0.589259386062622,
    "vol_252d_ann": 0.3858542014951324,
    "price_close": 156.660003662109,
    "market_cap": 128304545792,
    "stock_var": 0.000588456052355468,
    "l1_mkt_hr": -0.329592645168304,
    "l1_mkt_er": 0.0420421026647091,
    "l1_res_er": 0.957957923412323,
    "l1_cfr": 0.00256646354682744,
    "l1_rr": -0.0106080006808043,
    "l2_mkt_hr": 0.0545208603143692,
    "l2_sec_hr": -0.232281267642975,
    "l2_mkt_er": 0.0420421026647091,
    "l2_sec_er": 0.0174417551606894,
    "l2_res_er": 0.940516114234924,
    "l2_cfr": 0.00605057645589113,
    "l2_rr": -0.0140921138226986,
    "l3_mkt_hr": -0.46987172961235,
    "l3_sec_hr": 0.848803222179413,
    "l3_sub_hr": -1.0611926317215,
    "l3_mkt_er": 0.0420421026647091,
    "l3_sec_er": 0.0174417551606894,
    "l3_sub_er": 0.498538792133331,
    "l3_res_er": 0.441977351903915,
    "l3_cfr": -0.0059721888974309,
    "l3_rr": -0.00206934846937656,
    "lstar_rr": -0.00206934846937656,
    "lstar_level": 3,
    "l1_mkt_beta": 0.329592645168304,
    "l2_sec_beta": 0.237241268157959,
    "l3_sub_beta": 1.10407972335815,
    "lstar": "L3",
    "recommended_hedge_level": "L2",
    "user_segment_applied": "family_office",
    "leverage_cap_applied": 2,
    "l1_hedge_gross": 0.329592645168304,
    "l2_hedge_gross": 0.28680212795734417,
    "l3_hedge_gross": 2.3798675835132626,
    "higher_er_haircut": 0.3611863831058143
  },
  "meta": {
    "sector_etf": "XLK",
    "subsector_etf": "IGV",
    "asset_type": "stock"
  },
  "hedge_levels": {
    "L1": {
      "market_hr": -0.329592645168304,
      "sector_hr": null,
      "subsector_hr": null,
      "market_er": 0.0420421026647091,
      "sector_er": null,
      "subsector_er": null,
      "residual_er": 0.957957923412323,
      "hedge_etfs": {
        "market": "SPY",
        "sector": null,
        "subsector": null
      }
    },
    "L2": {
      "market_hr": 0.0545208603143692,
      "sector_hr": -0.232281267642975,
      "subsector_hr": null,
      "market_er": 0.0420421026647091,
      "sector_er": 0.0174417551606894,
      "subsector_er": null,
      "residual_er": 0.940516114234924,
      "hedge_etfs": {
        "market": "SPY",
        "sector": "XLK",
        "subsector": null
      }
    },
    "L3": {
      "market_hr": -0.46987172961235,
      "sector_hr": 0.848803222179413,
      "subsector_hr": -1.0611926317215,
      "market_er": 0.0420421026647091,
      "sector_er": 0.0174417551606894,
      "subsector_er": 0.498538792133331,
      "residual_er": 0.441977351903915,
      "hedge_etfs": {
        "market": "SPY",
        "sector": "XLK",
        "subsector": "IGV"
      }
    },
    "recommended_level": "L2",
    "statistical_lstar": "L3"
  },
  "_metadata": {
    "model_version": "3.0",
    "data_as_of": "2026-06-30",
    "factor_set_id": "SPY_uni_mc_3000",
    "universe_size": 3069,
    "wiki_uri": "https://riskmodels.app/docs/methodology",
    "factors": [
      "SPY",
      "XLK",
      "IGV"
    ]
  },
  "_data_health": {
    "er_populated": true,
    "vol_populated": true,
    "l1_populated": true,
    "l2_populated": true,
    "data_as_of": "2026-06-30"
  },
  "_agent": {
    "request_id": "req_mr1uj9cw_jrhqwi",
    "latency_ms": 4446,
    "provenance": "https://riskmodels.app/docs/methodology"
  }
}

Four-Layer Risk Decomposition (market / sector / subsector / residual):
{
  "ticker": "CRM",
  "symbol": "BW-BBG000BN2DC2",
  "data_as_of": "2026-06-30",
  "teo": "2026-06-30",
  "exposure": {
    "market": {
      "er": 0.0420421026647091,
      "hr": -0.46987172961235,
      "hedge_etf": "SPY"
    },
    "sector": {
      "er": 0.0174417551606894,
      "hr": 0.848803222179413,
      "hedge_etf": "XLK"
    },
    "subsector": {
      "er": 0.498538792133331,
      "hr": -1.0611926317215,
      "hedge_etf": "IGV"
    },
    "residual": {
      "er": 0.441977351903915,
      "hr": null,
      "hedge_etf": null
    }
  },
  "stock_specific": {
    "explained_variance": null,
    "hedgeable": false
  },
  "style": {
    "explained_variance": null,
    "hedgeable": false,
    "role": "diagnostic"
  },
  "hedge": {
    "SPY": 0.46987172961235,
    "XLK": -0.848803222179413,
    "IGV": 1.0611926317215
  },
  "hedge_levels": {
    "L1": {
      "market_hr": -0.329592645168304,
      "sector_hr": null,
      "subsector_hr": null,
      "market_er": 0.0420421026647091,
      "sector_er": null,
      "subsector_er": null,
      "residual_er": 0.957957923412323,
      "hedge_etfs": {
        "market": "SPY",
        "sector": null,
        "subsector": null
      }
    },
    "L2": {
      "market_hr": 0.0545208603143692,
      "sector_hr": -0.232281267642975,
      "subsector_hr": null,
      "market_er": 0.0420421026647091,
      "sector_er": 0.0174417551606894,
      "subsector_er": null,
      "residual_er": 0.940516114234924,
      "hedge_etfs": {
        "market": "SPY",
        "sector": "XLK",
        "subsector": null
      }
    },
    "L3": {
      "market_hr": -0.46987172961235,
      "sector_hr": 0.848803222179413,
      "subsector_hr": -1.0611926317215,
      "market_er": 0.0420421026647091,
      "sector_er": 0.0174417551606894,
      "subsector_er": 0.498538792133331,
      "residual_er": 0.441977351903915,
      "hedge_etfs": {
        "market": "SPY",
        "sector": "XLK",
        "subsector": "IGV"
      }
    },
    "recommended_level": "L2",
    "statistical_lstar": "L3"
  },
  "_metadata": {
    "model_version": "3.0",
    "data_as_of": "2026-06-30",
    "factor_set_id": "SPY_uni_mc_3000",
    "universe_size": 3069,
    "wiki_uri": "https://riskmodels.app/docs/methodology",
    "factors": [
      "SPY",
      "XLK",
      "IGV"
    ]
  },
  "_data_health": {
    "er_populated": true,
    "er_sum": 1.0000000018626445
  },
  "_agent": {
    "request_id": "req_mr1uje9w_k0jw3u",
    "latency_ms": 1731,
    "provenance": "https://riskmodels.app/docs/methodology"
  }
}

Practitioner Reading

  • exposure.market.er = 0.042 → Broad market accounts for ~4% of the L3 explained-risk decomposition.
  • exposure.sector.er = 0.017 → XLK (tech sector) adds only ~2% incrementally at L3.
  • exposure.subsector.er = 0.49 → IGV (software ETF) is the dominant systematic layer — nearly half of explained risk.
  • exposure.residual.er = 0.44 → Residual is also large — CRM is not a pure factor bet. hedge_levels.recommended_level = “L2” → The model recommends the L2 hedge snapshot — SPY and XLK only, without the subsector leg (IGV)

Following the signed hedge ratios in hedge_levels.L2 to neutralize market and sector exposure. Note the statistical lstar still points to L3 (subsector dominance drives the raw variance decomposition), but the leverage-capped, risk-adjusted recommendation is L2 — a reminder that “which layer explains the most variance” and “what you should actually hedge” aren’t always the same answer.

This is the kind of structured signal that changes how you build AI-powered analysis tools.

Under the Hood: Two API Calls

The MCP setup is the agent-native path. Under the hood, the same workflow is just explicit HTTP: one call for a metrics snapshot, one call for the four-layer decomposition.

import os
import json
import requests
if "RISKMODELS_API_KEY" not in os.environ:
    raise RuntimeError("Set RISKMODELS_API_KEY before running this example.")
API_KEY = os.environ["RISKMODELS_API_KEY"]
TICKER = "CRM"
BASE_URL = "https://riskmodels.app/api"
headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}
def print_section(title, data):
    print(f"\n{'=' * 50}")
    print(title)
    print("=" * 50)
    print(json.dumps(data, indent=2))
# 1. Metrics snapshot (full L1/L2/L3 wire keys under `metrics`)
r = requests.get(f"{BASE_URL}/metrics/{TICKER}", headers=headers)
r.raise_for_status()
metrics = r.json()
print_section(f"Metrics: {TICKER}", metrics)
# 2. Four-layer risk decomposition (agent-friendly shape)
r = requests.post(
    f"{BASE_URL}/decompose",
    headers=headers,
    json={"ticker": TICKER},
)
r.raise_for_status()
decomp = r.json()
print_section(f"Decomposition: {TICKER}", decomp)

Get your API key at **riskmodels.app/get-key**.

Why This Matters for AI Finance Apps

Once risk is returned as structured JSON, an LLM can do useful work without pretending to be the model.

It can:

  • explain the decomposition in plain English,
  • compare two stocks using the same schema,
  • generate a hedge discussion from ETF-denominated ratios,
  • flag whether risk is mostly systematic or stock-specific,
  • and produce portfolio commentary grounded in data rather than vibes.

The LLM becomes the interface. The risk model remains the source of truth.

The Difference a Risk Model Makes

Without ERM3 — a typical Claude response:

“Salesforce is a leading enterprise software company with cloud exposure. It carries moderate volatility and tends to move with the broader tech sector. Investors should watch SaaS multiples and macro IT spending.”

With ERM3 JSON in context:

“CRM shows 0.49 subsector risk via IGV — the dominant systematic layer — and 0.44 residual. Market and sector together explain only ~6% (0.042 + 0.017). Despite subsector dominance, the model’s recommended hedge is L2 — SPY and XLK — not the full L3 stack, reflecting the leverage cap and haircut applied to the subsector layer. A trader following the L2 recommendation would leave more subsector exposure unhedged than the raw variance split alone would suggest.”

That’s a different answer. It’s decomposable and hedgeable.

The LLM didn’t become smarter. It got better inputs.

If You Want to Build the Agent Yourself

MCP is the fastest way to let Claude call RiskModels directly. If you are building your own app or agent loop, you can pass the same /decompose JSON into an LLM prompt.

Example using Anthropic — the same pattern works with OpenAI, Grok, or any model that can reason over JSON:

import os
import anthropic
import json
if "ANTHROPIC_API_KEY" not in os.environ:
    raise RuntimeError("Set ANTHROPIC_API_KEY before running this example.")
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
risk_context = json.dumps(decomp, indent=2)
message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": f"""You are a quantitative portfolio analyst.
Here is the ERM3 risk decomposition for CRM as of today:
{risk_context}
Based on this data:
1. Which risk layer is dominant?
2. What hedge would isolate the residual risk?
3. What does the residual layer tell us about the stock-specific exposure?
Be specific and reference the numbers directly."""
    }]
)
print(message.content[0].text)

Run the HTTP example first so decomp is in scope, or paste the JSON from /decompose directly.

Why Not Yahoo Finance?

Yahoo Finance is not designed as a point-in-time institutional security master. Ticker symbols change (FB → META). Corporate actions and index membership shift. Historical analysis can break silently when symbology drifts.

ERM3 is built on licensed market data and a security-master-driven process designed for point-in-time analysis. That matters when you need attribution and hedges that still make sense on historical dates — not just on today’s ticker label.

Frequently Asked Questions

What is an equity risk model and why do I need one for AI financial tools? It decomposes risk into orthogonal layers (market, sector, subsector, residual). Without it, LLMs have no structured basis for attribution or hedging recommendations.

Can I use this with Claude, ChatGPT, etc.? Yes. The API returns clean JSON for any LLM workflow, and the MCP server lets Claude call RiskModels directly. See riskmodels.app/quickstart.

Who is this for? Developers, quant researchers, advisors, and smaller investment teams that need risk infrastructure without an enterprise implementation cycle.

Get Started

Get your API key at **riskmodels.app/get-key**, then connect Claude:

RISKMODELS_API_KEY=your_api_key_here npx -y riskmodels@latest install

Want the explicit code path instead? The Python example above uses the same data through /api/metrics/{ticker} and /api/decompose.

Full code for this tutorial: **github.com/Kevinelectronics/finance_risk_model**

ERM3 is available as both an MCP server and a standard HTTP API.

LLMs don’t need to replace analysts. They need a risk model.

Now they have one.

A Message from InsiderFinance

Thanks for being a part of our community! Before you go:


메타데이터
post_id
be7a6eafa56b
slug
claude-is-not-a-risk-model-heres-how-to-give-it-one-be7a6eafa56b
url
https://wire.insiderfinance.io/claude-is-not-a-risk-model-heres-how-to-give-it-one-be7a6eafa56b
canonical_url
https://wire.insiderfinance.io/claude-is-not-a-risk-model-heres-how-to-give-it-one-be7a6eafa56b
author_url
https://medium.com/@kevinmenesesgonzalez
status
ok
fetched_at
2026-07-11 12:05:32