eqlx.org / eqlx-portfolio
Python library · MCP server · v0.2 · Apache-2.0
What a loan book can lose in a bad year.
Loans are judged one by one, but they fail together. eqlx-portfolio looks at all of them at once and says how much could be lost in a bad year, how much capital that takes, and which borrowers and sectors drive it. Then it says what a new loan has to earn to be worth that capital.
What goes in, what comes out
No model inside, no network. Same input, same answer.
You give
- the loans: amount, chance of default, loss if it defaults
- each borrower's sector
- how strongly borrowers move together
eqlx-portfolio computes
- thousands of possible years, good and bad
- who defaults together in each
- the total loss of every year
- or the same by formula, without simulation
You get
- the loss in an ordinary year and in a bad one
- the capital that covers the gap
- each borrower's and sector's share of the risk
- what one more loan would change
One loan book, start to finish
A made-up book of 500 borrowers. What you enter, what the tool computes, what comes back.
1You enter the book
One file of loans, one file of assumptions.
| Loans | 621 loans to 500 borrowers |
| Lent in total | 995 million |
| Sectors | 6 |
| Moving togetherinside a sector, by sector | 12 % to 24 % |
| Sectors with each other | 50 % |
2The tool plays 200,000 possible years
In most years little is lost. In a few, many borrowers fail at once. Share of years by loss:
3An ordinary year and a bad one
The average hides the bad year. Loss in millions, out of 995 lent:
4Where the risk sits
Share of the money lent, and share of the loss in the worst years.
5Who drives it
Four borrowers hold 18 % of the money and 39 % of the risk.
| Borrower | of the money | of the risk |
|---|---|---|
| B0004construction | 4.0 % | 12.7 % |
| B0003construction | 4.7 % | 10.6 % |
| B0005construction | 4.2 % | 8.8 % |
| B0001construction | 5.5 % | 7.4 % |
6One more loan of 50 million
Same loan, same expected loss (0.45 million). Extra loss in the worst years, in millions:
What comes back
Expected loss 12.7 million. Loss in the 1-in-1,000 year 91.3 million; the capital is the difference. Construction is 41 % of the money and 69 % of the risk. Every figure comes with the steps that produced it.
Two commands: eqlx-portfolio sample demo, then eqlx-portfolio run demo/loans.csv --config demo/settings.json. Every figure above is their output. The book is made up; no real borrower is behind it.
What the new loan has to earn
The loan of step 6, three years, offered at 43 %. Is that enough for the capital it ties up?
What the rate is made of
For the construction borrower, the lowest rate that still earns the bank's target return:
| Fundingwhat the bank pays for the money | 40.00 % |
| Expected lossthe average cost of defaults | 1.11 % |
| Operating cost | 1.03 % |
| Capitalthe target return on the capital tied up | 1.62 % |
| Break-even rate | 43.76 % |
Inputs: funding 40 %, target return 45 % after 30 % tax, capital earning 38 %, operating cost 1 %. All yours to set.
Four ways to count the capital
Break-even rate by where the capital figure comes from. Bars show the capital part; the other 42.14 % is the same in all four.
A formula or a risk weight prices both borrowers the same. Only the book itself can tell them apart.
The tool states the break-even rate. It does not recommend a price.
The assumption that moves everything
How much borrowers have in common changes the capital, not the average loss.
The same book, four assumptions
Expected loss is 12.7 million in all four. Capital for the 1-in-1,000 year, in millions:
The tool does not choose this number. You do, and it shows what follows.
Three ways to the same question
100 equal loans of 1 million, 2 % chance of default, 45 % lost in default, 20 % in common. Loss in the 1-in-1,000 year, in millions:
The Basel formula assumes no single loan matters. Real books are lumpier. Two methods in one tool let you question one with the other.
How an agent uses it
The agent decides what to ask. The tool computes. It reads files in one folder, writes none, sends nothing.
To connect it to Claude Code:
pip install "eqlx-portfolio[mcp]"
claude mcp add portfolio -- eqlx-portfolio mcp --root /path/to/folder
How it was tested
Against the two public documents that introduced these methods, and against arithmetic that does not share its code.
Matched to published figures
CreditMetrics Technical Document (J.P. Morgan, 1997) and CreditRisk+ (Credit Suisse First Boston, 1997). The CreditRisk+ spreadsheet rounds amounts by a rule the document does not give; the 0.2 % is that rounding.
Checked another way; no published figure exists
Found on the way
Two figures printed in the 1997 document do not follow from its own tables. The tests assert the right value and show where the printed one comes from.
The first comes from one probability printed as 0.60 % where the document's own matrix has 0.26 %.
The whole
What it does not do
pip install "eqlx-portfolio[mcp]"
eqlx-portfolio sample demo
eqlx-portfolio run demo/loans.csv --config demo/settings.json
eqlx-portfolio what-if demo/loans.csv --config demo/settings.json --new new_loan.csv
eqlx-portfolio price demo/loans.csv --config demo/settings.json --new new_loan.csv --terms terms.json