{"record":{"id":"978694810bfce77c","repo":"HKUDS/Vibe-Trading","slug":"coupon-rate-must-be-a-decimal-fraction-0-05-means","errorCode":null,"errorMessage":"coupon_rate must be a decimal fraction (0.05 means 5%), got {rate!r}; a value above 1.0 is almost certainly a percentage","messagePattern":"coupon_rate must be a decimal fraction \\(0\\.05 means 5%\\), got (.+?); a value above 1\\.0 is almost certainly a percentage","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/entities/models.py","lineNumber":369,"sourceCode":"        \"\"\"Validate the base fields plus bond-specific ranges and consistency.\n\n        Raises:\n            ValueError: If ``face_value`` is non-positive, ``coupon_rate`` is\n                negative or expressed as a percentage, the coupon frequency\n                contradicts the coupon rate, or maturity precedes inception.\n        \"\"\"\n        super().__post_init__()\n        if self.face_value is not None:\n            face = float(self.face_value)\n            if face <= 0:\n                raise ValueError(f\"face_value must be positive, got {self.face_value!r}\")\n            object.__setattr__(self, \"face_value\", face)\n        if self.coupon_rate is not None:\n            rate = float(self.coupon_rate)\n            if rate < 0:\n                raise ValueError(f\"coupon_rate cannot be negative, got {rate!r}\")\n            if rate > 1.0:\n                raise ValueError(\n                    f\"coupon_rate must be a decimal fraction (0.05 means 5%), \"\n                    f\"got {rate!r}; a value above 1.0 is almost certainly a \"\n                    \"percentage\"\n                )\n            object.__setattr__(self, \"coupon_rate\", rate)\n        frequency = int(self.coupon_frequency)\n        if frequency < 0:\n            raise ValueError(\n                f\"coupon_frequency cannot be negative, got {self.coupon_frequency!r}\"\n            )\n        if self.coupon_rate and frequency == 0:\n            raise ValueError(\n                f\"coupon_frequency=0 marks a zero-coupon bond, but coupon_rate=\"\n                f\"{self.coupon_rate!r} is non-zero\"\n            )\n        object.__setattr__(self, \"coupon_frequency\", frequency)\n        if self.maturity_date is not None:\n            object.__setattr__(","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/entities/models.py#L351-L387","documentation":"Bond.__post_init__ enforces coupon_rate <= 1.0 with a decimal-fraction convention (0.05 = 5%). Values above 1.0 are assumed to be percentages mistakenly passed as-is (e.g. 5.0 meaning 5%) and are rejected.","triggerScenarios":"Bond(..., coupon_rate=5.0) meaning 5%, coupon_rate=650 for 6.5% stored as 6.5*100, or basis points passed raw. Values in [0, 1] pass; anything > 1.0 raises.","commonSituations":"Vendor feeds and spreadsheets quoting coupons in percent; users copying 'Coupon: 4.25%' values directly; mixed conventions across teams where one stores fractions and another percent.","solutions":["Divide percent values by 100 before construction (4.25 -> 0.0425)","If the source is basis points, divide by 10_000","Centralize the conversion in the ingestion layer and document the fraction convention"],"exampleFix":"# before\nBond(instrument_id='b1', coupon_rate=5.0)  # meant 5%\n\n# after\nBond(instrument_id='b1', coupon_rate=0.05)","handlingStrategy":"validation","validationCode":"cr = float(row['coupon_rate'])\nif cr > 1.0:\n    cr /= 100.0  # percent -> decimal fraction\nBond(..., coupon_rate=cr)","typeGuard":"def is_decimal_fraction(r) -> bool:\n    return r is None or 0.0 <= float(r) <= 1.0","tryCatchPattern":null,"preventionTips":["Convert percent coupons to fractions at the ingest boundary","Reject or flag coupon_rate > 1.0 during data profiling","Keep a single documented convention for all rate fields"],"tags":["python","dataclass","bond","unit-conversion","rate-validation"],"backgroundTag":"percent-vs-fraction-unit-error","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}