Fixed Income Validation¶
1. Calculation Name¶
Fixed-Income Data Validation Suite
2. Description and Mathematical Formula¶
The validation plugin inspects inbound positions before calculations. Typical checks include:
- Required field coverage: \( \mathrm{Coverage} = \frac{\text{non-null rows}}{\text{total rows}} \)
- Tolerance checks: \( |x_{\text{portfolio}} - x_{\text{benchmark}}| \leq \tau \)
- Duration consistency: \( |\mathrm{DV01}_{\text{sum}} - \mathrm{Reported\ DV01}| \leq \epsilon \)
- FX exposure balance: \( \sum \mathrm{FX\ Notional} \approx 0 \) for hedged portfolios
3. Input Sample Data¶
| Check ID | Description | Sample Metric | Threshold | Status | Notes |
|---|---|---|---|---|---|
| FI-V-001 | Mandatory columns present (ISIN, MV, Yield) | 100% coverage | 100% | Pass | No missing cells |
| FI-V-004 | Sum of DV01 vs reported total | 144.7 vs 145.0 | ±0.5 | Pass | Difference = 0.3 |
| FI-V-007 | FX hedge residual | 0.8mm USD | ±1.0mm | Pass | Within tolerance |
| FI-V-010 | Negative amortization flag | 2 rows | 0 | Warn | Review expected amort schedule |
| FI-V-014 | Benchmark mapping coverage | 97% | 99% | Fail | 3 securities unmapped |
4. Mathematical Solution¶
- Coverage example: \( \frac{980 \text{ valid rows}}{980} = 100\% \) (Check FI-V-001).
- DV01 reconciliation: \( |144.7 - 145.0| = 0.3 \leq 0.5 \) → Pass.
- FX residual: \( |0.8| \leq 1.0 \) million → Pass.
- Amortization: 2 violations > 0 threshold → Warning.
- Benchmark mapping: \( 97\% < 99\% \) → Fail, highlighting missing benchmark IDs.
5. Sample Python and R Code¶
results = [
{"check": "FI-V-001", "metric": 1.00, "threshold": 1.00},
{"check": "FI-V-004", "metric": abs(144.7 - 145.0), "threshold": 0.5},
{"check": "FI-V-007", "metric": abs(0.8), "threshold": 1.0},
{"check": "FI-V-010", "metric": 2, "threshold": 0},
{"check": "FI-V-014", "metric": 0.97, "threshold": 0.99},
]
for row in results:
status = "Pass"
if row["metric"] > row["threshold"]:
status = "Warn" if row["check"] == "FI-V-010" else "Fail"
print(row["check"], status)
results <- tibble::tibble(
check = c("FI-V-001", "FI-V-004", "FI-V-007", "FI-V-010", "FI-V-014"),
metric = c(1.00, abs(144.7 - 145.0), abs(0.8), 2, 0.97),
threshold = c(1.00, 0.5, 1.0, 0, 0.99)
)
results <- results %>%
mutate(
status = case_when(
check == "FI-V-010" & metric > threshold ~ "Warn",
metric > threshold ~ "Fail",
TRUE ~ "Pass"
)
)
results
6. Output Table¶
| Severity | Checks | Action |
|---|---|---|
| Pass | FI-V-001, FI-V-004, FI-V-007 | No action required |
| Warn | FI-V-010 | Review amortization schedule |
| Fail | FI-V-014 | Map missing benchmark IDs before running attribution |
7. Conclusion¶
Validation guardrails prevent calculation surprises. Documenting the tests—and their thresholds—alongside the outputs helps operations teams close data gaps before running sensitive fixed-income analytics in FinFacts.