{"record":{"id":"a5fb16e6e87f3f76","repo":"HKUDS/Vibe-Trading","slug":"spread-bps-must-be-non-negative-got-spread-bps","errorCode":null,"errorMessage":"spread_bps must be non-negative, got {spread_bps}","messagePattern":"spread_bps must be non-negative, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/credit.py","lineNumber":802,"sourceCode":"            * ``protection_leg_pv`` (float): Present value of default protection per dollar notional.\n            * ``premium_leg_pv`` (float): Present value of fixed running premium per dollar notional.\n            * ``par_spread_bps`` (float): Model par spread in basis points.\n            * ``upfront_pct`` (float): Upfront payment as decimal fraction of notional.\n            * ``upfront_amount`` (float): Net upfront cash payment (positive = buyer pays seller).\n            * ``buyer_mtm`` (float): Mark-to-market value for the protection buyer.\n\n    Raises:\n        ValueError: If spread_bps < 0, recovery_rate not in [0, 1), tenor_years <= 0, or notional <= 0.\n    \"\"\"\n    spread_bps = _require_finite(spread_bps, \"spread_bps\")\n    recovery_rate = _require_finite(recovery_rate, \"recovery_rate\")\n    tenor_years = _require_finite(tenor_years, \"tenor_years\")\n    risk_free_rate = _require_finite(risk_free_rate, \"risk_free_rate\")\n    coupon_bps = _require_finite(coupon_bps, \"coupon_bps\")\n    notional = _require_finite(notional, \"notional\")\n    payment_frequency = _require_finite(payment_frequency, \"payment_frequency\")\n    if spread_bps < 0.0:\n        raise ValueError(f\"spread_bps must be non-negative, got {spread_bps}\")\n    if not (0.0 <= recovery_rate < 1.0):\n        raise ValueError(f\"recovery_rate must be in [0.0, 1.0), got {recovery_rate}\")\n    if tenor_years <= 0.0:\n        raise ValueError(f\"tenor_years must be strictly positive, got {tenor_years}\")\n    if notional <= 0.0:\n        raise ValueError(f\"notional must be strictly positive, got {notional}\")\n    if payment_frequency <= 0:\n        raise ValueError(f\"payment_frequency must be positive, got {payment_frequency}\")\n\n    s_dec = spread_bps / 10_000.0\n    c_dec = coupon_bps / 10_000.0\n    lgd = 1.0 - recovery_rate\n\n    # Implied hazard rate lambda ≈ s / LGD\n    lambda_hazard = float(s_dec / lgd) if lgd > 0 else 0.0\n\n    n_periods = max(1, int(round(tenor_years * payment_frequency)))\n    t_grid = np.linspace(tenor_years / n_periods, tenor_years, n_periods)","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/credit.py#L784-L820","documentation":"cds_price prices a credit default swap from its par spread; a negative spread would imply the protection buyer is paid to buy protection, which is economically invalid in this model. The function rejects negative spreads before computing the hazard rate approximation s/LGD.","triggerScenarios":"Calling cds_price(spread_bps=-100, ...) or with any negative spread value in basis points.","commonSituations":"Sign errors when computing spreads from bond prices; passing a decimal (e.g. -0.01) or a percentage where bps are expected; data glitches in market feed pipelines producing negative quotes.","solutions":["Verify the sign of your spread input; use abs() only if the sign flip is a known data convention","Confirm the unit is basis points (250 = 2.5%), not decimal or percent","Sanitize market data feeds to clamp or flag negative spreads"],"exampleFix":"# before\npv = cds_price(spread_bps=-250, tenor_years=5)\n\n# after\npv = cds_price(spread_bps=250, tenor_years=5)","handlingStrategy":"validation","validationCode":"if spread_bps < 0.0:\n    spread_bps = abs(spread_bps)  # or raise/log\npv = cds_price(spread_bps, tenor_years=5.0)","typeGuard":"def is_valid_spread_bps(s: float) -> bool:\n    return isinstance(s, (int, float)) and math.isfinite(s) and float(s) >= 0.0","tryCatchPattern":"try:\n    pv = cds_price(spread, 5.0)\nexcept ValueError as e:\n    logger.error(\"cds_price rejected spread %s: %s\", spread, e)\n    pv = None","preventionTips":["Sanitize market feeds: flag negative spreads as data errors","Keep spreads in bps consistently; document units at API boundaries","Add contract checks in ingestion that spread >= 0"],"tags":["cds","credit-default-swap","spread","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"}