William Toni ← Back to Portfolio
Document AI · Data Extraction · 2026

Factsheet Scraper

Turns unstructured PDF fund factsheets, digital or scanned, into a live Excel model that ranks what a multi-fund portfolio actually holds.

3
strategy cascade
OCR
vision fallback
Look-through
consolidated
Formula
driven output

The problem

An advisor wants to see what a client's multi-fund portfolio actually holds when you look through the funds, the real underlying exposure, and where the same company is reached through two different funds. That information lives in monthly PDF factsheets: some are clean digital text, some are scans, and the top-holdings table is laid out differently in every one. Worse, bond names embed a coupon rate (GII 3/2022 4.662%) that a naive reader will happily mistake for a portfolio weight.

What it is

An extraction pipeline that turns those PDFs into a live Excel model ranking holdings by effective contribution. It reads; it does not do arithmetic, weights are located by position and tagged in the text before the model ever sees them, so a coupon rate can never be read as an allocation.

How it works

PDF factsheetdigital or scanned1 · Tablepdfplumber columns2 · Geometryweight by x-position3 · Vision OCRPyMuPDF → imageGeminireads + tagsnever computesValidatorreject badExcellive formulas

A three-strategy cascade tries the cheapest reliable method first and falls through to vision OCR only when a PDF has no usable text layer. A failsafe validator rejects any extraction whose weights do not add up before it can reach the workbook.

What it produces

The headline output is a consolidated look-through: the same holding reached through two funds is deduplicated and its exposure combined, so concentration that hides across funds becomes visible.

Maybank Berhad20.1%held in 2 fundsTenaga Nasional Berhad16.3%held in 2 fundsCIMB Group Holdings12.3%held in 2 fundsTop Glove Corporation8.3%Digi.Com Berhad8.2%Hartalega Holdings7.1%Axiata Group Berhad7.1%Supermax Corporation6.0%IHH Healthcare Berhad5.2%
Consolidated top holdings across the sample funds, by summed weight, rendered from the project's synthetic test data

What it removed

Transcription
Reading holdings out of PDFs by hand, fund by fund, month after month, is replaced by dropping files in a folder and running one command.
Coupon error
Geometry-aware pre-tagging distinguishes a right-aligned portfolio weight from a coupon rate embedded inline in a bond name, a mistake that silently corrupts the whole table.
Bad output
A validator blocks extractions with impossible weights, missing names or an out-of-range total before they reach the workbook, rather than surfacing them as clean-looking numbers.

Honest limitations

Tools
PythonGemini 2.5 FlashpdfplumberPyMuPDFopenpyxl
Methodology
Three-strategy extraction cascadeGeometry-aware weight taggingVision OCR fallbackFailsafe validationFormula-driven workbook