{"record":{"id":"7e50b7ed353860f3","repo":"HKUDS/Vibe-Trading","slug":"payment-frequency-must-be-positive-got-payment-f","errorCode":null,"errorMessage":"payment_frequency must be positive, got {payment_frequency}","messagePattern":"payment_frequency must be positive, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/credit.py","lineNumber":810,"sourceCode":"        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)\n    q_prev = np.r_[1.0, q_grid[:-1]]\n","sourceCodeStart":792,"sourceCodeEnd":828,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/credit.py#L792-L828","documentation":"cds_price builds a premium schedule with payments every 1/payment_frequency years, so payment_frequency must be a positive integer-like number (e.g. 4 for quarterly). Zero or negative frequencies make the step size invalid and would break or never terminate the payment loop.","triggerScenarios":"Calling cds_price with payment_frequency = 0, a negative number, or accidentally passing the period length in years (0.25) instead of the count per year (4).","commonSituations":"Confusing frequency (payments per year) with period length (years between payments); passing 0.25 for quarterly and hitting the <= 0 check only for zero, but typically hitting it with 0 from a default int.","solutions":["Pass payments per year: 1=annual, 2=semi, 4=quarterly, 12=monthly","If you have a period length dt, use payment_frequency = 1/dt rounded to int","Validate the value is a positive int in your wrapper before calling"],"exampleFix":"# before\npv = cds_price(250, 5.0, payment_frequency=0)\n\n# after\npv = cds_price(250, 5.0, payment_frequency=4)","handlingStrategy":"validation","validationCode":"payment_frequency = int(round(1.0 / period_years)) if period_years else 4\nassert payment_frequency > 0\npv = cds_price(250.0, tenor_years=5.0, payment_frequency=payment_frequency)","typeGuard":"def is_valid_payment_frequency(f: float) -> bool:\n    return isinstance(f, (int, float)) and float(f) > 0 and float(f).is_integer()","tryCatchPattern":"try:\n    pv = cds_price(250.0, 5.0, payment_frequency=freq)\nexcept ValueError as e:\n    if 'payment_frequency' in str(e):\n        pv = cds_price(250.0, 5.0, payment_frequency=4)  # default quarterly\n    else:\n        raise","preventionTips":["Pass an int count (4 = quarterly), never a period length","Validate that config-specified frequencies are positive integers","Document the unit (payments per year) at every call site"],"tags":["cds","payment-frequency","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"}