{
  "tool_id": "art-331-tvm-convexity",
  "note": "golden_hash is empty until first golden-parity.test.mjs --update. Same bond as art-329/art-330's fixtures (6% coupon, 5yr, semiannual, YTM 8%) so duration/DV01/convexity form a cross-checked family on one bond.",
  "vectors": [
    {
      "name": "convexity_semiannual_bullet",
      "description": "6% coupon, $1000 face, 5yr to maturity, semiannual, YTM 8%. Closed-form convexity 21.151083.",
      "policy_parameters": {
        "face_value": 1000,
        "coupon_rate_pct": 6,
        "ytm_pct": 8,
        "years_to_maturity": 5,
        "periods_per_year": 2
      },
      "output_payload": {
        "convexity": 21.151083,
        "price": 918.89,
        "face_value": 1000,
        "coupon_rate_pct": 6,
        "ytm_pct": 8,
        "years_to_maturity": 5,
        "periods_per_year": 2,
        "num_periods": 10,
        "convexity_price_adjustment_pct": null,
        "regulatory_basis": "Standard closed-form bond convexity, textbook definition (Fabozzi, Bond Markets Ch.4)",
        "note": "Convexity = sum(CF_t * t*(t+1) / (1+y)^(t+2)) / Price, annualized by dividing by periods_per_year^2. Same even-period bullet-bond schedule as compute_bond_duration/compute_dv01 (no odd first coupon / stub support, declared limitation). convexity_price_adjustment_pct only populates when yield_shock_bp is supplied (0.5 * convexity * dy^2 second-order term)."
      },
      "golden_hash": "fa5a8f6fe4d10c524d30c82dc975f6cb1ca9ca9bec739ad45426a7caaa1abd57"
    }
  ]
}
