{"record":{"id":"381c1154d87dab28","repo":"HKUDS/Vibe-Trading","slug":"notional-must-be-strictly-positive-got-notional","errorCode":null,"errorMessage":"notional must be strictly positive, got {notional}","messagePattern":"notional must be strictly positive, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/credit.py","lineNumber":808,"sourceCode":"\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)\n    t_prev = np.r_[0.0, t_grid[:-1]]\n    dts = t_grid - t_prev\n    t_mid = 0.5 * (t_prev + t_grid)\n\n    # Survival probabilities Q(t) = exp(-lambda * t)\n    q_grid = np.exp(-lambda_hazard * t_grid)","sourceCodeStart":790,"sourceCodeEnd":826,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/credit.py#L790-L826","documentation":"cds_price scales all premium and protection cash flows by notional, so the notional must be strictly positive. Zero or negative notionals would produce meaningless (zero or sign-flipped) mark-to-market values and usually indicate an input bug.","triggerScenarios":"Calling cds_price with notional = 0.0 or a negative amount, or forgetting the argument and having it default incorrectly in your wrapper code.","commonSituations":"Zero-initialized notional from an upstream struct; sign conventions from internal booking systems that represent seller-side as negative; passing notional in thousands/millions inconsistently.","solutions":["Pass a positive notional in the same units you want the result (e.g. 10_000_000.0)","Fix upstream trade records that store zero or negative notionals","If direction matters, price with abs(notional) and flip the sign of the resulting MTM yourself"],"exampleFix":"# before\npv = cds_price(250, 5.0, notional=-10_000_000)\n\n# after\npv = cds_price(250, 5.0, notional=10_000_000)","handlingStrategy":"validation","validationCode":"if notional <= 0.0:\n    notional = abs(notional)  # normalize booked shorts\npv = cds_price(250.0, tenor_years=5.0, notional=notional)","typeGuard":"def is_valid_notional(n: float) -> bool:\n    return math.isfinite(n) and n > 0.0","tryCatchPattern":"try:\n    pv = cds_price(250.0, tenor_years=5.0, notional=notional)\nexcept ValueError as e:\n    logger.error(\"invalid notional %s: %s\", notional, e)\n    pv = 0.0","preventionTips":["Validate trade records at ingestion: notional > 0","Handle sell-side direction by flipping the MTM sign, not the notional","Use named arguments (notional=...) to avoid positional mixups with tenor"],"tags":["cds","notional","credit","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"}