Available Hire Me
← All Writing Fixed Income

Building the UK Gilt Analytics Engine — from DMO Data to Post-Tax Yields

Building a UK gilt analytics engine — sourcing the DMO universe, pricing clean and dirty, computing gross and post-tax yields, and generating a daily report.

A daily report that prices every UK gilt — 104 instruments in issue, each with clean and dirty prices, accrued interest, gross yield, net yields across four income tax bands, curve and OIS spreads, duration, DV01 and a holding-period return model — is a data engineering problem wearing a finance costume. The finance is the easy half: the formulas are standard. The engineering is in the data sourcing, the settlement-date handling, the edge cases, and the output that survives being shared. This post is the design of the engine behind the UK Gilt Daily Report.

The universe

The source of truth for “what gilts exist” is the UK Debt Management Office (DMO). The engine starts from the DMO’s list of gilt issues and enriches it with market data — the price, yield and spread quotes that turn an instrument list into a market view. The current universe is 104 gilts: the report prices all 104, and the “not calculated” count — zero on a normal day — is a deliberate, visible signal for the instruments the engine could not price (a suspended quote, a missing input), rather than a silent omission.

Gilts split into two families that price differently: conventional gilts (fixed coupon, priced off the nominal yield curve) and index-linked gilts (coupon and redemption linked to RPI, priced off the real yield curve). The report renders them as separate views for exactly this reason — mixing them on one curve is a category error.

Pricing: clean, dirty, and the settlement maze

The market quotes a gilt clean — without the interest accrued since the last coupon. The cash you actually pay is the dirty price:

dirty = clean + accrued interest

Accrued interest is the coupon prorated to the settlement date: for the 0 3/8% Treasury Gilt 2026 trading at clean 99.48 with an accrual of 0.127, the dirty price is 99.61. Simple — until you realise the accrued interest depends on which settlement date you pick. Betfair-style, the gilt market trades T+1, T+2 and T+3, and the accrued interest differs across them. The engine computes the yield for all three settlement dates, which is why the report’s settlement selector switches the gross yield between 3.43% (T+1), 3.49% (T+2) and 3.67% (T+3) for the same bond on the same day. The settlement maze — ex-dividend dates, next-coupon dates, weekends — is where most amateur pricing models quietly go wrong, because the yield genuinely is a function of settlement.

Gross yield, the DMO convention

Yield-to-maturity is the standardised number that makes bonds comparable, and the engine follows the DMO’s yield convention so its numbers line up with the official ones. For every gilt it computes:

  • Gross yield — the yield-to-maturity ignoring tax.
  • Running yield — coupon divided by clean price: for the 0 3/8% gilt, 0.38% running against a 3.43% gross yield — the gap is the redemption uplift, because the bond trades below par.
  • Modified duration and DV01 — 0.17 years and 0.0017 for the ultra-short gilt; the same two numbers on a 50-year index-linked are what risk desks actually manage by.

The tax model

Gilts are special in UK tax: coupon interest is taxable income, but capital gains on gilts are exempt — the report’s header carries the bands as 0% / 20% / 40% / 45% / 0%, the trailing zero being the CGT rate. That split means the same gilt has five different yields depending on who holds it, and it is the engine’s post-tax model — net yield per band plus a tax-equivalent yield — that turns a bond list into something a real investor can act on. The ranking shifts between bands are the interesting output: the 0 3/8% gilt is rank 70 for a 0% taxpayer and rank 54 for a 40% taxpayer, because the tax burden on a low-coupon gilt is smaller. I covered the band model and the numbers in the follow-up post on gross vs post-tax yields.

Relative value: curve, benchmark and OIS

Yield alone does not tell you whether a gilt is cheap. The engine computes relative value against three references:

  • Curve spread — the gilt’s yield against the fitted nominal yield curve at the same maturity: -57.7 bps means the gilt trades 57.7 bps through its curve point.
  • Benchmark spread — against the nearest benchmark gilt, with the divergence count in the header (3 on the sample day) flagging gilts whose price no longer tracks their benchmark — usually the first sign of a special or a funding squeeze.
  • OIS spread — the gilt yield against the SONIA overnight index swap curve, the closest thing to a risk-free rate. A widening OIS spread is the classic signal of gilt-specific stress rather than curve movement.

Holding-period return — the model that answers “what would I actually make?”

Price-to-yield is theory; the holding-period return model is the practical check. For a chosen holding period it computes consideration, accrued interest paid, maturity income, capital gain or loss, total costs, and the net return — for the 0 3/8% gilt: £99,475 consideration, £525 capital gain, £428.60 net return on the modelled period. The effective rate and implied rate pair is the engine being honest about what that return is worth after costs.

The output

Every engine eventually has to ship its numbers. The report is generated as a single self-contained HTML file — no server, no database, no external assets beyond a pinned, hash-verified Chart.js — so each day’s output is a permanent, shareable artifact with the calculation version (1.3 on the sample) stamped in the header. The daily snapshot doubles as the development log of the engine itself, and the archive is how the report evolves visibly over time — the whole pipeline is covered in shipping a daily report pipeline.

The engine is deliberately boring in the places finance people glamorise — the formulas are textbook — and demanding in the places that actually break: settlement dates, tax treatment, and outputs that must be correct and shareable. If you’re building fixed-income tooling and want the tax and settlement maze handled properly, have a chat.

Samuel Jackson

Samuel Jackson

Senior Java Back End Developer & Contractor

Senior Java Back End Developer — Betfair Exchange API specialist, Spring Boot, AWS, and event-driven architecture. 25+ years delivering high-performance systems across betting, finance, energy, retail, and government. Available for Java contracting.