# QuantOS Statistics

> Returns comprehensive portfolio statistics including returns, risk, and ratios.

`POST https://api.bavest.co/v2/quant-os/stats`

Group: Bavest QuantOS. Route id: `v2_quant_os_stats`. Included in: Growth.

## Authentication

Send your API key in the `x-api-key` header on every request. No key yet? Sign up at https://dashboard.bavest.co/sign-up (free trial). The examples read the key from the `BAVEST_API_KEY` environment variable.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | QuantOSStats | no | Comprehensive portfolio statistics keyed by position index and total. |
| `data.sharpeRatio` | string | no | Sharpe ratio for this position or total portfolio. |
| `data.correlation` | object | no | Correlation matrix entries. |
| `data.series` | object | no | Time series data. |
| `data.series.t` | array of number | no |  |
| `data.series.c` | array of number | no |  |
| `data.series.h` | array of number | no |  |
| `data.series.l` | array of number | no |  |
| `data.series.o` | array of number | no |  |
| `data.series.s` | string | no |  |
| `data.series.v` | array of number | no |  |
| `data.stats` | object | no | Detailed performance statistics. |
| `data.stats.riskFree` | number (double) | no |  |
| `data.stats.totalReturn` | number (double) | no |  |
| `data.stats.cagr` | number (double) | no |  |
| `data.stats.maxDrawdown` | number (double) | no |  |
| `data.stats.calmar` | number (double) | no |  |
| `data.stats.mtd` | number (double) | no |  |
| `data.stats.threeMonth` | number (double) | no |  |
| `data.stats.sixMonth` | number (double) | no |  |
| `data.stats.ytd` | number (double) | no |  |
| `data.stats.oneYear` | number (double) | no |  |
| `data.stats.threeYear` | number (double) \| null | no |  |
| `data.stats.fiveYear` | number (double) \| null | no |  |
| `data.stats.tenYear` | number (double) \| null | no |  |
| `data.stats.inception` | number (double) | no |  |
| `data.stats.dailySharpe` | number (double) | no |  |
| `data.stats.dailySortino` | number (double) | no |  |
| `data.stats.dailyMean` | number (double) | no |  |
| `data.stats.dailyVolume` | number (double) | no |  |
| `data.stats.dailySkew` | number (double) | no |  |
| `data.stats.dailyKurt` | number (double) | no |  |
| `data.stats.bestDay` | number (double) | no |  |
| `data.stats.worstDay` | number (double) | no |  |
| `data.stats.monthlySharpe` | number (double) | no |  |
| `data.stats.monthlySortino` | number (double) | no |  |
| `data.stats.monthlyMean` | number (double) | no |  |
| `data.stats.monthlyVol` | number (double) | no |  |
| `data.stats.monthlySkew` | number (double) | no |  |
| `data.stats.monthlyKurt` | number (double) | no |  |
| `data.stats.bestMonth` | number (double) | no |  |
| `data.stats.worstMonth` | number (double) | no |  |
| `data.stats.yearlySharpe` | number (double) | no |  |
| `data.stats.yearlySortino` | number (double) | no |  |
| `data.stats.yearlyMean` | number (double) | no |  |
| `data.stats.yearlyVol` | number (double) | no |  |
| `data.stats.yearlySkew` | number (double) \| null | no |  |
| `data.stats.yearlyKurt` | number (double) \| null | no |  |
| `data.stats.bestYear` | number (double) | no |  |
| `data.stats.worstYear` | number (double) | no |  |
| `data.stats.avgDrawdown` | number (double) | no |  |
| `data.stats.avgDrawdownDays` | number (double) | no |  |
| `data.stats.avgUpMonth` | number (double) | no |  |
| `data.stats.avgDownMonth` | number (double) | no |  |
| `data.stats.winYearPerc` | number (double) | no |  |
| `data.stats.twelveMonthWinPerc` | number (double) | no |  |
| `data.error` | string \| null | no | Error message if computation failed for this position. |
| `meta` | ResponseMeta | no | Response envelope metadata. Always present on a 200: `time` is set by `core/response.py` on every successful response. Errors carry the same block, built by the same code, so a client parses one meta shape whether the call succeeded or failed. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |

## Example request

```bash
curl -X POST 'https://api.bavest.co/v2/quant-os/stats' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": {
    "0": {
      "sharpeRatio": "0.86",
      "correlation": {
        "0": 1,
        "1": "0.23",
        "total": "0.61"
      },
      "series": {
        "t": [
          1735819200
        ],
        "c": [
          -0.001
        ],
        "h": [],
        "l": [],
        "o": [],
        "s": "ok",
        "v": []
      },
      "stats": {
        "riskFree": 0.7,
        "totalReturn": 3.1483,
        "cagr": 2.1732,
        "maxDrawdown": -0.2838,
        "calmar": 7.6564,
        "mtd": -0.0437,
        "threeMonth": -0.0752,
        "sixMonth": -0.0094,
        "ytd": -0.0691,
        "oneYear": 0.1356,
        "threeYear": 2.1732,
        "fiveYear": null,
        "tenYear": null,
        "inception": 2.1732,
        "dailySharpe": 0.5308,
        "dailySortino": 6.8143,
        "dailyMean": 1.341,
        "dailyVolume": 1.5257,
        "dailySkew": 20.0825,
        "dailyKurt": 416.0306,
        "bestDay": 2,
        "worstDay": -0.0831,
        "monthlySharpe": 0.7119,
        "monthlySortino": 12.0393,
        "monthlyMean": 2.3582,
        "monthlyVol": 2.5504,
        "monthlySkew": 3.8309,
        "monthlyKurt": 14.7666,
        "bestMonth": 2.8494,
        "worstMonth": -0.0769,
        "yearlySharpe": 0.3986,
        "yearlySortino": 1.8269,
        "yearlyMean": 1.6935,
        "yearlyVol": 2.4926,
        "yearlySkew": null,
        "yearlyKurt": null,
        "bestYear": 3.456,
        "worstYear": -0.0691,
        "avgDrawdown": -0.0681,
        "avgDrawdownDays": 45.4444,
        "avgUpMonth": 0.4627,
        "avgDownMonth": -0.0364,
        "winYearPerc": 0.5,
        "twelveMonthWinPerc": 1
      },
      "error": null
    },
    "1": {
      "sharpeRatio": "0.76",
      "correlation": {
        "0": "0.23",
        "1": 1,
        "total": "0.91"
      },
      "series": {
        "t": [
          1736164800
        ],
        "c": [
          -0.0064
        ],
        "h": [],
        "l": [],
        "o": [],
        "s": "ok",
        "v": []
      },
      "stats": {
        "riskFree": 0.7,
        "totalReturn": 2.4973,
        "cagr": 1.7626,
        "maxDrawdown": -0.3245,
        "calmar": 5.4312,
        "mtd": -0.075,
        "threeMonth": -0.2495,
        "sixMonth": -0.2852,
        "ytd": -0.2391,
        "oneYear": -0.0623,
        "threeYear": 1.7626,
        "fiveYear": null,
        "tenYear": null,
        "inception": 1.7626,
        "dailySharpe": 0.4671,
        "dailySortino": 6.7901,
        "dailyMean": 1.2436,
        "dailyVolume": 1.5252,
        "dailySkew": 20.1235,
        "dailyKurt": 416.9528,
        "bestDay": 2,
        "worstDay": -0.0561,
        "monthlySharpe": 0.6578,
        "monthlySortino": 9.3706,
        "monthlyMean": 2.2948,
        "monthlyVol": 2.6637,
        "monthlySkew": 3.8205,
        "monthlyKurt": 14.7093,
        "bestMonth": 2.9598,
        "worstMonth": -0.1125,
        "yearlySharpe": 0.3608,
        "yearlySortino": 1.4736,
        "yearlyMean": 1.6785,
        "yearlyVol": 2.7118,
        "yearlySkew": null,
        "yearlyKurt": null,
        "bestYear": 3.596,
        "worstYear": -0.2391,
        "avgDrawdown": -0.0378,
        "avgDrawdownDays": 21.5,
        "avgUpMonth": 0.5558,
        "avgDownMonth": -0.0518,
        "winYearPerc": 0.5,
        "twelveMonthWinPerc": 0.8
      },
      "error": null
    },
    "total": {
      "sharpeRatio": "0.80",
      "correlation": {
        "0": "0.61",
        "1": "0.91",
        "total": 1
      },
      "series": {
        "t": [
          1736164800
        ],
        "c": [
          -0.0061
        ],
        "h": [],
        "l": [],
        "o": [],
        "s": "ok",
        "v": []
      },
      "stats": {
        "riskFree": 0.7,
        "totalReturn": 2.7369,
        "cagr": 1.9153,
        "maxDrawdown": -0.2371,
        "calmar": 8.0793,
        "mtd": -0.0625,
        "threeMonth": -0.1869,
        "sixMonth": -0.1934,
        "ytd": -0.1777,
        "oneYear": 0.0096,
        "threeYear": 1.9153,
        "fiveYear": null,
        "tenYear": null,
        "inception": 1.9153,
        "dailySharpe": 0.4899,
        "dailySortino": 8.2368,
        "dailyMean": 1.2772,
        "dailyVolume": 1.5227,
        "dailySkew": 20.2169,
        "dailyKurt": 419.6071,
        "bestDay": 2,
        "worstDay": -0.0489,
        "monthlySharpe": 0.675,
        "monthlySortino": 11.2402,
        "monthlyMean": 2.3096,
        "monthlyVol": 2.618,
        "monthlySkew": 3.8472,
        "monthlyKurt": 14.8585,
        "bestMonth": 2.9191,
        "worstMonth": -0.0811,
        "yearlySharpe": 0.3736,
        "yearlySortino": 1.5845,
        "yearlyMean": 1.6834,
        "yearlyVol": 2.632,
        "yearlySkew": null,
        "yearlyKurt": null,
        "bestYear": 3.5445,
        "worstYear": -0.1777,
        "avgDrawdown": -0.0428,
        "avgDrawdownDays": 28.4286,
        "avgUpMonth": 0.3995,
        "avgDownMonth": -0.0441,
        "winYearPerc": 0.5,
        "twelveMonthWinPerc": 0.8
      },
      "error": null
    }
  }
}
```

## Errors

| Status | Meaning |
|---|---|
| 400 | Invalid request parameters. Returned when required query parameters are missing, have invalid types, or violate constraints (e.g., providing both symbol and isin when they are mutually exclusive). |
| 401 | Missing or invalid API key. |
| 404 | Resource not found. |
| 429 | Rate limit exceeded. Retry after the `Retry-After` header interval. |
| 500 | An unexpected error occurred on the server. If the issue persists, contact support with the X-Request-Id header value. |
| 502 | Upstream data provider returned an error or is temporarily unavailable. Retry after a short delay. |
| 504 | The request timed out waiting for a response from the upstream data provider. This may occur for complex queries or during peak load. |
| default | An unexpected error occurred on the server. If the issue persists, contact support with the X-Request-Id header value. |

- `403` from the gateway: the API key is invalid or switched off.
- `429` with message `Limit Exceeded`: the monthly quota of the key is used up. With `Too Many Requests`: the key is throttled, or this route is not in the key's plan. Wait for `Retry-After` when it is sent.

## Links

- HTML page: https://dashboard.bavest.co/docs/v2_quant_os_stats
- OpenAPI: https://dashboard.bavest.co/openapi.json (YAML: https://dashboard.bavest.co/openapi.yaml)
- Authentication: https://dashboard.bavest.co/docs/authentication.md
- MCP server for AI agents: https://dashboard.bavest.co/docs/mcp.md
- All routes: https://dashboard.bavest.co/llms.txt
