How to chart bond duration and convexity
Quick answer
Chart duration and convexity by repricing the bond across a range of yields and plotting three series on the same axes: the true price-yield curve, the straight line implied by modified duration, and the parabola implied by duration plus convexity. The gap between the line and the curve is what convexity measures, and it widens with the square of the yield move. Take both numbers by bumping the yield in your own pricing function rather than from a closed form, so the tangent is guaranteed to touch the curve you drew.
Reprice the bond at every yield you want to show, then draw three series on the same axes: the prices you just computed, the straight line that modified duration implies, and the curve that duration plus convexity implies. The first is the truth, the second is the approximation most risk reporting runs on, and the distance between them is the entire subject of the chart.
Everything else on this page is about the choices that decide whether that distance looks trivial or alarming. On the same bond, it can honestly look like either.
What the chart shows, and why it is worth publishing
A price-yield chart is one bond's price plotted against its own yield to maturity. It slopes down, because a higher yield discounts the same cash flows harder. It bends, because each further rise in yield does slightly less damage than the one before. Duration is the slope at today's yield. Convexity is the bend.
The reason to publish the picture rather than the two numbers is that a duration of 8.2 means very little to a reader on its own, while a straight line visibly pulling away from a curve at 100 basis points tells them exactly where the number they have been quoted stops working. Client letters and risk appendices quote duration constantly. Very few of them show the point at which it fails.
This is a single-bond chart. It answers a different question from a Treasury yield curve, which is a cross-section of many maturities on one day, and from a credit spread series, which is a difference between two yields through time. Put the three together in a fixed income pack and they answer where rates are, what the market charges for risk, and what a 1 percent move would do to the thing you hold.
Reprice the bond, do not interpolate it
Start from the pricing function, not from the chart. Price at yield y is the sum of every cash flow discounted at y, with the coupon frequency and the discounting frequency matched. Semiannual coupons mean a semiannual yield and semiannual periods. Get that wrong and every point is wrong by a consistent amount, which is the worst kind of error, because the shape still looks right.
Then choose the yield grid and evaluate the pricer at every point on it. Do not price three yields and interpolate between them. Interpolating a curve with a straight line is precisely the error this chart exists to expose, so building it that way would hide its own subject. A few hundred evaluations is cheap and gives a curve that stays smooth at any print size.
Take duration and convexity from the same pricer
Modified duration and convexity both have closed forms, and both come with compounding conventions that have to match the way you priced. The route that avoids the mismatch, and that keeps working later, is to get both numbers numerically from the pricing function you already wrote.
Effective duration is the price at a yield one bump lower, minus the price at a yield one bump higher, divided by twice the starting price times the bump. Effective convexity is the two bumped prices added together, minus twice the starting price, divided by the starting price times the bump squared. A bump of one basis point is a sensible default.
Two reasons to prefer this. The tangent is guaranteed to touch the curve you drew, because both came out of the same function, so you never publish a chart where the straight line visibly misses the curve at today's yield. And the method survives contact with a callable bond or a mortgage pass-through, where the cash flows themselves move when the yield moves and the textbook formulas quietly stop applying.
A worked example on a ten-year bond at par
The figures below are arithmetic on a hypothetical bond rather than market quotations, so they are exact and reproducible rather than current. Take a ten-year bond paying a 4 percent coupon semiannually, priced at a yield of 4 percent. It prices at 100.000.
Bumping the yield one basis point either way gives an effective duration of 8.1757 years and an effective convexity of 78.898. The closed forms agree: Macaulay duration 8.3392 years, modified duration 8.1757, convexity 78.898. Agreement to four decimal places on a plain bond is a check worth running once, because it proves the bump size and the pricer are consistent before you trust the same method on a bond where no closed form exists.
Now move the yield. At 25 basis points higher the bond is worth 97.9805 and the duration line says 97.9561, short by about two and a half cents per hundred of face. Nobody would see that on a chart and nobody should care.
At 100 basis points higher the true price is 92.2054 and the duration line says 91.8243, short by 0.3811. Adding the convexity term lands at 92.2188, over by 0.0134, so the second-order correction removes roughly 96 percent of the error.
At 300 basis points higher the duration line says 75.4729 against a true price of 78.6814, short by 3.2086 points. The duration and convexity parabola reaches 79.0233, over by 0.3419. Even the corrected estimate is visibly off at that distance, which is itself worth showing.
Two features of that sequence belong in the caption. The duration line is short in every row, in both directions: for a bond with no embedded option it always understates the price, so a risk figure built on duration alone is conservative in a sell-off and too gloomy in a rally. And the error is not symmetric. At 100 basis points the miss is 0.3811 when yields rise and 0.4086 when they fall, because the curve is steeper on the left.
The yield range you choose is the argument you are making
One decision changes what this chart appears to prove, and it is the width of the x-axis. Plot plus or minus 25 basis points and the straight line and the curve are indistinguishable, and the reader concludes duration is fine. Plot plus or minus 300 and they are obviously different animals, and the reader concludes duration is dangerous. Both charts are honest. Both are of the same bond.
So pick the range from the move you want the reader to reason about, and say what it is. A rate-decision chart and a stress-test chart are not the same chart, and a reader who cannot see the axis range cannot tell which one they are looking at.
Maturity does the same work. The same exercise on a two-year 4 percent bond gives a duration of 1.9039 and a convexity of 4.620, and a 100 basis point rise leaves the duration line short by 0.0229, which no reader would notice. On a thirty-year the duration is 17.3805, the convexity is 420.813, and the identical move leaves the line short by 1.9261 points. Across those three bonds convexity rises at roughly the square of duration, which is why this chart earns its place in a long-duration portfolio and barely justifies itself at the front end.
Plot the error, not only the lines
Three series on one set of axes is a crowded picture, and the crowding hides the finding. The version that reads better puts the price-yield curve and the two approximations on top, and a second panel underneath showing the approximation error in price points or in basis points of price, with zero as a reference line.
The error panel is where 25 basis points and 300 basis points stop looking alike. It also makes the asymmetry visible as a shape rather than as a sentence, in the same way an underwater drawdown curve turns a single worst-case number into something a reader can sit with.
Where the closed forms stop and this method keeps going
Convexity is positive for any bond without an embedded option, which is why the curve always sits above its own tangent. Callable bonds and mortgage pass-throughs can be negatively convex across part of their yield range, because the borrower's option to refinance caps the price on a rally. Over that stretch the curve bends the other way and the duration line sits above it rather than below.
Those securities need a model that reprices the embedded option at each yield rather than a discounted cash flow sum, and a chart drawn without one will be wrong in exactly the region a reader cares about. The bump-and-reprice method carries over unchanged the moment the pricer does, which is the practical reason to build the chart that way from the start. Fabozzi's Handbook of Fixed Income Securities is the standard reference for the option-adjusted treatment.
Building it in Quadesto
Point Quadesto at a cash flow schedule and a yield, and the chart is the reprice-and-bump routine above rather than a formula pasted from a textbook: the curve comes from the pricer, the tangent and the parabola come from bumping that same pricer, and the error panel is generated from the difference rather than maintained by hand.
[QUADESTO-EMBED: price-yield curve for a 10y 4% semiannual bond at a 4% yield, with the modified-duration tangent and the duration-plus-convexity parabola overlaid, a yield range slider from plus or minus 25bp to plus or minus 300bp, and a lower panel plotting the approximation error of both estimates in price points]
The interactive version is the point here, because the yield range is the argument and a reader who can drag it can see for themselves where duration stops being good enough. Charts published from Quadesto embed on your own site the same way the yield curve chart does, and can be exported as a static image when the destination will not take a frame. Start on the free tier and see whether the error panel changes how your duration numbers get read.