HKUDS/Vibe-Trading · error · ValueError
asset_correlation must be in [0.0, 1.0), got {asset_correlat
Error message
asset_correlation must be in [0.0, 1.0), got {asset_correlation} What it means
vasicek_credit_var uses asset_correlation as rho in sqrt(rho) within the single-factor model, so it must be in [0.0, 1.0): 1.0 would make the portfolio a single perfectly correlated obligor and sqrt/expression degenerate; negatives are not valid correlations.
Source
Thrown at agent/src/quantlib/credit.py:938
* ``unexpected_loss`` (float): Economic capital / Credit VaR (WCL - EL).
* ``capital_ratio`` (float): Capital required as decimal fraction of EAD.
Raises:
ValueError: If parameters violate domain constraints.
"""
ead = _require_finite(ead, "ead")
pd = _require_finite(pd, "pd")
lgd = _require_finite(lgd, "lgd")
asset_correlation = _require_finite(asset_correlation, "asset_correlation")
confidence = _require_finite(confidence, "confidence")
if ead <= 0.0:
raise ValueError(f"ead must be strictly positive, got {ead}")
if not (0.0 < pd < 1.0):
raise ValueError(f"pd must be in (0.0, 1.0), got {pd}")
if not (0.0 <= lgd <= 1.0):
raise ValueError(f"lgd must be in [0.0, 1.0], got {lgd}")
if not (0.0 <= asset_correlation < 1.0):
raise ValueError(f"asset_correlation must be in [0.0, 1.0), got {asset_correlation}")
if not (0.0 < confidence < 1.0):
raise ValueError(f"confidence must be in (0.0, 1.0), got {confidence}")
rho = asset_correlation
inv_pd = float(norm.ppf(pd))
inv_conf = float(norm.ppf(confidence))
numerator = inv_pd + np.sqrt(rho) * inv_conf
denominator = np.sqrt(1.0 - rho)
wcdr = float(norm.cdf(numerator / denominator))
el = expected_loss(ead, pd, lgd)
wcl = float(ead * lgd * wcdr)
ul = float(max(0.0, wcl - el))
capital_ratio = float(ul / ead) if ead > 0 else 0.0
return {
"expected_loss": el,View on GitHub (pinned to 80ffdda44c)
Solutions
- Pass a decimal in [0.0, 1.0), e.g. 0.20
- Cap at 0.999 if your model approaches 1
- Convert percent inputs: rho = pct / 100
Example fix
# before var = vasicek_credit_var(1e6, 0.02, 0.6, asset_correlation=20, confidence=0.999) # after var = vasicek_credit_var(1e6, 0.02, 0.6, asset_correlation=0.20, confidence=0.999)
Defensive patterns
Strategy: validation
Validate before calling
asset_correlation = min(max(asset_correlation, 0.0), 0.999) var = vasicek_credit_var(ead, pd, lgd, asset_correlation, confidence)
Type guard
def is_valid_correlation(r: float) -> bool:
return isinstance(r, (int, float)) and 0.0 <= float(r) < 1.0 Try / catch
try:
var = vasicek_credit_var(ead, pd, lgd, rho, conf)
except ValueError as e:
if 'asset_correlation' in str(e):
var = vasicek_credit_var(ead, pd, lgd, 0.20, conf) # Basel default
else:
raise Prevention
- Convert Basel rho percentages to decimals
- Cap correlations below 1.0 in estimation code
- Validate 0 <= rho < 1 in config schemas
When it happens
Trigger: Calling vasicek_credit_var with asset_correlation = 1.0, -0.1, or a percent like 20 instead of 0.20.
Common situations: Basel-style correlations often quoted in percent; hitting exactly 1.0 with rho modeled as 1 - 1/n for small n; negative correlations from mis-estimated copulas.
Related errors
- ead must be strictly positive, got {ead}
- pd must be in (0.0, 1.0), got {pd}
- confidence must be in (0.0, 1.0), got {confidence}
- ts_corr window must be >= 2, got {n}
- survival_prob must be in (0.0, 1.0], got {survival_prob}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/8a80f8a00f25c317.
Report an issue: GitHub.