Methodology
CarryCurve computes carry and roll-down under a static-curve assumption across four sovereign markets: UK gilts (Bank of England), US Treasuries (Treasury par yields, bootstrapped to zeros), Government of Canada bonds (Bank of Canada zero-coupon curve), and Euro-area AAA-rated government bonds (ECB). The math is identical across the four; the per-curve preprocessing and data conventions differ.
What CarryCurve computes
For a zero-coupon position of original maturity T held for time h,
CarryCurve reports the expected continuously-compounded log return under a static-curve assumption:
Total(T, h) = T · y(T) − (T − h) · y(T − h)
= h · y(T) ← carry
+ (T − h) · [y(T) − y(T − h)] ← roll-down
The sweet spot at horizon h is the tenor
T*(h) at which Total(T, h) is largest across the
displayed range. CarryCurve computes this on each currency, for four standard
horizons (1M, 3M, 6M, 1Y), every business day in that currency's calendar.
Worked example (GBP)
With T = 5y, h = 0.25y, y(5) = 4.50%, y(4.75) = 4.42%:
Carry = 0.25 · 0.0450 = 112.5 bps Rolldown = 4.75 · (0.0450 − 0.0442) = 38.0 bps Total = 5 · 0.0450 − 4.75 · 0.0442 = 150.5 bps
The USD curve uses the same math after a bootstrap step (Treasury publishes par yields, not zeros). For a fully-traced USD worked example against a real Treasury date, see USD methodology §B.3.
The four sovereign curves
CarryCurve currently covers four sovereign curves. Each has its own source, methodology, and publication cadence. The summary table below is the source of truth for methodology disclosure across the product, and the badges shown alongside each curve on the live pages map directly to it.
| Currency | Source | Curve type | Methodology tag | Cadence | Tenor range | Page |
|---|---|---|---|---|---|---|
| GBP | Bank of England | Zero-coupon spot (VRP spline) | Native | Daily, by noon UK | 0.5y → 30y (40y with Pro ultra-long) | GBP curve |
| USD | US Department of the Treasury | Par yields (CMT) bootstrapped to zeros | Bootstrapped | Daily, by 6 PM ET | 0.5y → 30y | USD curve · USD methodology |
| CAD | Bank of Canada | Zero-coupon spot (MLES spline) | Native | Weekly Thursdays, ~2-week lag | 0.25y → 30y | CAD curve · CAD methodology |
| EUR | European Central Bank | Zero-coupon spot, AAA-rated (Svensson) | Native | Daily, by noon CET | 0.25y → 30y | EUR curve · EUR methodology |
Methodology tiers — Native vs Bootstrapped
Three of the four curves (GBP, CAD, EUR) come from sources that publish a zero-coupon spot curve directly. CarryCurve reads these as-is — methodology tag: Native. One curve (USD) comes from a source that publishes a par yield curve at fixed Constant Maturity Treasury (CMT) tenors; CarryCurve bootstraps zero rates from the par yields before applying the carry/rolldown math — methodology tag: Bootstrapped.
Both produce continuously-compounded zero rates suitable for the static-curve calculation. The Bootstrapped tag signals an additional preprocessing step is performed; the resulting curve is fair under the static-curve assumption but isn't a direct read of source data. The full bootstrap procedure plus an empirical worked example are documented at /methodology/usd.
Static-curve assumption
The reported numbers are the realised return if the curve doesn't move over the horizon. In reality, curves move every day. The static figure is a baseline — useful as a relative-value reference (which point pays best if nothing else changes?), not a forecast of realised return. Over horizons longer than ~1 month, especially during regime shifts, realised returns can diverge materially from the static figure.
Linear interpolation
Each source publishes its curve on a fixed tenor grid (0.5y intervals for GBP and USD-bootstrap, 0.25y for CAD, irregular for EUR). When CarryCurve needs y(T − h) at a tenor not on the grid, it interpolates linearly between the two adjacent published nodes. The underlying curves are already smoothed by their issuer's fit (VRP for BoE, MLES for BoC, Svensson for ECB; the USD case is handled by the bootstrap pipeline), so linear residuals are small and an auditable rule is preferable to a higher-order interpolant.
Tenor range and ultra-long
Default sweet-spot range: 1y – 30y across all four currencies. For GBP only, a Pro toggle extends the range to 40y, because the 30y+ end of the gilt curve is heavily distorted by structural LDI / Solvency II demand from UK pension funds and insurers — apparent “carry” at 35–40y often reflects forced buying. The toggle includes a caveat banner. USD, CAD, and EUR all cap at 30y because their source curves don't extend further.
Historical context — 10-year percentile (Pro)
For each (currency, horizon) pair, the displayed total return is ranked against the trailing 10-year sample of daily sweet-spot total returns at the same horizon in the same currency. Today's value is excluded from the sample so the percentile is a comparison of today vs the past. Below 6 months of history the percentile is suppressed; between 6 months and 10 years, it's shown alongside “based on N business days”.
Percentiles are not pooled across currencies. A 95th-percentile reading on GBP means "high relative to GBP's last 10 years", not "high relative to a global pool". Cross-currency historical comparison would confound rate-regime and economic differences in ways a single percentile can't represent honestly.
Cross-curve ranking (Pro)
For each holding horizon, CarryCurve ranks today's sweet-spot total expected return across the four currencies. The ranking is on gross local-currency basis points — there is no FX-hedging adjustment. This view answers "which curve is paying best today" in the most literal sense; it does not answer "which carry trade is best after hedging back to my base currency", which is the FX-hedged variant on the v2.1 roadmap.
The cross-curve view shows methodology + freshness badges per row so the user can see at a glance that (e.g.) a CAD row is 10 business days old (BoC's natural lag) while the others are today's data. The bar chart visualises the magnitude of the ranking and the curve-overlay chart shows where each currency's sweet spot sits relative to its full carry-return profile.
Per-currency data freshness
CarryCurve runs four parallel refresh jobs, each tuned to its source's publication cadence:
- GBP: daily, 17:00 UTC after the BoE's noon publication. Stale threshold: 3 UK business days.
- USD: daily, 23:30 UTC after Treasury's 6 PM ET publish (1.5–2.5h buffer across DST). Stale threshold: 2 US business days.
- CAD: weekly Thursdays at 22:00 UTC. The BoC publishes its zero curve weekly with a structural two-week lag, so a "10 business days ago" freshness badge on a CAD row is normal, not an error. Stale threshold: 16 business days (sized to cover BoC's worst-case normal lag — the day before each Thursday publish — plus one business day of grace).
- EUR: daily, 13:30 UTC after the ECB's noon CET publish. Stale threshold: 3 TARGET business days.
Each currency's freshness is computed in that currency's business-day calendar (UK bank holidays for GBP, SIFMA-recommended bond holidays for USD, Bank of Canada Ontario calendar for CAD, TARGET2 for EUR). So a USD curve that's 1 US-trading-day old shows "yesterday" even on a UK bank holiday.
Data sources and attribution
All yield-curve inputs come from public central-bank or treasury data:
- Bank of England — Yield curves (GBP)
- US Department of the Treasury — Interest Rate Statistics (USD)
- Bank of Canada — Yield curves for zero-coupon bonds (CAD)
- European Central Bank — AAA spot curve (EUR)
CarryCurve consumes each source's published, fitted output as authoritative; it does not refit or re-smooth.
Disclaimer
CarryCurve is a market-data tool, not investment advice. It does not recommend trades, does not consider any user's circumstances, and does not name particular bonds. The cross-curve ranking is gross local-currency carry and is not adjusted for FX hedging cost; it is a methodology-informational view, not a buy/sell signal. Outputs are computed from public central-bank data under a documented static-curve assumption.