03
Legends Advocates
Administrative and executive support
- Assisted with business registration and initial company setup.
- Handled branding and digital operations.
Writing • Projects • Curriculum Vitae • About
§ 01
Indefinitely NEET. Almost everything I am working on is on this website. Contact me for more information, or to discuss opportunities.
I thoroughly enjoy the process of an idea growing into an executable plan, and ultimately results.
§ 02
01
Founder and Developer
Developing a student-focused events platform for discovering and managing university societies, social events and parties, with an emphasis on secure user verification, payments and location-based functionality.
02
Data analysis and modelling
Categorising 205,551 active West Midlands companies to shortlist about 1,500 for a GVA led regional growth programme.
Research paper · October 2026
Using only free official data, 146,095 of 205,551 active West Midlands companies were sized or classified, identifying 12,417 firms with 8–300 staff. The remaining 59,456, mostly companies yet to file accounts, were ranked by their likelihood of having staff.
A regional growth company needed about 1,500 West Midlands firms with roughly 10–250 staff to approach with consultancy aimed at raising gross value added (GVA). No public dataset gives headcount for every company, so we built one from the employee note that UK companies must include in their annual accounts.
We read the machine-readable (iXBRL) accounts of every listed company from Companies House bulk files, downloading only the parts needed (about 1–1.5 GB instead of about 31 GB). For the 6,656 companies that file on paper or as PDFs, we retrieved 6,295 scanned documents through the Companies House API and read them with optical character recognition (OCR), rebuilding tables from word positions. For companies that have not yet filed accounts, we matched four free registers (company ownership, the Home Office visa sponsor list, the Care Quality Commission and Food Standards Agency hygiene ratings) and trained a model on 38,454 young West Midlands firms to estimate each one's chance of having 8 or more staff.
Of 205,551 active companies, 146,095 were sized or classified and 12,417 fall in the 8–300 band; 1,737 of these came from scanned accounts. After corrections, 36 of 37 hand-verified scanned figures were right. A regression test of the electronic reader exposed a scale defect in 9,560 figures; correcting it brought 1,751 more firms into the band, and 8 of 8 sampled corrections matched their accounts. The model separates firms well (AUC 0.83; 17.3% predicted against 15.6% actual in its top decile). It expects about 1,729 of the 59,456 unsized firms to have 8 or more staff, and about 268 of them sit in a prioritised list of 2,471 new firms. A growth-forecast model to choose the final 1,500 is specified and pre-registered.
The aim is a target list of about 1,500 firms with 8–300 staff (10–250 at the core), drawn from all 205,551 active companies registered in the West Midlands. The client is a regional quasi-public growth company that consults with firms to raise gross GVA, so firms are not excluded for serving local markets.
Headcount is the deciding filter, and it is hard to get at scale:
This paper describes how each form was handled, the problems met and how they were fixed, how accuracy was checked, and what the resulting dataset shows. The selection of the final 1,500 and the growth projections follow in a separate section.
Every input is free and official, so the whole dataset can be rebuilt and checked by anyone.
| Source | What it provides | Scale used | As at |
|---|---|---|---|
| Companies House accounts data (monthly and daily) | Machine-readable accounts, including the average number of employees | 13 monthly files (≈31 GB) plus 10 daily files; 152,781 filings read | Sep 2025 – 14 Oct 2026 |
| Companies House historic accounts data | Older accounts for firms with no recent electronic filing | 20 monthly files; 10,266 filings read | Jan 2024 – Aug 2025 |
| Companies House basic company data | Accounts type, industry (SIC) codes, status, incorporation date, registered charges | All 205,551 listed companies matched | 1 Oct 2026 |
| Companies House public data API (free key) | Each company's filing history and accounts documents | 6,656 companies; 6,295 scanned PDFs | Oct 2026 |
| Persons with significant control (PSC) snapshot | Who owns each company: people and parent companies | 16.05 million records; 198,570 listed firms with owners | 15 Oct 2026 |
| Home Office register of licensed sponsors | Employers licensed to recruit workers from abroad | 143,220 employers; 5,396 matched | 15 Oct 2026 |
| Care Quality Commission care directory | Registered care services, care-home beds, provider company numbers | 57,098 active locations; 1,471 companies matched | 1 Oct 2026 |
| Food Standards Agency hygiene ratings | Food businesses trading from premises | 24,514 businesses in 7 councils; 7,534 companies matched | 14 Oct 2026 |
Three other routes were assessed and rejected:
Each company went through up to four stages, from the cheapest and most reliable source to the hardest, and only the companies still unresolved moved on to the next stage. One program carries out every stage (section 3.1); section 3.6 shows how its output was verified, and section 3.7 sets out the growth-forecast model built on it.
Every stage is carried out by one program, kept in a private Git repository (wm-growth-model) so that any figure in this paper can be rebuilt from free public files. It has two halves: data collectors written in Node.js 24 with Windows PowerShell, and a forecasting package in Python 3.12 (section 3.7).
| Component | Language | What it does |
|---|---|---|
extract_facts.mjs, lib/xbrl_facts.mjs, lib/remote_zip.mjs | Node.js | Reads Companies House bulk accounts zips remotely and turns each iXBRL or XBRL filing into dated facts (section 3.2) |
extract_employees.mjs | Node.js | The original staff-only reader used for the 15 Oct 2026 run, kept as the regression baseline |
ch_docs.mjs | Node.js | Fetches the latest accounts of paper and PDF filers through the Companies House API |
ocr_pdf.ps1, ocr_runner.mjs, ocr_extract.mjs | PowerShell, Node.js | Renders scanned pages, runs Windows OCR in parallel, and extracts the staff note (section 3.4) |
psc.mjs, signals.mjs, free_sources.mjs | Node.js | Ownership links, visa-sponsor, CQC and food-premises matching |
combine.mjs, rank_noaccounts.mjs, make_zip.mjs | Node.js | Joins the register, classifies every company, ranks the unsized ones and writes the CSV outputs |
regress_employees.mjs, patch_cache.mjs, rebuild_csvs.sh, compare_outputs.mjs | Node.js, Bash | Regression testing, targeted re-reading and before-and-after comparison of outputs (section 3.6) |
model/ | Python | The growth-forecast model: panel, labels, models, calibration, backtests and selection (in build) |
Five design rules apply throughout:
About three-quarters of UK accounts are filed as inline XBRL (iXBRL): web pages in which every figure is tagged with a concept, a reporting period and a unit. Companies House publishes them in monthly zip archives of 1.6–4.1 GB, and in daily files kept for 60 days.
Remote access. A zip file's index (its central directory) sits at the end of the file. The reader fetches the last 64 KB with an HTTP range request and finds the end-of-directory record. For files over 4 GiB it follows the ZIP64 locator. It then downloads only the index, about 20–50 MB per monthly file.
Each entry's name carries the company number and balance-sheet date, for example Prod224_2512_09564242_20250430.html. Entries are then read in one of two ways:
Entries are decompressed (DEFLATE) and parsed in parallel worker threads.
Fact model. Each filing is reduced to numeric facts. A fact is a concept, a context, a unit, a value and a stated precision.
Value rules. The displayed text is converted by its stated format:
The value is then the displayed number × 10scale, negated when the sign attribute is "−". Facts marked nil are dropped, and a repeated concept–context pair is kept once.
Staff figure. The legal disclosure is the average number of employees (Companies Act 2006, s.411). It is resolved by seven rules, in order:
AverageNumberEmployeesDuringPeriod, or its older UK GAAP equivalents.EntityDormantTruefalse = true) or a "Dormant Company Accounts" title, and classed as having no staff.Other facts and fields.
Availability date. A filing in a monthly file counts as public from the 1st of the following month, and one in a daily file from the next day. This conservative rule is what lets the forecasting panel replay any past date without seeing later filings (section 3.7).
Coverage and speed.
Each company's latest accounts were joined to the Companies House register snapshot. This adds accounts type, industry codes, incorporation date, status and registered charges, and assigns a result: a size band, dormant, or unknown with a reason. Every figure carries its source and a confidence level.
For the 6,656 companies with no electronic accounts since January 2024, the Companies House API supplied each one's latest accounts: 6,295 scanned PDFs, 123 electronic documents and 238 with no usable document. The scans are images with no text layer, so they were read with the OCR engine built into Windows, which needed no extra software.
Companies less than about 21 months old have not yet filed accounts, so no headcount exists for them. Instead they were ranked using free signals and a statistical model, and linked to any established firm under the same ownership (section 7).
The new reader was tested against the old one before any output changed. The test exposed a scale defect that had dropped 1,751 firms out of the 8–300 band. The affected filings were re-read and every output rebuilt, which moved the band from 10,673 to 12,417 firms.
Unit tests. Sixteen synthetic filings each isolate one case:
They contain no real company data and run on every change.
Regression test. The 14 Oct 2026 daily file (9,977 filings) was re-parsed with the new reader. Each of its 382 West Midlands filings was compared with the published figure, and every difference was classified:
| Outcome | Filings | What the source document shows |
|---|---|---|
| Identical figure | 314 | — |
| Negative-scale correction | 33 | Tags read "5", "14", "2" with scale −2; the old reader gave 0.05, 0.14, 0.02 |
| Dormant accounts the old reader missed | 35 | Titled "Dormant Company Accounts" and flagged dormant; already classed dormant from the register |
| Unexplained | 0 | — |
Scope of the defect. The old figures held 9,466 fractional headcounts. They start in filings from about August 2025, which points to a change in one software package. A real 100, 200 or 300 would have shown as a whole 1, 2 or 3, so every such figure from July 2025 on was re-read as well. In all, 75,937 filings across 26 bulk files were re-read, with no errors.
Result. 9,563 figures changed:
Check. Eight corrected firms were drawn at random with a fixed seed. All eight matched the employee note in their accounts: 14, 96, 27, 24, 20, 272, 8 and 9 staff.
Rebuild. The original merge steps were re-run on corrected copies of the stored figures: register join, ownership and sponsor signals, the ranking model, the final CSVs and the zip.
The 1,500 firms are chosen by each firm's forecast chance of hitting a size-based growth target over the next 12 months. The design below was fixed before any model results were seen, so it can be tested honestly. It is being built in stages, and an extra component is kept only if it beats simpler rules on years the model never saw.
Success test. Let B be the firm's financial year ending between 16 Oct 2026 and 15 Oct 2027, and T the year after it. Both are annual averages, so comparing T with B measures growth over a window that, across firms, is centred on the next 12 months (±6 months). For any one firm the horizon runs from about a year (October year-ends) to about 2.5 years (September year-ends), and the outcomes are known only by mid-2029.
With n the average staff in B, the target rate is:
A firm hits its target if either route is met:
The remaining outcomes are classed as follows:
Sensitivity variants are fixed in advance:
Point-in-time panel. The unit is a company in a financial year, drawn from every UK electronic filer from January 2017 to October 2026. Prior-year comparatives extend this back to financial years 2015–16. The national scope matters because the region alone has too few larger firms to learn from: only 77 West Midlands companies have 251–300 staff.
Snapshots are taken as of 15 April and 15 October each year. Each one uses only what was public before its date:
For the remaining fields:
Inputs.
| Family | Inputs |
|---|---|
| Size and history | Headcount; staff trend over 1–5 years; acceleration; volatility; distance below a past peak; years of history; firm age. The trend is smoothed with a one-sided Kalman filter, whose noise variance is estimated from restated comparatives |
| Finance | Real turnover growth, margins, and pay and revenue per head where published. Net assets; cash and current ratios; gearing; growth in debtors, creditors and fixed assets; intangibles; dividends |
| Filing signals | Moving up an accounts category, first audit, going-concern wording, late filing, year-end changes, time since the latest accounts |
| Events since the latest accounts | Share allotments, new charges, director appointments, ownership changes, office moves, public contracts, grants |
| Ownership and management | Group size, parent location, investor backing, board size and tenure, all rebuilt as of each date from dated officer and owner records |
| Place and economy | Industry section and division; council area; deprivation; local cluster density; lagged sector and area employment growth; wage-floor exposure; energy intensity; debt × Bank Rate; automotive and tariff exposure |
Directors' sex, nationality and age are excluded.
Models. The models compete as a tournament:
Selection.
Firms with 8–9 staff also need dated evidence of growth: one hard item or two soft ones.
Gross GVA is operating profit plus staff costs plus depreciation and amortisation, where published. Otherwise it is staff × West Midlands GVA per job for the sector, adjusted for the firm's pay.
Validation.
The primary pass marks are:
Secondary checks are reported with Benjamini–Hochberg correction:
If the model fails, the best simple rule that passes is used, and the report says so.
Most of the work went into problems that only showed up once real filings were read. Each fix was tested on the documents that exposed it before being applied to the whole set.
| Area | Challenge | Solution | Effect |
|---|---|---|---|
| Scale | 205,551 companies, far too many to look up one by one | Read the whole register's bulk accounts files instead | Every listed company covered |
| Scale | Monthly files of 2–4 GB (about 31 GB in total) | Read each zip's index remotely and fetch only the needed entries | About 1–1.5 GB transferred |
| Coverage | Thirteen months of filings missed firms whose latest accounts came earlier | Second pass over Jan 2024 – Aug 2025 for unresolved firms only | About 5,800 more figures |
| Coverage | The register snapshot lagged recent filings | Added daily files; dormant accounts filed in October override the register | About 225 firms correctly reclassed as dormant |
| Formats | 6,656 firms file on paper or as PDFs | Fetched each one's latest accounts through the free API, within its 600-requests-per-5-minutes limit | 6,295 scans retrieved, 0 errors |
| Formats | The public website's "accounts" filter returned other forms (10 of 20 in a pilot) | Used the API's accounts category and accounts form type instead | Correct documents every time |
| Formats | Every paper filing is an image-only scan | OCR built into Windows, so nothing to install | All 6,295 read |
| Speed | OCR takes about 2.4 seconds a page | Started reading mid-document and stopped at the note; up to 13 parallel workers; full re-reads only where needed | The whole PDF stage took about 4.5–5 hours instead of days |
| OCR | Look-alike characters: l, I and | for 1; O for 0; "IO" for 10; "ml" for nil; "vas" for was | Look-alike rules in the number reader | Figures recovered instead of lost |
| OCR | OCR separates table labels from their numbers | Rebuilt rows and columns from word positions | Tables readable |
| Parsing | Date headings ("28 December", "52 weeks ended") read as staff numbers | Skip date and period rows | Example: 474 staff, first read as 52 |
| Parsing | Page numbers and legal boilerplate ("section 1072 of the Companies Act") read as figures | Boilerplate filter; ignore numbers inside long prose lines | Example: 0 staff, first read as 1,072 |
| Parsing | Group accounts saying "the Company has no employees" beside the group's staff table | Prefer the group figure, which describes the business | Examples: 145, 219 and 583 staff, first read as 0 |
| Parsing | "No employees whose pay exceeded £60,000" mistaken for "no employees" | Treat pay-band sentences separately | False zeros removed |
| Parsing | From about August 2025 some software tags headcounts with a scale of −2, so the original reader turned 14 staff into 0.14 | Ignore a negative scale on headcounts; re-read every fractional figure, and every 1, 2 or 3 from July 2025 on (75,937 filings) | 9,560 figures corrected; 1,751 firms restored to the 8–300 band |
| Parsing | A few filings tag the year heading ("2025") as the headcount | Reject a whole number equal to the period's year unless another staff figure in the filing supports it; fall back to the note text | Example: 1 employee, first read as 2,025 (20.25 before the scale fix) |
| Matching | Food-premises matches picked up other businesses at the same address (a pharmacy inside a supermarket) | Excluded chain names, limited address matches to food sectors | Matched firms fell from 8,932 to 7,534 |
| Matching | Shared ownership could chain unrelated firms into giant groups | Ignored owners of more than 25 companies (formation agents, nominees); direct links only | Largest group: 14 firms |
| Data integrity | 4 of the 33 ownership files arrived corrupted | Checked each file's integrity and downloaded again | Complete ownership data |
| Hardware | Processor at 100% and memory short at peak | Worker count sized to the machine; kept awake through the run | Stable to completion |
Accuracy was checked by eye against the source documents at every stage. After the final corrections, 36 of 37 verified figures (97%) match the accounts, up from 26 of 31 before them.
| Check | Sample | Result |
|---|---|---|
| Electronic accounts parser, first test | 300 filings | 285 gave a figure; the other 15 were dormant or had no employee note |
| Current-year vs prior-year figure | 3 filings read in full | Current-year figure picked every time |
| New electronic reader against the published figures | 382 West Midlands filings in the 14 Oct 2026 daily file | 314 identical; 33 scale corrections and 35 missed dormant filings, both confirmed in the documents; 0 unexplained |
| Scale correction | 8 corrected firms drawn at random | 8 of 8 match the employee note in their accounts |
| OCR pilot, before the full run | 20 scanned accounts | 18 correct; the other 2 had no employee note. Table figures confirmed against page images |
| Spot check after the full run | 15 scans, 5 per confidence level, checked against page images | High 4/5, medium 5/5, low 1/5. The errors led to the five parsing fixes in section 4 |
| Re-check after the fixes | 37 documents verified by eye | 36 correct; the remaining one is flagged low confidence for manual review |
| Low-confidence OCR figures | All 6,295 scans | Fell from 115 to 47; all are on a manual check list |
| Ranking model | 7,772 firms held back from training | AUC 0.83. In the top decile, 17.3% predicted vs 15.6% actual (rerun after the scale correction) |
| Visa sponsor matches | 12 sampled | Matches confirmed by town were correct; name-only matches marked medium confidence |
| CQC and food-premises matches | 5–10 per match type | Name-and-postcode matches correct; same-premises matches tightened after a false match |
Two safeguards apply to the output itself:
12,417 companies fall in the 8–300 band, about 6% of the active register. 146,095 companies (71%) were sized or classified; most of the rest are too new to have filed accounts.
Within the band, 10,017 sit in the core 10–250 range, 2,323 have 8–9 staff and 77 have 251–300. These counts include the 1,751 firms restored by the scale correction (section 3.6).
Where the staff figures came from:
| Source of the figure | All firms with a figure | Firms in the 8–300 band |
|---|---|---|
| Electronic accounts (tagged figure) | 122,592 | 10,672 |
| Scanned accounts read by OCR | 4,864 | 1,737 |
| Electronic accounts fetched through the API | 93 | 8 |
| Electronic accounts (figure read from text) | 5 | 0 |
The scanned accounts matter more than their number suggests. They make up 4% of figures but 14% of the band, largely because PDF filers lean towards fuller accounts formats (full, group, medium, small and subsidiary accounts make up 3,885 of the 6,656). Of the 1,737 in-band figures read from scans, 1,224 are high confidence, 491 medium and 22 low.
59,456 companies have no staff figure. 57,671 of them are simply too new: first accounts are due 21 months after incorporation, and as of 1 October 2026 none of these had filed any. The rest are 1,431 scanned accounts with no employee note, 238 with no accounts document, 87 electronic accounts that omit the figure, and 29 unresolved.
They can't be counted, but they can be ranked. Of 38,454 West Midlands firms set up in 2022–24 that have since filed accounts, 3.3% have 8 or more staff. That rate varies sharply by sector: about 15% for restaurants and takeaways and for care homes, 8–11% for home care, cleaning and recruitment, and under 2% in 22 of the 52 sectors with at least 50 young firms.
Each company was matched against free signals that point to real staff:
A logistic regression with 73 features was trained on the 38,454 young firms to estimate each unsized company's chance of having 8 or more staff.
| Group | Companies | What to do |
|---|---|---|
| Linked by ownership to an established firm with 8+ staff | 2,149 (1,455 groups) | Approach through the established firm |
| Very likely to have 8+ staff (40% chance or more) | 99 | Check by hand, then approach |
| Likely (15–40%) | 663 | Check by hand |
| Possible (5–15%) | 7,223 | Wait for first accounts |
| Unlikely (under 5%) | 49,322 | Wait for first accounts |
Summing the probabilities, the model expects about 1,729 of the 59,456 to have 8 or more staff. Most of them can't be singled out yet; they are spread thinly across thousands of low-probability firms.
A prioritised supplementary list of 2,471 new firms (1,953 of them ownership-linked) should hold about 268 with 8 or more staff. That's a hit rate of about 11%, against 2.7% for new firms overall.
The new firms are not the core of the target list, but ignoring them would systematically miss the newest businesses. About 10,800 of them must file first accounts by March 2027, and a monthly re-run will replace these estimates with real counts as they do.
The figures are as good as the accounts behind them, and eight limits apply:
A review of the forecast design on 16 October 2026, before any model code was written, found 17 weaknesses. Four could have broken the result; each is now built into the design in section 3.7 and in the model configuration. The four decisions the review left open were taken the same day and are recorded here so they can be revisited.
Decisions taken on 16 October 2026
| Question | Decision | Reason |
|---|---|---|
| Which measure is primary? | The staff-route hit rate, P(staff hit). The either-route measure, P(hit), is reported as a flagged estimate. | Companies House reform (software-only filing and a profit-and-loss account for small and micro companies, both reported for 1 April 2027, the P&L part still described as a proposal) makes turnover observable for most small firms part-way through the target years. No training year had that, so an either-route probability would be mis-calibrated by design. |
| Does acquisitive growth count? | No. Jobs and turnover gained by buying a company are deducted where the acquired firm is a UK filer; otherwise the case is left out of scoring. Acquisitions found only through filing events are flagged and counted, not deducted. | The programme supports organic growth, and buying a West Midlands firm relabels regional GVA rather than adding to it. |
| GVA tie-break or equality duty? | Keep the expected-GVA tie-break within probability tiers, and give every council area at least 75% of its pool-proportional places. | The client's aim is gross GVA. The floor stops the tie-break emptying deprived areas and low-pay sectors from the list; the cost in expected hits is reported. |
| Which reform dates to plan on? | 1 April 2027 for both software-only filing and small-company P&L filing, as a planning assumption. | The earliest reported dates are the worst case for calibration. The modelling choice above is the same whichever date holds. The dates have not yet been checked against the Companies House announcement. |
What the review changed
| Finding | Change |
|---|---|
| The label measures growth 1 to 2.5 years out, not the next 12 months, and outcomes land in 2029 | The horizon is stated in the success test and shown per firm; an interim check of the base-year nowcast is due in October 2027 |
| Headcount noise at 8 to 19 staff is as large as the target | Noise is also measured from firms with two independent readings of one year (a scanned filing and an electronic one); the 8 to 9 evidence rule is the main defence |
| Acquisitions are invisible in small-company accounts | Filing events act as detectors; see the decision above |
| Six usable training vintages, about one at the first test origin | Accounts are collected from 2010 for all sizes; only three of the six add-ons are tested in v1 |
| The two lockbox origins share target years | They are pooled into one test; the pass mark is a higher point estimate, and development needs +2 points |
| Sector economic sensitivity rests on about six observations | About eight sector groups, shrunk toward one national value; the overlay never changes the ranking |
| Sizes read from scanned accounts at medium or low confidence | Such firms go to the reserves, not the top 1,500 |
| Odd-length periods on the staff route | The 50 to 54 week rule applies to both routes |
| Sector code taken from the current register leaks the future | Sector history comes from dated confirmation statements |
| No hiring, premises or insolvency signals | Charges satisfied, Gazette notices and sector history join the first API pass; careers pages, EPC certificates and planning applications are piloted on 200 firms |
| Timeline | An accounts-only v1 ships if the schedule slips; that is decided in advance |
Status. The success test, the no-leakage rule and the selection logic are now code (model/labels.py, model/asof.py, model/select.py), with tests that pin the rate curve, the +2 rule, the 49/50 boundary, deflation, closure and late outcomes, the leakage canary, quota apportionment, one entry per group and the area floor. Since then the rest of the pipeline has been written and tested on synthetic data: the filing-events and accounts-history collectors, the OCR reader for both years and the money items, the economic data collector with publication dates on every value, the panel that joins them per firm per as-of date, and the model stage (benchmarks, the transparent challenger, the LightGBM main model, calibration, the tournament with its pass marks, reasons, the forecast and the selection). Nothing has yet run on real data: the first step is a 100-firm pilot of the collectors, then full collection, then pre-registration of the pass marks before any backtest.
§ 03
03
Administrative and executive support
02
Catering and event operations
01
Sole operator
A small e-commerce venture run end to end.
§ 04
01
GCSEs: 2024 / A Levels: 2026
§ 05
01
Founder and President
Founded the school's Finance Society and led it as President, setting up a forum for students interested in markets, economics and business.
02
Volunteer
03
Volunteer
§ 06
§ 07
Places I have been, and roughly when. Meeting people whose backgrounds look nothing like mine has taught me more than most things have.
Hover a marked country to see when I was there.
§ 08
The quickest way to reach me is email. I read everything, and I reply to most things.
[email protected]