Models / Fund terms and risk / fee_waterfall
Fee waterfall
What do the management and performance fees take from this return series, and at what return does a performance fee start?
Runs a series of gross returns through a management fee, a performance fee, a hurdle and a high-water mark, period by period. Shows net against gross, fees by kind, the mark and the drag. All numbers come from the caller. It is arithmetic on the terms sent, not a reading of any fund's documents and not a forecast.
On these numbers, a hypothetical 100,000,000 becomes 127,017,063.48 before fees and 116,287,292.81 after them over 14 periods, with 7,358,920.48 in management fees, 2,166,562.01 in performance fees and a drag of 2.67 points a year.
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.
Net NAV at the end
116,287,293
After 461,690.20 accrued and not yet paid.
Gross NAV at the end
127,017,064
The same returns with no fees.
Management fees
7,358,920
Performance fees paid
1,704,872
On 1 of 3 dates.
Performance fee accrued, not paid
watch461,690
Fee drag
2.6662points a year
Hypothetical gross 7.07% a year, net 4.41% a year.
High-water mark at the end
112,218,174
Gain on assets before the next performance fee
0%
From assets at the end to the hurdle line at the end.
What flips it
The value of one input where the outcome changes, with the others held.
flat_gross_return_pct
1.4853
At or below this flat gross return a period, no performance fee appears: it only covers the management fee and the hurdle. Above it, one does.
Flags
What went past a line, and what to read before you trust the rest.
- watchThe series ends between dates with 461,690.20 accrued and not yet paid. It can still shrink or vanish. stub_accrual
What this leaves out
What the formula leaves out, by name.
- Subscriptions and redemptions. One holder from day one, so no equalization or series accounting.
- Clawback of fees paid earlier, after a later loss.
- A hurdle that carries a missed year forward.
- Partial catch-up tiers. A soft hurdle here is a full catch-up at once.
- Expenses other than these two fees: admin, audit, financing and trading costs.
- Taxes, on the fund or on the holder.
- Rebates, fee classes and side letters.
What it took as given (9)
What it took as given to get here.
- Order each period: gross return, then management fee, then the performance fee accrual.
- The management fee is simple: the annual rate divided by periods_per_year, on opening assets before any accrued performance fee.
- An accrued fee stays in the fund until it is paid, so the return applies to assets before the accrual. Net NAV is assets less the accrual.
- An accrual can shrink or vanish before a date. Only the fee at a date is paid, and it is not returned after a later loss.
- The hurdle compounds at the annual rate: over k periods the line is mark x (1 + h)^(k / p), so one full year is exactly h.
- The hurdle restarts from the mark at every date. A missed year is not carried forward.
- The mark rises to the NAV after fees whenever that is above it, even in a period with no fee. With use_hwm false, it moves to the NAV after fees at every date, up or down.
- A series that ends between dates pays nothing for the last part. That accrual is shown apart and is inside net NAV, with the hurdle prorated.
- Fee drag is compound gross growth a year less compound net growth a year, with years = periods / periods_per_year.
- Gross NAV
- Net NAV
- High-water mark
The data
Gross against net, hypothetical
| Item | Value |
|---|---|
| Gross NAV at the end | 127,017,064 |
| Net NAV at the end | 116,287,293 |
| Gap | 10,729,771 |
| Management fees | 7,358,920 |
| Performance fees paid | 1,704,872 |
| Performance fee accrued, not paid | 461,690 |
| Compounding effect: gap less the fees | 1,204,288 |
| Gross growth a year, % | 7.0717 |
| Net growth a year, % | 4.4055 |
| Fee drag, points a year | 2.6662 |
| Gap as a share of the gross gain, % | 39.71 |
| Net NAV at the end with use_hwm false | 113,710,410 |
Fee dates
| Period | Assets before fee | Mark before | Hurdle line | Performance fee | Assets after fee | Mark after |
|---|---|---|---|---|---|---|
| 4 | 112,524,359 | 100,000,000 | 104,000,000 | 1,704,872 | 110,819,487 | 110,819,487 |
| 8 | 95,946,742 | 110,819,487 | 115,252,267 | 0 | 95,946,742 | 110,819,487 |
| 12 | 112,218,174 | 110,819,487 | 115,252,267 | 0 | 112,218,174 | 112,218,174 |
Period by period
| Period | Gross return % | Opening assets | Management fee | Assets before performance fee | Hurdle line | Accrued at the end | Paid | Net NAV | Mark | Gross NAV |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 5 | 100,000,000 | 500,000 | 104,500,000 | 100,985,341 | 702,932 | 0 | 103,797,068 | 100,000,000 | 105,000,000 |
| 2 | 3 | 104,500,000 | 522,500 | 107,112,500 | 101,980,390 | 1,026,422 | 0 | 106,086,078 | 100,000,000 | 108,150,000 |
| 3 | 4 | 107,112,500 | 535,563 | 110,861,438 | 102,985,245 | 1,575,239 | 0 | 109,286,199 | 100,000,000 | 112,476,000 |
| 4 | 2 | 110,861,438 | 554,307 | 112,524,359 | 104,000,000 | 0 | 1,704,872 | 110,819,487 | 110,819,487 | 114,725,520 |
| 5 | -6 | 110,819,487 | 554,097 | 103,616,221 | 111,911,437 | 0 | 0 | 103,616,221 | 110,819,487 | 107,841,989 |
| 6 | -5 | 103,616,221 | 518,081 | 97,917,328 | 113,014,146 | 0 | 0 | 97,917,328 | 110,819,487 | 102,449,889 |
| 7 | 1 | 97,917,328 | 489,587 | 98,406,915 | 114,127,720 | 0 | 0 | 98,406,915 | 110,819,487 | 103,474,388 |
| 8 | -2 | 98,406,915 | 492,035 | 95,946,742 | 115,252,267 | 0 | 0 | 95,946,742 | 110,819,487 | 101,404,901 |
| 9 | 6 | 95,946,742 | 479,734 | 101,223,813 | 111,911,437 | 0 | 0 | 101,223,813 | 110,819,487 | 107,489,195 |
| 10 | 5 | 101,223,813 | 506,119 | 105,778,885 | 113,014,146 | 0 | 0 | 105,778,885 | 110,819,487 | 112,863,654 |
| 11 | 4 | 105,778,885 | 528,894 | 109,481,146 | 114,127,720 | 0 | 0 | 109,481,146 | 110,819,487 | 117,378,200 |
| 12 | 3 | 109,481,146 | 547,406 | 112,218,174 | 115,252,267 | 0 | 0 | 112,218,174 | 112,218,174 | 120,899,546 |
| 13 | 2 | 112,218,174 | 561,091 | 113,901,447 | 113,323,906 | 115,508 | 0 | 113,785,939 | 112,218,174 | 123,317,537 |
| 14 | 3 | 113,901,447 | 569,507 | 116,748,983 | 114,440,532 | 461,690 | 0 | 116,287,293 | 112,218,174 | 127,017,064 |
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/fee_waterfall.md.
# Fee waterfall: 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.** What do the management and performance fees take from this return series, and at what return does a performance fee start?## MethodEach period: assets = opening x (1 + r) - opening x m / p. Hurdle line = mark x (1 + h)^(k / p), k periods since the last date. Hard fee = f x (assets - line) above the line. Soft fee = f x (assets - mark) above the line. Between dates that fee is an accrual inside net NAV. At a date it is paid, then mark = max(mark, assets after the fee). Flip: r* = m / p + (1 + h)^(1 / p) - 1.## Conventions- Order each period: gross return, then management fee, then the performance fee accrual.- The management fee is simple: the annual rate divided by periods_per_year, on opening assets before any accrued performance fee.- An accrued fee stays in the fund until it is paid, so the return applies to assets before the accrual. Net NAV is assets less the accrual.- An accrual can shrink or vanish before a date. Only the fee at a date is paid, and it is not returned after a later loss.- The hurdle compounds at the annual rate: over k periods the line is mark x (1 + h)^(k / p), so one full year is exactly h.- The hurdle restarts from the mark at every date. A missed year is not carried forward.- The mark rises to the NAV after fees whenever that is above it, even in a period with no fee. With use_hwm false, it moves to the NAV after fees at every date, up or down.- A series that ends between dates pays nothing for the last part. That accrual is shown apart and is inside net NAV, with the hurdle prorated.- Fee drag is compound gross growth a year less compound net growth a year, with years = periods / periods_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{ "nav_start": 100000000, "gross_returns_pct": [ 5, 3, 4, 2, -6, -5, 1, -2, 6, 5, 4, 3, 2, 3 ], "periods_per_year": 4, "mgmt_fee_pct_annual": 2, "perf_fee_pct": 20, "hurdle_pct_annual": 4, "hurdle_type": "hard", "crystallize_every": 4, "use_hwm": true}```Work them out with the method above. Yours should match these within 0.5%.- Net NAV at the end: 116287292.8- Gross NAV at the end: 127017063.5- Management fees: 7358920.477- Performance fees paid: 1704871.813- Performance fee accrued, not paid: 461690.1957- Fee drag: 2.666213864 points a year- High-water mark at the end: 112218174.2- Gain on assets before the next performance fee: 0 %Where the outcome flips, with the other inputs held:- flat_gross_return_pct at 1.485340655: At or below this flat gross return a period, no performance fee appears: it only covers the management fee and the hurdle. Above it, one does.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:- Subscriptions and redemptions. One holder from day one, so no equalization or series accounting.- Clawback of fees paid earlier, after a later loss.- A hurdle that carries a missed year forward.- Partial catch-up tiers. A soft hurdle here is a full catch-up at once.- Expenses other than these two fees: admin, audit, financing and trading costs.- Taxes, on the fund or on the holder.- Rebates, fee classes and side letters.## 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/fee_waterfall/prompt.md. Terms: https://hedgefund.md/termsCall 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/fee_waterfall.
curl -s https://hedgefund.md/api/v1/fee_waterfall \ -H 'content-type: application/json' \ -d '{"nav_start":100000000,"gross_returns_pct":[5,3,4,2,-6,-5,1,-2,6,5,4,3,2,3],"periods_per_year":4,"mgmt_fee_pct_annual":2,"perf_fee_pct":20,"hurdle_pct_annual":4,"hurdle_type":"hard","crystallize_every":4,"use_hwm":true}' \ | jq '{summary, flags, flips, not_modeled, inputs_hash}'The tool is fee_waterfall on https://hedgefund.md/mcp.
curl -s https://hedgefund.md/mcp \ -H 'content-type: application/json' -H 'accept: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"fee_waterfall","arguments":{"nav_start":100000000,"gross_returns_pct":[5,3,4,2,-6,-5,1,-2,6,5,4,3,2,3],"periods_per_year":4,"mgmt_fee_pct_annual":2,"perf_fee_pct":20,"hurdle_pct_annual":4,"hurdle_type":"hard","crystallize_every":4,"use_hwm":true}}}' \ | jq '.result.structuredContent | {summary, flags, flips, not_modeled, inputs_hash}'One file with no dependencies, and nothing is sent anywhere.
curl -fsSL https://hedgefund.md/hedgefund.mjs -o hedgefund.mjs # read it before you run itnode hedgefund.mjs template fee_waterfall > mine.json # replace every number in itnode hedgefund.mjs run fee_waterfall mine.json | jq '{summary, flags, flips, not_modeled, inputs_hash}'Made-up numbers that run as they stand. Replace every one.
{ "nav_start": 100000000, "gross_returns_pct": [ 5, 3, 4, 2, -6, -5, 1, -2, 6, 5, 4, 3, 2, 3 ], "periods_per_year": 4, "mgmt_fee_pct_annual": 2, "perf_fee_pct": 20, "hurdle_pct_annual": 4, "hurdle_type": "hard", "crystallize_every": 4, "use_hwm": true}Inputs
| Input | Type | Range | Required | What it is |
|---|---|---|---|---|
| nav_start | number | over 0 to 10000000000000 | yes | NAV at the start, in money. |
| gross_returns_pct | array | 1 to 240 items | yes | Gross return of each period in percent, oldest first. |
| periods_per_year | whole number | 1 to 365 | yes | Periods in a year: 12 for months, 4 for quarters. |
| mgmt_fee_pct_annual | number | 0 to 20 | yes | Management fee a year in percent. One period pays this divided by periods_per_year, on opening NAV. |
| perf_fee_pct | number | 0 to 100 | yes | Performance fee in percent of the gains it applies to. |
| hurdle_pct_annual | number | 0 to 100 | no | Hurdle a year in percent. Ignored when hurdle_type is none. |
| hurdle_type | string | none | hard | soft | no | none; hard, a fee only on gains above the hurdle line; soft, a fee on all gains above the mark once past the line. |
| crystallize_every | whole number | 1 to 240 | yes | Periods between dates when the accrued performance fee is paid. |
| use_hwm | boolean | no | true compares with the high-water mark. false compares with the NAV after fees at the last date, up or down. |
Hypothetical, and on made-up numbers until you replace them. Nobody traded this, and nothing here is on offer.