Sai Aryan Goswami

FINBLUROCK, Mutual fund portfolio analytics, from CAS PDF to XIRR


Mutual fund portfolio analytics, from CAS PDF to XIRR

Drop in the statement your fund house already sends you. It works out your real annualised return and flags the exact rupee amount you are quietly paying in commission for holding the wrong plan of a fund you already own.

Year
2026
Domain
fintech
Stack
Next.js, TypeScript, PostgreSQL, Prisma

Before

Consolidated Account Statement, as extracted

1099384756

folio number

a commission compounding quietly for years

1099384756 / 0    HDFC MID-CAP OPPORTUNITIES FUND - GROWTH PLAN
(Advisor: ARN-00845) Registrar : CAMS  Opening Unit Bal: 0.000
02-Apr-2021 Purchase 25,000.00 24,750.00 78.4521 315.4900 315.490
11-Jul-2021 Purchase 25,000.00 24,750.00 84.1120 294.2500 609.740
04-Oct-2021 Purchase 25,000.00 24,750.00 91.7734 269.7300 879.470
***  Nominee 1: NOT REGISTERED  ***  STT Paid 0.00
9871220034 / 0    AXIS BLUECHIP FUND - REGULAR PLAN - GROWTH
(Advisor: ARN-00845) Registrar : KFINTECH  Opening Unit Bal: 0.000
18-Jan-2022 Purchase 50,000.00 49,500.00 47.2210 1048.24 1048.240
22-Mar-2023 Redemption (12,000.00) 51.8830 (231.290) 816.950
***  KYC: OK  ***  PAN: ABCDE1234F  ***  Mode: JOINT

After

the parser

18.42%

XIRR, converged

a number on screen, and an XIRR that converges

XIRR
18.42%
Invested
4,80,000
Current value
7,12,940
Plan held
Regular
Direct exists
Yes, same fund
Trail paid to date
41,600

The problem

An Indian retail investor's mutual fund holdings are usually spread across several fund houses and two registrars. The one document that shows all of it in one place is the Consolidated Account Statement, and it arrives as a password-protected PDF built to be read by a person rather than parsed by a program.

So the first question any portfolio analytics tool has to answer is not analytical at all. It is whether you can reliably get the data out.

The second question is the one that actually costs investors money. A holding in a regular plan pays a trail commission to a distributor for as long as it is held. The direct plan of the same fund, same manager, same underlying portfolio, does not. Most investors do not know which one they hold, and the difference compounds quietly for years.

FinBlurock is a mutual fund portfolio analytics MVP built for a wealth management client, aimed at both of those questions.

CAS as the ingestion path

Choosing the CAS as the way in is the decision the rest of the product rests on.

The alternative was account aggregator APIs or per-registrar integrations. Those give cleaner data and take far longer to ship: commercial agreements, onboarding, and a separate set of quirks per provider. A CAS is available to every investor today, requires no integration with anyone, and the user already knows how to request one.

The cost is that you inherit a parsing problem.

Why there is only one parser

The parsing is built on casparser (v1.3.0) rather than a custom layout-aware extractor.

This is worth stating plainly because the obvious assumption is wrong. You would expect CAMS and KFintech, the two registrars, to need separate parsers producing separate shapes that then have to be reconciled. They do not. The CAS is a standardised cross-RTA format, so one library handles statements from both without branching.

That single fact removes what would otherwise have been the largest and least interesting chunk of work in the project, and it is the reason ingestion stopped being the bottleneck early enough for the analysis to get attention.

Using a maintained library here rather than writing a parser is the correct call for the same reason writing the XIRR was: parsing a standardised format is a solved problem with an actively maintained solution, and the returns calculation was not.

A dependency-free XIRR

Returns on a fund holding are irregular by nature. Money goes in on arbitrary dates in arbitrary amounts, SIPs and lump sums mixed together, sometimes partially redeemed along the way. A simple percentage return is meaningless against that cash flow. The correct measure is XIRR, the annualised internal rate of return for irregularly timed flows.

XIRR has no closed-form solution. It is found numerically, by iterating on a discount rate until the net present value of the cash flows reaches zero.

I wrote it from scratch, with no dependency.

Why not import one

The available options split into two unattractive groups. Some pull in a heavy numerical stack to provide a single function. The rest do not converge reliably on the cash flow shapes that actually show up in Indian retail portfolios: irregular intervals, partial redemptions, and mixed positive and negative flows in the same series.

That second problem is the real one. A returns figure that silently fails to converge on a subset of portfolios is worse than no figure at all, because nothing about the output tells you which portfolios were affected.

Newton-Raphson, with bisection underneath

The implementation runs Newton-Raphson with a bisection fallback.

Newton-Raphson is fast and converges quickly on well-behaved cash flows, which is most of them. It can also diverge on certain shapes, and when it diverges it does so unhelpfully rather than obviously.

Bisection is slower and cannot fail. It is guaranteed to converge on a bracketed root, so it catches every case Newton-Raphson walks away from.

Running the fast method first and falling back to the guaranteed one is the whole design. It gives Newton-Raphson's speed on the common path and bisection's guarantee on the tail, which for a financial calculation shown to an investor is the property that actually matters. A returns number that is correct 97 percent of the time is not a returns number.

What the analysis flags

Parsing and XIRR are table stakes. The output that changes behaviour is narrower, and in v1 it is deliberately narrow.

Regular versus direct plan detection, derived from the scheme name and the advisor ARN fields in the CAS itself. This turns an invisible recurring cost into a number on a screen.

AMC-level and single-fund concentration, computed directly from CAS data. Portfolios assembled one fund at a time drift into accidental concentration, and the most common form is simply too much of the portfolio sitting with one asset management company.

What v1 does not do

Category and sector-weight analysis, the look-through layer that would catch several funds holding substantially the same underlying stocks, is not in v1. It needs a holdings data source that is not the CAS, and that source is not wired in yet. It is the v2 layer.

Stating that plainly matters more than it might seem. Concentration analysis that claims to look through funds but only compares fund names would be a worse product than one that says exactly what it measures.

Decisions and trade-offs

CAS over aggregator APIs. Lower data fidelity, dramatically faster to a working product, and no dependency on anyone else's commercial timeline. Correct for an MVP whose job was to reach an investor demo.

A maintained parser, a hand-written XIRR. These look like opposite decisions and follow from the same rule: import the solved problem, own the one where correctness at the edges is the product.

The intake screen shipped before the results screen did. This is the trade-off I am least comfortable with, so it belongs in the open. The engine is real and working, CAS parsing, XIRR, plan detection, concentration flagging, and there is now a live screen to drop a CAS PDF into and run it. What is still ahead is the other half of the same problem: turning what the engine finds into something an investor looks at, rather than something an API returns. For a product whose entire value proposition is making an invisible cost visible, that reveal is still the more important surface to finish.

Outcome

Built toward an investor demo. The response was positive, and it is still early. There is meaningfully more work between this and a full product than between nothing and this.

What I would keep from it is the discipline about scope: an MVP that measures two things correctly and says so is more defensible than one that gestures at six. The v1 concentration layer is narrower than the pitch would like, and being straightforward about that boundary is what makes the numbers it does produce worth trusting.