{"record":{"id":"d597977d9475fbe4","repo":"HKUDS/Vibe-Trading","slug":"price-face-par-amount-must-be-positive-and-sprea","errorCode":null,"errorMessage":"price, face, par_amount must be positive and spread_duration non-negative","messagePattern":"price, face, par_amount must be positive and spread_duration non-negative","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/credit.py","lineNumber":992,"sourceCode":"    Args:\n        spread_duration: Modified/spread duration in years.\n        price: Current clean market price of the credit instrument.\n        face: Quoted par base (standard 100.0).\n        par_amount: Total par notional held in position.\n\n    Returns:\n        Dollar loss for a 1 bp increase in credit spread (positive float).\n\n    Raises:\n        ValueError: If price, face, or par_amount is not positive, or if\n            spread_duration is negative.\n    \"\"\"\n    spread_duration = _require_finite(spread_duration, \"spread_duration\")\n    price = _require_finite(price, \"price\")\n    face = _require_finite(face, \"face\")\n    par_amount = _require_finite(par_amount, \"par_amount\")\n    if face <= 0.0 or price <= 0.0 or par_amount <= 0.0 or spread_duration < 0.0:\n        raise ValueError(\"price, face, par_amount must be positive and spread_duration non-negative\")\n    return float(spread_duration * (price / face) * 1e-4 * par_amount)\n","sourceCodeStart":974,"sourceCodeEnd":994,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/credit.py#L974-L994","documentation":"credit_spread_dv01 computes spread DV01 as spread_duration * (price/face) * 1e-4 * par_amount. price, face, and par_amount enter as denominators/scalars and must be positive, while spread_duration only scales the sensitivity and may be zero. A single combined message covers all four checks.","triggerScenarios":"Calling credit_spread_dv01 with price <= 0, face <= 0, par_amount <= 0, or a negative spread_duration; e.g. price=0 for a defaulted bond or face passed as a negative booked amount.","commonSituations":"Distressed/defaulted bond prices of 0; negative face amounts from short positions in booking systems; zero-initialized struct fields; sign errors in duration calculations.","solutions":["Inspect all four arguments; the message does not say which one failed","Use positive prices/faces/par amounts; use abs() on booked shorts and flip result signs yourself","Default spread_duration to 0.0 (allowed) rather than -1 or None placeholders"],"exampleFix":"# before\ndv01 = credit_spread_dv01(spread_duration=4.5, price=0.0, face=100.0, par_amount=1_000_000)\n\n# after\ndv01 = credit_spread_dv01(spread_duration=4.5, price=98.5, face=100.0, par_amount=1_000_000)","handlingStrategy":"validation","validationCode":"if min(price, face, par_amount) <= 0.0 or spread_duration < 0.0:\n    raise ValueError(f\"bad dv01 inputs: price={price}, face={face}, par={par_amount}, dur={spread_duration}\")\ndv01 = credit_spread_dv01(spread_duration, price, face, par_amount)","typeGuard":"def is_valid_dv01_inputs(price: float, face: float, par: float, dur: float) -> bool:\n    return all(math.isfinite(v) and v > 0 for v in (price, face, par)) and math.isfinite(dur) and dur >= 0","tryCatchPattern":"try:\n    dv01 = credit_spread_dv01(dur, price, face, par)\nexcept ValueError:\n    logger.warning(\"skipping instrument with invalid dv01 inputs: price=%s face=%s par=%s\", price, face, par)\n    dv01 = 0.0","preventionTips":["Check all four args since the error message is combined","Filter out non-positive priced (defaulted) instruments before risk aggregation","Use 0.0 (not -1 or None) as the spread_duration default placeholder"],"tags":["credit","dv01","spread-duration","input-validation","python"],"backgroundTag":"argument-out-of-range","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}