Skip to content

Latest commit

 

History

History
452 lines (363 loc) · 10 KB

File metadata and controls

452 lines (363 loc) · 10 KB

Risk API

Endpoints for accessing risk metrics, VaR calculations, and exposure analysis.


Endpoints

Method Endpoint Description
GET /api/v1/risk/metrics Get all risk metrics
GET /api/v1/risk/var Get VaR details
GET /api/v1/risk/exposure Get exposure breakdown

Get Risk Metrics

Retrieve comprehensive risk metrics for the portfolio.

GET /api/v1/risk/metrics

Query Parameters

Parameter Type Required Description
as_of_date date Metrics date (default: today)

Example Request

curl http://localhost:8000/api/v1/risk/metrics

Response

{
  "date": "2024-01-15",
  "portfolio_value": 125000.00,
  "var": {
    "95_1d": {
      "confidence": 95,
      "horizon_days": 1,
      "var_pct": 1.65,
      "var_amount": 2062.50,
      "method": "historical_simulation"
    },
    "95_10d": {
      "confidence": 95,
      "horizon_days": 10,
      "var_pct": 5.22,
      "var_amount": 6525.00,
      "method": "historical_simulation"
    },
    "99_1d": {
      "confidence": 99,
      "horizon_days": 1,
      "var_pct": 2.33,
      "var_amount": 2912.50,
      "method": "historical_simulation"
    },
    "99_10d": {
      "confidence": 99,
      "horizon_days": 10,
      "var_pct": 7.37,
      "var_amount": 9212.50,
      "method": "historical_simulation"
    }
  },
  "drawdown": {
    "current_drawdown_pct": 3.2,
    "current_drawdown_amount": 4000.00,
    "max_drawdown_pct": 8.5,
    "max_drawdown_amount": 10625.00,
    "peak_date": "2024-01-05",
    "peak_value": 129000.00,
    "trough_date": "2024-01-10",
    "trough_value": 118375.00
  },
  "volatility": {
    "20d": 0.15,
    "60d": 0.18,
    "252d": 0.22
  },
  "sharpe_ratio": {
    "20d": 1.85,
    "60d": 1.42,
    "252d": 1.25,
    "risk_free_rate": 0.02
  },
  "risk_free_rate": 0.02
}

Response Fields

VaR (Value at Risk)

Field Description
confidence Confidence level (95% or 99%)
horizon_days Time horizon (1 or 10 days)
var_pct VaR as percentage of portfolio
var_amount VaR in base currency
method Calculation method

Drawdown

Field Description
current_drawdown_pct Current drawdown from peak (%)
current_drawdown_amount Current drawdown in currency
max_drawdown_pct Maximum drawdown experienced (%)
max_drawdown_amount Maximum drawdown in currency
peak_date Date of portfolio peak
peak_value Portfolio value at peak
trough_date Date of maximum drawdown
trough_value Portfolio value at trough

Volatility

Annualized volatility for different lookback windows.

Sharpe Ratio

Risk-adjusted returns for different lookback windows.


Get VaR Details

Retrieve detailed Value at Risk calculations.

GET /api/v1/risk/var

Query Parameters

Parameter Type Required Description
confidence integer Confidence level: 95 or 99 (default: 95)
horizon integer Time horizon in days: 1 or 10 (default: 1)

Example Request

curl "http://localhost:8000/api/v1/risk/var?confidence=99&horizon=1"

Response

{
  "confidence": 99,
  "horizon_days": 1,
  "var_pct": 2.33,
  "var_amount": 2912.50,
  "method": "historical_simulation",
  "portfolio_value": 125000.00,
  "calculation_date": "2024-01-15",
  "lookback_days": 252,
  "data_points": 252
}

VaR Interpretation

VaR 99% 1-day of $2,912.50 means: There is a 99% probability that the portfolio will not lose more than $2,912.50 in a single day under normal market conditions.


Get Exposure Breakdown

Retrieve portfolio exposure by various dimensions.

GET /api/v1/risk/exposure

Query Parameters

Parameter Type Required Description
as_of_date date Exposure date (default: today)
dimension string Specific dimension to return

Example Request

curl http://localhost:8000/api/v1/risk/exposure

Response

{
  "date": "2024-01-15",
  "base_currency": "USD",
  "total_gross_exposure": 150000.00,
  "total_net_exposure": 125000.00,
  "by_asset_class": [
    {
      "dimension": "asset_class",
      "value": "EQUITY",
      "long_exposure": 80000.00,
      "short_exposure": 0.00,
      "gross_exposure": 80000.00,
      "net_exposure": 80000.00,
      "gross_pct": 53.33,
      "net_pct": 64.00
    },
    {
      "dimension": "asset_class",
      "value": "CRYPTO",
      "long_exposure": 30000.00,
      "short_exposure": 0.00,
      "gross_exposure": 30000.00,
      "net_exposure": 30000.00,
      "gross_pct": 20.00,
      "net_pct": 24.00
    },
    {
      "dimension": "asset_class",
      "value": "FX",
      "long_exposure": 15000.00,
      "short_exposure": 0.00,
      "gross_exposure": 15000.00,
      "net_exposure": 15000.00,
      "gross_pct": 10.00,
      "net_pct": 12.00
    }
  ],
  "by_currency": [
    {
      "dimension": "currency",
      "value": "USD",
      "long_exposure": 100000.00,
      "short_exposure": 0.00,
      "gross_exposure": 100000.00,
      "net_exposure": 100000.00,
      "gross_pct": 66.67,
      "net_pct": 80.00
    },
    {
      "dimension": "currency",
      "value": "EUR",
      "long_exposure": 25000.00,
      "short_exposure": 0.00,
      "gross_exposure": 25000.00,
      "net_exposure": 25000.00,
      "gross_pct": 16.67,
      "net_pct": 20.00
    }
  ],
  "by_sector": [
    {
      "dimension": "sector",
      "value": "Technology",
      "long_exposure": 50000.00,
      "short_exposure": 0.00,
      "gross_exposure": 50000.00,
      "net_exposure": 50000.00,
      "gross_pct": 33.33,
      "net_pct": 40.00
    },
    {
      "dimension": "sector",
      "value": "Financials",
      "long_exposure": 20000.00,
      "short_exposure": 0.00,
      "gross_exposure": 20000.00,
      "net_exposure": 20000.00,
      "gross_pct": 13.33,
      "net_pct": 16.00
    }
  ]
}

Exposure Fields

Field Description
long_exposure Total long position value
short_exposure Total short position value
gross_exposure Long + Short (absolute)
net_exposure Long - Short
gross_pct Percentage of total gross
net_pct Percentage of total net

Risk Metrics Calculation Methods

Value at Risk (VaR)

FARP uses Historical Simulation for VaR calculation:

  1. Collect historical returns (default: 252 days)
  2. Calculate portfolio returns based on current holdings
  3. Sort returns from worst to best
  4. Find the return at the confidence percentile
  5. Scale for time horizon using √T approximation

Formula:

VaR(T days) = VaR(1 day) × √T

Volatility

Annualized standard deviation of daily returns:

Volatility = StdDev(Daily Returns) × √252

Sharpe Ratio

Risk-adjusted return measure:

Sharpe = (Annualized Return - Risk Free Rate) / Annualized Volatility

Maximum Drawdown

Largest peak-to-trough decline:

Drawdown = (Peak Value - Trough Value) / Peak Value

Beta

Correlation with market benchmark (SPY):

Beta = Cov(Portfolio, Benchmark) / Var(Benchmark)

Response Schemas

RiskMetricsResponse

{
  "date": "string (YYYY-MM-DD)",
  "portfolio_value": "number",
  "var": {
    "<confidence>_<horizon>d": {
      "confidence": "integer",
      "horizon_days": "integer",
      "var_pct": "number",
      "var_amount": "number",
      "method": "string"
    }
  },
  "drawdown": {
    "current_drawdown_pct": "number",
    "current_drawdown_amount": "number",
    "max_drawdown_pct": "number",
    "max_drawdown_amount": "number",
    "peak_date": "string | null",
    "peak_value": "number | null",
    "trough_date": "string | null",
    "trough_value": "number | null"
  },
  "volatility": {
    "<window>d": "number"
  },
  "sharpe_ratio": {
    "<window>d": "number",
    "risk_free_rate": "number"
  },
  "risk_free_rate": "number"
}

ExposureResponse

{
  "dimension": "string (asset_class | currency | sector)",
  "value": "string",
  "long_exposure": "number",
  "short_exposure": "number",
  "gross_exposure": "number",
  "net_exposure": "number",
  "gross_pct": "number",
  "net_pct": "number"
}

Python Example

import requests

API_BASE = "http://localhost:8000/api/v1"

# Get all risk metrics
risk = requests.get(f"{API_BASE}/risk/metrics").json()

print(f"Portfolio Value: ${risk['portfolio_value']:,.2f}")
print("\n=== VaR ===")
for key, var in risk['var'].items():
    print(f"  VaR {var['confidence']}% {var['horizon_days']}d: ${var['var_amount']:,.2f} ({var['var_pct']:.2f}%)")

print("\n=== Drawdown ===")
dd = risk['drawdown']
print(f"  Current: {dd['current_drawdown_pct']:.2f}%")
print(f"  Maximum: {dd['max_drawdown_pct']:.2f}%")

print("\n=== Volatility ===")
for window, vol in risk['volatility'].items():
    print(f"  {window}: {vol*100:.1f}%")

print("\n=== Sharpe Ratio ===")
for window, sharpe in risk['sharpe_ratio'].items():
    if window != 'risk_free_rate':
        print(f"  {window}: {sharpe:.2f}")

# Get exposure breakdown
exposure = requests.get(f"{API_BASE}/risk/exposure").json()

print("\n=== Asset Class Exposure ===")
for exp in exposure['by_asset_class']:
    print(f"  {exp['value']}: {exp['net_pct']:.1f}%")

Notes

  1. Historical Data Required: Risk metrics require historical price data. Ensure prices are seeded before calculating metrics.

  2. Minimum Data Points: VaR calculations require at least 20 data points. Results may be less reliable with fewer observations.

  3. Risk-Free Rate: Configurable via RISK_FREE_RATE environment variable (default: 0.02 = 2%).

  4. Benchmark: Beta is calculated against SPY by default. Ensure SPY price data is available for beta calculations.

  5. VaR Limitations: Historical simulation VaR assumes past returns are indicative of future returns and may underestimate tail risk.