HEDGEFUND.md

Models / Credit / private_credit_tape

Private credit tape

How do this loan tape's losses and interest fall through its tranches, and how much sits under the senior at a 1% chance of impairment?

Runs a loan tape through a one-factor Gaussian copula and a senior-first waterfall. Gives each tranche's expected loss, impairment chance, 99% tail loss and coupon cover, the pool loss distribution, and the junior size that puts the senior's impairment chance at 1%. Loans, rates and default rates come from the caller. Not a rating, an offering or advice.

The paste-ready promptmodel.md

On these numbers, across 5000 hypothetical paths with seed 7 over 3 years, the pool loses 5.42% on average and 25.8% at the 99th percentile, and the senior, with 25% under it, is impaired on 1.2% of paths. A size of 25.8% under it would put that chance at 0.98%.

Hypothetical, and on made-up numbers until you replace them. Nobody traded this, and nothing here is on offer.

Readings

The numbers, with their units.

Pool expected loss

5.4195%of pool

Exact figure from the formula: 5.4168%. The gap is sampling noise.

Monte Carlo error on that

0.0842347%of pool

One standard error: stdev / sqrt(sims).

Pool loss stdev

5.9563%of pool

Pool loss, 95th percentile

17.4%of pool

Pool loss, 99th percentile

25.8%of pool

Size under the senior for a 1% chance

breach

25.8%of pool

From these draws: 0.98% of paths lie above it. About 95% sampling band for this percentile: 24.7 to 27.5.

Senior impairment chance

breach

1.2%

With 25% under it.

Mean excess interest

7.6876%of pool

Over the horizon. Reported, not used to absorb losses.

What flips it

The value of one input where the outcome changes, with the others held.

  1. junior_size_pct

    25.8

    With less than this much under the senior, more than 1% of these paths impair it.

  2. asset_correlation_pct

    16.82%now 20

    Above this correlation, more than 1% of these same paths impair the senior.

  3. default_rate_multiple

    0.891404

    Above this multiple of every loan's default rate, more than 1% of these same paths impair the senior.

Flags

What went past a line, and what to read before you trust the rest.

  • breach
    With 25% under it, the senior is impaired on 1.2% of paths. On these draws, a 1% chance sits at 25.8%. The 1% is this model's fixed reference, not a rating or a standard. senior_chance_above_one_pct

What this leaves out

What the formula leaves out, by name.

  • Prepayment, amortization and new loans. Each balance stays flat until the horizon.
  • Recovery timing. A loss is taken in full at the horizon, with no workout period.
  • Coverage triggers, cash traps and any turbo that would redirect excess interest to principal.
  • Default timing beyond the midpoint convention, and correlation that changes in stress.
  • Fat tails: the copula is Gaussian, so joint extreme defaults are thin compared with a heavier-tailed one.
  • Rate changes on floating loans, hedges, reserve accounts and fees other than servicing.
  • Secondary-market prices, liquidity and, for tokenized notes, anything about the chain, the wrapper or transfer limits.
  • Taxes.
What it took as given (9)

What it took as given to get here.

  • Draw order on each path is Z, then one e per loan in list order, from one stream seeded by the seed and the model's id. Correlation and default rates change thresholds, not draws, so moving them keeps the same paths.
  • Interest is simple. A performing loan pays balance * rate * H. A defaulted loan pays for half the horizon, as if it defaulted at the midpoint.
  • Servicing is charged on the starting pool for the whole horizon and is paid first from interest.
  • Coupons are due on each tranche's starting size for the whole horizon, even after a write-down. Interest and principal run separately: excess interest is reported and doesn't absorb losses.
  • Losses hit the most junior tranche first and are taken in full at the horizon. A loss landing exactly on an attachment point impairs nothing above it. A tranche's loss figures are percents of its own size, and pool figures are percents of the pool.
  • Coupon cover for a tranche is mean interest after servicing, over the coupons due on that tranche and everything senior to it.
  • Percentiles use linear interpolation between order statistics, except the junior size. That one is an order statistic: the smallest size with at most 1% of these paths above it, recounted from the same draws, and rounded up at the tenth digit so it still passes when sent back.
  • Correlation moves losses between tranches, but it leaves the pool's expected loss alone. The exact figure is the sum of balance * LGD * (1 - (1 - pd)^H) over the pool.
  • The sleeve is for the whole pool: gross and net are 100, tail is the 99th percentile pool loss, and carry is mean interest after servicing, per year.
Pool loss across pathsShare of paths, %
0102030024681012141618202224262830323436Pool loss, % of pool, low edge of each bin
The data

Tranches

tranchesize_pctattach_pctdetach_pctcoupon_pctexpected_loss_pctimpairment_chance_pcttail_99_loss_pctcoupon_cover_xcoupon_cover_worst_1pct_xcoupon_shortfall_chance_pct
Senior75251006.50.05891.21.06672.07921.61230
Mezzanine151025106.524919.241001.591.23290
Junior100101243.9768.721001.33811.03760.58

Interest waterfall, means over paths

itemduemean_paidmean_shortfall
Interest collected31,907,802
Servicing1,500,0001,500,0000
Senior coupon14,625,00014,625,0000
Mezzanine coupon4,500,0004,500,0000
Junior coupon3,600,0003,595,1554,845
Excess7,687,647

Largest contributors to expected loss

loanbalancedefault_chance_over_horizon_pctloss_if_defaultexpected_lossshare_of_expected_loss_pct
Loan 114,000,00022.132,600,000575,41110.62
Loan 123,000,00027.12,100,000569,10010.51
Loan 86,000,00014.263,600,000513,4509.48
Loan 96,000,00014.263,600,000513,4509.48
Loan 105,000,00016.943,000,000508,2489.38
Loan 68,000,00011.534,400,000507,1629.36
Loan 78,000,00011.534,400,000507,1629.36
Loan 410,000,0008.73275,000,000436,6358.06
Loan 120,000,0004.43288,000,000354,6276.55
Loan 58,000,0008.73274,000,000349,3086.45

Simulation

itemvalue
sims5,000
seed7
draws_per_path13
monte_carlo_error_pct0.084235
exact_expected_loss_pct5.4168
gap_in_standard_errors0.032

Hypothetical, computed from the numbers sent and any stated default, with hindsight. Nobody traded it, and costs and liquidity are only as assumed. Not a forecast, a recommendation, an offer, or a record of real trading. Don't use it to market an investment.

formula Each path draws a market factor Z and one e per loan. A loan defaults within the horizon if sqrt(rho) Z + sqrt(1 - rho) e < normInv(1 - (1 - pd)^H). Pool loss is the sum of balance * LGD over defaults. Each tranche takes min(max(loss - attach, 0), size). Interest pays servicing, then coupons senior first.

inputs_hash 3f3b554e7d08f0af

Paste it into your agent

No connection needed. This prompt carries the method, the conventions and what this site's engine gives on the made-up numbers, so your agent can check its own work before it touches real ones. Every prompt, with its hash, is listed at /prompts.json. A copy that stays fixed for this version, for a stack to point at: /v/1.0/models/private_credit_tape.md.

prompt.md
# Private credit tape: a prompt from hedgefund.mdPaste this into your AI agent. It needs no connection to hedgefund.md. An agent that can run code should write and run it, and shouldn't work a long series by hand.**Question.** How do this loan tape's losses and interest fall through its tranches, and how much sits under the senior at a 1% chance of impairment?## MethodEach path draws a market factor Z and one e per loan. A loan defaults within the horizon if sqrt(rho) Z + sqrt(1 - rho) e < normInv(1 - (1 - pd)^H). Pool loss is the sum of balance * LGD over defaults. Each tranche takes min(max(loss - attach, 0), size). Interest pays servicing, then coupons senior first.## Conventions- Draw order on each path is Z, then one e per loan in list order, from one stream seeded by the seed and the model's id. Correlation and default rates change thresholds, not draws, so moving them keeps the same paths.- Interest is simple. A performing loan pays balance * rate * H. A defaulted loan pays for half the horizon, as if it defaulted at the midpoint.- Servicing is charged on the starting pool for the whole horizon and is paid first from interest.- Coupons are due on each tranche's starting size for the whole horizon, even after a write-down. Interest and principal run separately: excess interest is reported and doesn't absorb losses.- Losses hit the most junior tranche first and are taken in full at the horizon. A loss landing exactly on an attachment point impairs nothing above it. A tranche's loss figures are percents of its own size, and pool figures are percents of the pool.- Coupon cover for a tranche is mean interest after servicing, over the coupons due on that tranche and everything senior to it.- Percentiles use linear interpolation between order statistics, except the junior size. That one is an order statistic: the smallest size with at most 1% of these paths above it, recounted from the same draws, and rounded up at the tenth digit so it still passes when sent back.- Correlation moves losses between tranches, but it leaves the pool's expected loss alone. The exact figure is the sum of balance * LGD * (1 - (1 - pd)^H) over the pool.- The sleeve is for the whole pool: gross and net are 100, tail is the 99th percentile pool loss, and carry is mean interest after servicing, per year.## Step 1: check your method on these made-up numbersThe numbers and names below are made up. They aren't market levels, typical values or anyone's real figures.```json{  "loans": [    {      "name": "Loan 1",      "balance": 20000000,      "rate_pct": 9,      "pd_annual_pct": 1.5,      "lgd_pct": 40    },    {      "name": "Loan 2",      "balance": 12000000,      "rate_pct": 10,      "pd_annual_pct": 2,      "lgd_pct": 45    },    {      "name": "Loan 3",      "balance": 10000000,      "rate_pct": 10,      "pd_annual_pct": 2,      "lgd_pct": 45    },    {      "name": "Loan 4",      "balance": 10000000,      "rate_pct": 11,      "pd_annual_pct": 3,      "lgd_pct": 50    },    {      "name": "Loan 5",      "balance": 8000000,      "rate_pct": 11,      "pd_annual_pct": 3,      "lgd_pct": 50    },    {      "name": "Loan 6",      "balance": 8000000,      "rate_pct": 12,      "pd_annual_pct": 4,      "lgd_pct": 55    },    {      "name": "Loan 7",      "balance": 8000000,      "rate_pct": 12,      "pd_annual_pct": 4,      "lgd_pct": 55    },    {      "name": "Loan 8",      "balance": 6000000,      "rate_pct": 13,      "pd_annual_pct": 5,      "lgd_pct": 60    },    {      "name": "Loan 9",      "balance": 6000000,      "rate_pct": 13,      "pd_annual_pct": 5,      "lgd_pct": 60    },    {      "name": "Loan 10",      "balance": 5000000,      "rate_pct": 14,      "pd_annual_pct": 6,      "lgd_pct": 60    },    {      "name": "Loan 11",      "balance": 4000000,      "rate_pct": 15,      "pd_annual_pct": 8,      "lgd_pct": 65    },    {      "name": "Loan 12",      "balance": 3000000,      "rate_pct": 16,      "pd_annual_pct": 10,      "lgd_pct": 70    }  ],  "tranches": [    { "name": "Senior", "size_pct": 75, "coupon_pct": 6.5 },    { "name": "Mezzanine", "size_pct": 15, "coupon_pct": 10 },    { "name": "Junior", "size_pct": 10, "coupon_pct": 12 }  ],  "asset_correlation_pct": 20,  "horizon_years": 3,  "servicing_bps": 50,  "sims": 5000,  "seed": 7}```Work them out with the method above. These values come from random paths, so yours won't match exactly: treat a gap over 10% as a problem.- Pool expected loss: 5.41948 % of pool- Monte Carlo error on that: 0.08423465796 % of pool- Pool loss stdev: 5.956289785 % of pool- Pool loss, 95th percentile: 17.4 % of pool- Pool loss, 99th percentile: 25.8 % of pool- Size under the senior for a 1% chance: 25.8 % of pool- Senior impairment chance: 1.2 %- Mean excess interest: 7.687647 % of poolWhere the outcome flips, with the other inputs held:- junior_size_pct at 25.8: With less than this much under the senior, more than 1% of these paths impair it.- asset_correlation_pct at 16.81566238: Above this correlation, more than 1% of these same paths impair the senior.- default_rate_multiple at 0.891404079: Above this multiple of every loan's default rate, more than 1% of these same paths impair the senior.If yours differ, stop and tell the person which ones and by how much. Don't go on to real numbers until they match, or until the person has seen the difference. These values come from one engine and can be wrong too.## Step 2: run it on the person's numbersReplace every input with the person's own. Ask for any number you don't have, and don't invent one.## Step 3: reportGive one sentence beginning "On these numbers,", then the values, then where the outcome flips. Always add what this leaves out:- Prepayment, amortization and new loans. Each balance stays flat until the horizon.- Recovery timing. A loss is taken in full at the horizon, with no workout period.- Coverage triggers, cash traps and any turbo that would redirect excess interest to principal.- Default timing beyond the midpoint convention, and correlation that changes in stress.- Fat tails: the copula is Gaussian, so joint extreme defaults are thin compared with a heavier-tailed one.- Rate changes on floating loans, hedges, reserve accounts and fees other than servicing.- Secondary-market prices, liquidity and, for tokenized notes, anything about the chain, the wrapper or transfer limits.- Taxes.## LimitsResults are hypothetical: arithmetic on the numbers given, prepared with hindsight. Nobody achieved them, and costs and liquidity are only as assumed. They aren't a forecast, a recommendation, an offer or a record of real trading. Don't say what to buy, sell or hold, and don't use them to market an investment. Whether a person may hold or trade an instrument is a legal question for counsel.Provided as is, at your own risk, by hedgefund.md, which is not a fund and isn't anyone's adviser. Version 1.0. Source: https://hedgefund.md/models/private_credit_tape/prompt.md. Terms: https://hedgefund.md/terms

Call it

The same code answers on this page, over HTTP, over MCP and on your own machine, and the same inputs give the same bytes. No key, and nothing is stored. Send positions by POST or run the library, because a URL can land in a server log. model.md holds all of this for your agent.

POST the inputs to /api/v1/private_credit_tape.

terminal
curl -s https://hedgefund.md/api/v1/private_credit_tape \  -H 'content-type: application/json' \  -d '{"loans":[{"name":"Loan 1","balance":20000000,"rate_pct":9,"pd_annual_pct":1.5,"lgd_pct":40},{"name":"Loan 2","balance":12000000,"rate_pct":10,"pd_annual_pct":2,"lgd_pct":45},{"name":"Loan 3","balance":10000000,"rate_pct":10,"pd_annual_pct":2,"lgd_pct":45},{"name":"Loan 4","balance":10000000,"rate_pct":11,"pd_annual_pct":3,"lgd_pct":50},{"name":"Loan 5","balance":8000000,"rate_pct":11,"pd_annual_pct":3,"lgd_pct":50},{"name":"Loan 6","balance":8000000,"rate_pct":12,"pd_annual_pct":4,"lgd_pct":55},{"name":"Loan 7","balance":8000000,"rate_pct":12,"pd_annual_pct":4,"lgd_pct":55},{"name":"Loan 8","balance":6000000,"rate_pct":13,"pd_annual_pct":5,"lgd_pct":60},{"name":"Loan 9","balance":6000000,"rate_pct":13,"pd_annual_pct":5,"lgd_pct":60},{"name":"Loan 10","balance":5000000,"rate_pct":14,"pd_annual_pct":6,"lgd_pct":60},{"name":"Loan 11","balance":4000000,"rate_pct":15,"pd_annual_pct":8,"lgd_pct":65},{"name":"Loan 12","balance":3000000,"rate_pct":16,"pd_annual_pct":10,"lgd_pct":70}],"tranches":[{"name":"Senior","size_pct":75,"coupon_pct":6.5},{"name":"Mezzanine","size_pct":15,"coupon_pct":10},{"name":"Junior","size_pct":10,"coupon_pct":12}],"asset_correlation_pct":20,"horizon_years":3,"servicing_bps":50,"sims":5000,"seed":7}' \  | jq '{summary, flags, flips, not_modeled, inputs_hash}'

Inputs

InputTypeRangeRequiredWhat it is
loansarray1 to 100 itemsyesThe loan tape. Up to 100 loans.
loans[].namestringyesA label, such as Loan 3.
loans[].balancenumber0.01 to 10000000000000yesLoan balance.
loans[].rate_pctnumber0 to 100yesInterest rate a year. 10 means 10%.
loans[].pd_annual_pctnumber0 to 100yesYearly default chance. 3 means 3%.
loans[].lgd_pctnumber0 to 100yesLoss given default, as a share of balance. 45 means 45%.
tranchesarray1 to 10 itemsyesTranches, senior first, sizes summing to 100.
tranches[].namestringyesA label, such as Senior.
tranches[].size_pctnumber0.01 to 100yesShare of the pool. 70 means 70%.
tranches[].coupon_pctnumber0 to 100yesCoupon a year on the tranche's starting size. 0 for a residual.
asset_correlation_pctnumber0 to 100yesAsset correlation rho in the one-factor copula. 20 means 20%.
horizon_yearsnumber0.25 to 30yesYears the tape runs.
servicing_bpsnumber0 to 1000noServicing fee a year on the starting pool, paid first from interest. Default 0.
simswhole number100 to 5000noMonte Carlo paths, up to 5000. Default 5000.
seedwhole number0 to 2147483647noSeed for the draws. The same seed gives the same bytes. Default 1.

Hypothetical, and on made-up numbers until you replace them. Nobody traded this, and nothing here is on offer.

1.0Use at your own risk: hedgefund.md is not a fund, not an offer of any security, token or fund interest, and not advice. Results are hypothetical, may be wrong, and are not a record of real trading. Don't use them to market an investment. See the terms.