# Ulcer Index API
> Ranks a cross-asset universe by how painful each market's drawdowns have been, and how much return it paid for that pain, computed live from Yahoo Finance daily closes — no key, nothing stored. Volatility treats an up-move and a down-move as equally risky, but investors only lose sleep over the downside: the depth of the fall from the last high and how long it drags on before recovering. The Ulcer Index (Peter Martin) captures exactly that — the root-mean-square of every day's percentage drawdown from the running peak, so a deep, long drawdown is penalised far more than a brief dip and a market that keeps making new highs scores near zero. From it comes the Martin ratio (the Ulcer Performance Index) — annualised excess return divided by the Ulcer Index — the return earned per unit of drawdown pain, a downside-only cousin of the Sharpe ratio. The asset endpoint returns one instrument's full pain profile: Ulcer Index, maximum, average and current drawdown, longest time underwater, the Martin ratio and the pain ratio. The screener endpoint ranks the 21-instrument universe (equities, sectors, commodities, bonds, crypto; filterable by class) by Martin ratio (best pain-adjusted return) or by Ulcer Index (smoothest ride). This is the drawdown-pain / Ulcer-Index cut — distinct from a current-drawdown monitor (a point-in-time snapshot of how far below peak each market is), the Sharpe/Sortino/Calmar screener (Calmar uses only the single worst drawdown) and the price APIs. It scores the whole shape of the pain, not one point of it.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/ulcerindex-api/..."
```

## Pricing
- **Free** (Free) — 760 calls/Mo, 2 req/s
- **Starter** ($11/Mo) — 16,400 calls/Mo, 6 req/s
- **Pro** ($35/Mo) — 88,000 calls/Mo, 16 req/s
- **Mega** ($79/Mo) — 488,000 calls/Mo, 40 req/s

## Endpoints

### Screener

#### `GET /v1/screener` — Rank the universe by Martin ratio or Ulcer Index

**Parameters:**
- `metric` (query, optional, string) — martin (best pain-adjusted return) or ulcer (smoothest) Example: `martin`
- `window` (query, optional, string) — Lookback in trading days (60-756) Example: `252`
- `class` (query, optional, string) — equity, sector, commodity, bond, crypto or all Example: `all`
- `rf` (query, optional, string) — Annual risk-free percent (0-20) Example: `0`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/ulcerindex-api/v1/screener?metric=martin&window=252&class=all&rf=0"
```

**Response:**
```json
{
    "data": {
        "note": "Ranked by Martin ratio descending (best pain-adjusted return first) over window_days of daily closes. Ulcer Index = RMS of daily drawdowns from the running peak (a deep, long drawdown is penalised most). Martin ratio = annualised excess return / Ulcer Index. Read fresh per call, nothing cached.",
        "class": "all",
        "count": 21,
        "metric": "martin",
        "source": "Yahoo Finance",
        "results": [
            {
                "name": "US Small Caps",
                "rank": 1,
                "class": "equity",
                "symbol": "IWM",
                "available": true,
                "pain_index": 2.15,
                "pain_ratio": 16.768,
                "ulcer_index": 3.17,
                "martin_ratio": 11.407,
                "observations": 252,
                "ann_return_pct": 36.11,
                "avg_drawdown_pct": -2.62,
                "max_drawdown_pct": -11.19,
                "current_drawdown_pct": -0.55,
                "current_underwater_days": 10,
                "longest_underwater_days": 57
            },
            {
                "name": "S&P 500",
                "rank": 2,
                "class": "equity",
                "symbol": "SPY",
                "available": true,
                "pain_index": 1.16,
                "pain_ratio": 19.699,
                "ulcer_index": 2.01,
                "martin_ratio": 11.36,
                "observations": 252,
                "a
…(truncated, see openapi.json for full schema)
```

### Asset

#### `GET /v1/asset` — Full drawdown-pain profile of one instrument

**Parameters:**
- `symbol` (query, required, string) — Universe symbol Example: `GLD`
- `window` (query, optional, string) — Lookback in trading days (60-756) Example: `252`
- `rf` (query, optional, string) — Annual risk-free percent (0-20) Example: `0`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/ulcerindex-api/v1/asset?symbol=GLD&window=252&rf=0"
```

**Response:**
```json
{
    "data": {
        "name": "Gold",
        "note": "Ulcer Index = RMS of daily drawdowns from the running peak over window_days; max/avg drawdown and longest_underwater_days describe the worst and the typical pain. Martin ratio = annualised excess return / Ulcer Index; pain ratio uses the mean absolute drawdown. Read fresh per call, nothing cached.",
        "class": "commodity",
        "reads": {
            "ulcer": "high drawdown pain",
            "martin": "excellent return per unit of drawdown pain",
            "underwater": "currently -22.1% below peak, 92 trading days underwater"
        },
        "source": "Yahoo Finance",
        "symbol": "GLD",
        "pain_index": 5.99,
        "pain_ratio": 4.24,
        "ulcer_index": 8.38,
        "window_days": 252,
        "martin_ratio": 3.03,
        "observations": 252,
        "risk_free_pct": 0,
        "ann_return_pct": 25.39,
        "avg_drawdown_pct": -7.12,
        "max_drawdown_pct": -24.46,
        "current_drawdown_pct": -22.1,
        "current_underwater_days": 92,
        "longest_underwater_days": 92
    },
    "meta": {
        "timestamp": "2026-06-12T10:34:51.495Z",
        "request_id": "e96c74b2-f596-4208-a463-a682130afc14"
    },
    "status": "ok",
    "message": "Asset pain profile retrieved successfully",
    "success": true
}
```

### Universe

#### `GET /v1/universe` — The cross-asset universe and its classes

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/ulcerindex-api/v1/universe"
```

**Response:**
```json
{
    "data": {
        "note": "The cross-asset universe the screener ranks. Pass class= to a screener call to rank within one class.",
        "count": 21,
        "assets": [
            {
                "name": "S&P 500",
                "class": "equity",
                "symbol": "SPY"
            },
            {
                "name": "Nasdaq 100",
                "class": "equity",
                "symbol": "QQQ"
            },
            {
                "name": "US Small Caps",
                "class": "equity",
                "symbol": "IWM"
            },
            {
                "name": "Developed ex-US",
                "class": "equity",
                "symbol": "EFA"
            },
            {
                "name": "Emerging Markets",
                "class": "equity",
                "symbol": "EEM"
            },
            {
                "name": "Technology",
                "class": "sector",
                "symbol": "XLK"
            },
            {
                "name": "Financials",
                "class": "sector",
                "symbol": "XLF"
            },
            {
                "name": "Energy",
                "class": "sector",
                "symbol": "XLE"
            },
            {
                "name": "Health Care",
                "class": "sector",
                "symbol": "XLV"
            },
            {
                "name": "Industrials",
                "class": "sector",
                "sym
…(truncated, see openapi.json for full schema)
```

### Meta

#### `GET /v1/meta` — Service metadata

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/ulcerindex-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "note": "metric is martin (default, best pain-adjusted return) or ulcer (least painful). window is 60-756 trading days (default 252). rf is an optional annual risk-free percent (0-20) netted off the Martin/pain ratios. class filters to equity/sector/commodity/bond/crypto (default all). Read fresh per call, nothing cached.",
        "source": "Yahoo Finance daily closes, live",
        "classes": [
            "equity",
            "sector",
            "commodity",
            "bond",
            "crypto"
        ],
        "metrics": [
            "martin",
            "ulcer"
        ],
        "service": "ulcerindex-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/asset": "Full drawdown-pain profile of one instrument (symbol=GLD, window=252, rf=0).",
            "GET /v1/screener": "Rank the universe by Martin ratio or Ulcer Index (metric=martin, window=252, class=all, rf=0).",
            "GET /v1/universe": "The cross-asset universe and its classes."
        },
        "description": "Ulcer Index & pain-adjusted return — ranks a cross-asset universe by how painful each market's drawdowns have been and how much return it paid for that pain, live from Yahoo Finance daily closes (no key, nothing stored). The Ulcer Index is the RMS of every day's drawdown from the running peak (depth and duration), and the Martin ratio is annualised excess return divided by it. asset returns one instrument's full pain p
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/ulcerindex-api
OpenAPI spec: https://www.oanor.com/api/ulcerindex-api/openapi.json
