Documentation
MBB Risk Engine is a high-performance analytics platform for callable mortgage bonds: build portfolios, design prepayment models, and calibrate Z-SHIFT in milliseconds to reconcile model and market dirty prices. Compute a full AAD risk stack (BPV, smooth/stable convexity, and vega buckets) instantly—whether for pricing or large-scale scenario sweeps—so you can move from inputs to decisions in near real time, even on long-dated bonds.
Theoretical documentation
Interest rate model (Hull–White / GSR short-rate)
dr(t) = (θ(t) − κ·r(t)) dt + σ(t) dW(t)
κis the mean-reversion speed (constant).σ(t)is a term-structure of volatility implemented as piecewise-constant buckets over time.θ(t)is chosen so the model fits the initial discount curve exactly.
Prepayment model
- Schedule-driven: applied at event dates alongside coupon/settlement logic.
- Path dependent: the pool factor evolves over time and affects future cashflows.
- Calibration link: Z-shift reconciliation: calibrate a constant parallel shift to the input yield curve; this shift affects both discounting and prepayment behavior (via incentive measures), and is solved so the schedule-driven model matches the market dirty price.
Risk numbers
- BPV / DV01: price sensitivity to small curve shocks (units: per 1bp, with your sign convention).
- Convexity: second-order rate sensitivity (stable/consistent with the engine’s definition).
- Vega: sensitivity to σ-bucket shocks (bucketed term-structure exposures).
- Kappa sensitivity: shows the change in value with respect to the kappa parameter.
Automatic differentiation (AAD)
- First-order: curve and σ-bucket sensitivities (and model parameter sensitivities where enabled).
- Second-order: convexity-style measures via stable second-derivative workflows.
- One engine: no separate “risk pricer” — sensitivities are tied to the exact schedule/PDE logic used for price.
Performance
Risk numbers
Manuals & sample files
CSV templates
- portfolio_sample_display_units.csv — Portfolio (includes custom cashflow example row; contains display-unit + canonical fallback columns for compatibility)
- market_data_sample.csv — Market data
- pde_settings_sample.csv — PDE settings
Generic table keyboard shortcuts
Cmd. Windows/Linux: use Ctrl.
Cmd/Ctrl + Left: jump to leftmost column in the current rowCmd/Ctrl + Right: jump to rightmost column in the current rowCmd/Ctrl + Up: jump to first row in the current columnCmd/Ctrl + Down: jump to last row in the current column
Full input samples with cashflow (JSON/XLSX)
Prepayment Model Builder
- Start from a known example
- Edit logic or parameters, then rerun pricing/risk/scenarios
Guide (PDF)
Sample models (JSON)
- prep_model_example_1.json
- prep_model_example_2.json
- prep_model_example_3.json
- prep_model_example_4.json
- prep_model_example_5.json
Units & interpretation
- BPV/convexity/vega definitions: see Risk Numbers
Notes on units
- Some inputs are displayed in scaled units (e.g. bps, %), but stored internally in canonical decimals.
- When importing CSV, the sample files match the UI’s display units.
API (external usage)
Base URL
https://api.mbbriskengine.com
API flow (3 calls)
-
Submit calculation file (multipart form):
POST https://api.mbbriskengine.com/v1/runs -
Read
run_idfrom the response, then poll status:
GET https://api.mbbriskengine.com/v1/runs/{run_id} -
When status is
succeeded, download artifact(s):
GET https://api.mbbriskengine.com/v1/runs/{run_id}/artifact?format=json
GET https://api.mbbriskengine.com/v1/runs/{run_id}/artifact?format=xlsx
.xlsx, .xlsm, .json.
Output format options
output_format=jsonreturns JSON artifactoutput_format=xlsxreturns Excel artifactoutput_format=bothlets you download both JSON and XLSX
output_format controls what the backend generates. You still download each artifact explicitly using
?format=json and/or ?format=xlsx.
Timing basis and GSR (important)
day_count_basissets how payment dates are converted to year fractions (the PDE time grid).- GSR is evaluated on that same time grid.
- If omitted, default is
ThirtyE360. - For GUI/API parity, keep all model inputs identical: portfolio (including custom cashflows), request settings (
trade_date_iso,command, calibration/z-shift options),market_data(yieldTable,volTable,meanrev),pde_settings, andprepayment_spec.
Sample input files
Core request block
For JSON input, set this under request. For Excel input, use the same keys in the request sheet.
"request": {
"command": "BOTH",
"output_format": "both",
"zshift_unit": "bp",
"calibrate_zshift": true,
"calibrate_zshift0_dec": 0.0,
"calibrate_max_iter": 20,
"calibrate_tol": 1e-8,
"trade_date_iso": "2026-02-11"
}
custom_cashflow_enabled=true, payment dates and amounts in
custom_cashflow are taken literally. amortisation_type is ignored; date
adjustment and entitlement settings (date_move_convention, day_count_basis,
ex_interest_days, ex_redemption_days, ex_lag_in_business_days,
use_default_calendar_if_empty) still apply.
Allowed values (quick reference)
request.command
RISK— run risk calculation onlySCENARIO— run scenario calculation onlyBOTH— run both risk and scenario (recommended for full output)
request.output_format
json— backend generates JSON artifactxlsx— backend generates Excel artifactboth— backend generates both JSON and Excel artifacts
?format=json and/or ?format=xlsx.
Start here (most users)
- Download a sample JSON from Manuals & Samples.
- Set
INFILEto your local file path. - Copy/paste one block below (Unix/macOS or Windows PowerShell).
Unix/macOS terminal (copy/paste)
Set INFILE to your local .json request file.
Set output mode inside the file at request.output_format (json, xlsx, or both).
# COPY FROM HERE (include all lines)
API="https://api.mbbriskengine.com"
INFILE="$HOME/Downloads/mbb_risk_api_input_sample_with_cashflow.json"
[ -f "$INFILE" ] || { echo "File not found: $INFILE (download the sample JSON from this page first)"; exit 1; }
echo "Using input: $INFILE"
# 1) Create run
RESP=$(curl -sS -X POST "$API/v1/runs" \
-F "file=@${INFILE}")
echo "$RESP"
RUN_ID=$(printf "%s" "$RESP" | sed -n 's/.*"run_id":"\([^"]*\)".*/\1/p')
echo "RUN_ID=$RUN_ID"
# 2) Poll until done
while true; do
ST=$(curl -sS "$API/v1/runs/$RUN_ID")
STATUS=$(printf "%s" "$ST" | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
echo "status=$STATUS"
if [ "$STATUS" = "succeeded" ]; then break; fi
if [ "$STATUS" = "failed" ]; then echo "$ST"; exit 1; fi
sleep 1
done
# 3) Download artifacts (both if available)
OUTDIR="$(dirname "$INFILE")"
JSON_OUT="${OUTDIR}/${RUN_ID}_output.json"
XLSX_OUT="${OUTDIR}/${RUN_ID}_output.xlsx"
if curl -fsS -L "$API/v1/runs/$RUN_ID/artifact?format=json" -o "$JSON_OUT"; then
echo "saved $JSON_OUT"
else
echo "JSON artifact not available"
fi
if curl -fsS -L "$API/v1/runs/$RUN_ID/artifact?format=xlsx" -o "$XLSX_OUT"; then
echo "saved $XLSX_OUT"
else
echo "XLSX artifact not available (set request.output_format to xlsx or both)"
fi
# COPY UNTIL HERE
Windows PowerShell (copy/paste)
Set INFILE to your local .json request file.
Use curl.exe exactly as shown.
# COPY FROM HERE (include all lines)
$API = "https://api.mbbriskengine.com"
$INFILE = "$env:USERPROFILE\Downloads\mbb_risk_api_input_sample_with_cashflow.json"
if (!(Test-Path $INFILE)) { Write-Host "File not found: $INFILE (download the sample JSON from this page first)"; exit 1 }
Write-Host "Using input: $INFILE"
# 1) Create run
$RESP_RAW = curl.exe -sS -X POST "$API/v1/runs" -F "file=@$INFILE"
Write-Output $RESP_RAW
$RUN_ID = ($RESP_RAW | ConvertFrom-Json).run_id
if (-not $RUN_ID) { Write-Host "Could not parse run_id"; exit 1 }
Write-Host "RUN_ID=$RUN_ID"
# 2) Poll until done
while ($true) {
$ST_RAW = curl.exe -sS "$API/v1/runs/$RUN_ID"
$STATUS = ($ST_RAW | ConvertFrom-Json).status
Write-Host "status=$STATUS"
if ($STATUS -eq "succeeded") { break }
if ($STATUS -eq "failed") { Write-Output $ST_RAW; exit 1 }
Start-Sleep -Seconds 1
}
# 3) Download artifacts (both if available)
$OUTDIR = Split-Path -Parent $INFILE
$JSON_OUT = Join-Path $OUTDIR "${RUN_ID}_output.json"
$XLSX_OUT = Join-Path $OUTDIR "${RUN_ID}_output.xlsx"
curl.exe -fsS -L "$API/v1/runs/$RUN_ID/artifact?format=json" -o "$JSON_OUT"
if ($LASTEXITCODE -eq 0) {
Write-Host "saved $JSON_OUT"
} else {
Write-Host "JSON artifact not available"
}
curl.exe -fsS -L "$API/v1/runs/$RUN_ID/artifact?format=xlsx" -o "$XLSX_OUT"
if ($LASTEXITCODE -eq 0) {
Write-Host "saved $XLSX_OUT"
} else {
Write-Host "XLSX artifact not available (set request.output_format to xlsx or both)"
}
# COPY UNTIL HERE
Advanced: run as saved file (Unix/macOS)
Save once and re-run with different JSON files.
cat > ~/Downloads/test_mbb_api_json.sh <<'SH'
#!/usr/bin/env bash
set -euo pipefail
API="${API:-https://api.mbbriskengine.com}"
INFILE="${1:?Usage: test_mbb_api_json.sh /absolute/path/to/input.json}"
[ -f "$INFILE" ] || { echo "File not found: $INFILE"; exit 1; }
RESP=$(curl -sS -X POST "$API/v1/runs" -F "file=@${INFILE}")
echo "Create response: $RESP"
RUN_ID=$(printf "%s" "$RESP" | sed -n 's/.*"run_id":"\([^"]*\)".*/\1/p')
[ -n "$RUN_ID" ] || { echo "Could not parse run_id"; exit 1; }
while true; do
ST=$(curl -sS "$API/v1/runs/$RUN_ID")
STATUS=$(printf "%s" "$ST" | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
echo "status=$STATUS"
if [ "$STATUS" = "succeeded" ]; then break; fi
if [ "$STATUS" = "failed" ]; then echo "$ST"; exit 1; fi
sleep 1
done
OUTDIR="$(dirname "$INFILE")"
JSON_OUT="${OUTDIR}/${RUN_ID}_output.json"
XLSX_OUT="${OUTDIR}/${RUN_ID}_output.xlsx"
if curl -fsS -L "$API/v1/runs/$RUN_ID/artifact?format=json" -o "$JSON_OUT"; then
echo "saved $JSON_OUT"
else
echo "JSON artifact not available"
fi
if curl -fsS -L "$API/v1/runs/$RUN_ID/artifact?format=xlsx" -o "$XLSX_OUT"; then
echo "saved $XLSX_OUT"
else
echo "XLSX artifact not available (set request.output_format to xlsx or both)"
fi
SH
chmod +x ~/Downloads/test_mbb_api_json.sh
~/Downloads/test_mbb_api_json.sh "$HOME/Downloads/mbb_risk_api_input_sample_with_cashflow.json"
Common issues
Only .xlsx/.xlsm/.json files are supported: upload one of these file types.output_format="both"but no Excel file: you must also call/artifact?format=xlsx.status=failedwith validation message: check required fields in your uploaded file.
More issues
- Custom cashflow rule: when
custom_cashflow_enabled=true, the lastpayment_dateincustom_cashflowmust equalmaturity_datefor that row. - Explicit cashflow mode: payment dates and amounts are taken from
custom_cashflowliterally;ex_interest_daysandex_redemption_daysare ignored.
Contact
Disclaimer
Important notice
No warranty
Use at your own risk
Independent judgment required
Acceptance
References
static/papers/pde-aad-risk-numbers.pdf.