← Atlas

Project Record

Debt Note Bond Extraction

PDF debt-note extraction and Markit bond matching—linking ISIN-level disclosures in filings to issuer reference data and quarterly financials.

Domains
Hedge FundCreditDocuments
Capability
Market Data Engineering
Methods
NlpRegex ExtractionEntity MatchingData Ingestion

Executive Summary

Credit analysts working through quarterly and annual filings often need bond-level detail—ISINs, coupons, maturities, issue sizes—that does not always appear cleanly in market reference feeds. Debt-note sections in issuer PDFs carry that information, but the text is unstructured, inconsistently formatted, and hard to reconcile against vendor bond universes.

I built a pipeline that isolated debt-note disclosures from PDF filings, extracted bond-level fields with a mix of natural language processing and regex tuned to classical bond notation, and matched the results against Markit’s issuer and instrument coverage. The system surfaced cases where filings contained bonds Markit did not list, where vendor records were incomplete, and where reported financials could be tied back to specific ISINs. That gave the desk a richer debt picture than standard market data alone.

This demonstrates document extraction for fixed-income research, probabilistic entity matching against reference data, and end-to-end linkage from unstructured filings to structured bond and financial records.

Problem

Debt-note tables in PDF filings are semi-structured at best: ISINs may appear inline with issue names, coupon rates use mixed decimal conventions, and maturity dates are written in several formats. Markit provides strong bond and issuer reference coverage, but it is not always complete or current for every name in a credit book—especially private or thinly followed issuers.

We need a system that (1) locates and extracts the debt-note section from a filing PDF, (2) parses bond-level attributes from noisy text, (3) normalizes identifiers and notation to a common schema, (4) matches extracted records to Markit instruments and issuers, and (5) flags gaps where filings and vendor data disagree.

Extraction Pipeline

Let DD be the raw text extracted from a filing PDF. The pipeline first isolates the debt-note block SDS \subset D using section-heading heuristics (e.g. “Notes to the financial statements”, “Borrowings”, “Debt securities”) and layout cues from the upstream PDF parser.

Within SS, each candidate bond mention bjb_j is parsed into a tuple:

bj=(isinj,  cj,  mj,  nj,  namej)b_j = (\text{isin}_j,\; c_j,\; m_j,\; n_j,\; \text{name}_j)

where cjc_j is coupon, mjm_j maturity, njn_j notional or face value, and namej\text{name}_j is the issue label. Extraction combines:

  1. ISIN regex — strict 12-character alphanumeric pattern with check-digit validation where possible.
  2. Bond notation regex — coupon and maturity patterns common in fixed-income tables (e.g. 5.25% 2028, FRN 2031, €500m).
  3. NLP span tagging — context windows around currency symbols, “senior”, “secured”, and issuer legal names to recover fields when table structure breaks across lines.

Normalized output records invalid or partial tuples for review rather than silently dropping them.

Matching Rule

Let MM be the Markit reference set of instruments indexed by ISIN, and E={b1,,bk}E = \{b_1, \ldots, b_k\} the extracted bond set for a filing. Matching proceeds in stages:

Stage 1 — ISIN join. For each bjb_j with valid isinj\text{isin}_j, look up M(isinj)M(\text{isin}_j). A direct hit assigns confidence wj=1w_j = 1.

Stage 2 — Fuzzy attribute match. When ISIN is missing or unmatched, generate candidates CjMC_j \subset M blocked by issuer legal name and currency, then score:

score(bj,m)=α1[isin match]+βsim(namej,m.name)+γ1[cjm.c<ϵc]+δ1[mjm.m<ϵm]\text{score}(b_j, m) = \alpha \cdot \mathbb{1}[\text{isin match}] + \beta \cdot \text{sim}(\text{name}_j, m.\text{name}) + \gamma \cdot \mathbb{1}[|c_j - m.c| < \epsilon_c] + \delta \cdot \mathbb{1}[|m_j - m.m| < \epsilon_m]

where sim\text{sim} is string similarity (e.g. Jaro–Winkler) and ϵc\epsilon_c, ϵm\epsilon_m are tolerance bands on coupon and maturity. Assign bjb_j to argmaxmCjscore(bj,m)\arg\max_{m \in C_j} \text{score}(b_j, m) when the score exceeds threshold τ\tau; otherwise route to manual review.

Stage 3 — Coverage diff. Unmatched extracted bonds and unmatched Markit instruments for the same issuer form a symmetric diff—surfacing bonds disclosed in filings but absent from Markit, and Markit listings with no filing mention in the current period.

Implementation

Trade-offs

PDF layout variance is the main failure mode—multi-column tables, footnote breaks, and scanned pages degrade extraction accuracy. Regex handles classical bond notation well but breaks on non-standard labels or embedded footnotes. Markit coverage is strong for liquid names but incomplete for private issuers; the filing often becomes the authoritative source in those cases, not the vendor feed. Fuzzy matching improves recall but can conflate similar tranches from the same issuer if coupon and maturity are close; ISIN extraction quality is therefore the highest-leverage field. Human review on provisional matches is intentional—the goal is analyst-grade linkage, not fully unattended ingestion at any cost.

Related Work