# Position size limits (size_position)

Desk: Fund terms and risk. Page: https://hedgefund.md/models/size_position

**What it asks.** What does each constraint allow for this position, and which one is smallest?

Shows what a Kelly fraction, a vol budget, a stop and a volume cap each allow for one position, with square-root impact and days to exit at each size. All numbers come from the caller. It states what each constraint allows on those numbers. It is not a size to take and not a view on the position.

Results are hypothetical: arithmetic on the numbers sent, a made-up template or a stated default. Nobody achieved them, and they aren't a forecast, a recommendation, an offer or a record of real trading. Don't show any output to investors or clients, or use it to market an investment. Terms: https://hedgefund.md/terms

## Inputs

| Input | Type | Range | Required | What it is |
| --- | --- | --- | --- | --- |
| `nav` | number | over 0 to 10000000000000 | yes | NAV in money. |
| `vol_pct` | number | 0 to 500 | yes | Annual vol of the position in percent. |
| `expected_return_pct` | number | -100 to 500 | yes | Expected return a year in percent, read as over the funding cost. The caller's own estimate. |
| `kelly_fraction` | number | over 0 to 2 | no | Fraction of full Kelly. 0.25 means a quarter. |
| `risk_budget_pct_nav` | number | 0 to 100 | yes | Risk budget in percent of NAV: one year's vol for the vol budget, the loss at the stop for the stop. |
| `stop_pct` | number | 0 to 100 | no | Optional stop distance in percent of the position's value. |
| `adv_value` | number | 0 to 10000000000000 | yes | Average daily traded value, in money. |
| `max_participation_pct` | number | 0 to 100 | yes | Most of the daily value to trade, in percent. |
| `days_to_build` | number | 1 to 252 | yes | Trading days allowed to build the position. |
| `impact_coeff` | number | 0 to 10 | no | Coefficient on the square-root impact. |
| `trading_days_per_year` | whole number | 200 to 366 | no | Days a year for turning annual vol into daily vol: 252, or 365 for assets that trade every day. |

## Template

Made-up numbers that run as they stand, so you can see the shape of a result. They aren't market levels, typical values or estimates, and the names in them don't exist. Replace every number before you read anything into a run.

```json
{
  "nav": 100000000,
  "vol_pct": 30,
  "expected_return_pct": 8,
  "kelly_fraction": 0.25,
  "risk_budget_pct_nav": 2,
  "stop_pct": 10,
  "adv_value": 5000000,
  "max_participation_pct": 15,
  "days_to_build": 5,
  "impact_coeff": 1
}
```

## What the template gives

On these numbers, the constraints allow from 3,750,000 to 22,222,222.22, and the smallest is the volume cap at 3.75% of NAV, with 163.66 bps of one-way impact and 5 days to exit, which is what each constraint allows, not a size to take.

- Kelly fraction allows: 22,222,222
- Vol budget allows: 6,666,667
- Stop allows: 20,000,000
- Volume cap allows: 3,750,000
- Smallest of these: 3,750,000
- Impact at the smallest, one way: 163.66 bps
- Days to exit at the smallest: 5 days

Where it flips, with the other inputs held:

- `expected_return_pct` at 1.35: Below this expected return, the Kelly fraction is the smallest limit. Above it, the volume cap is, at 3,750,000.
- `days_to_build` at 8.888888889: Below this many days, the volume cap is the smallest limit. Above it, the vol budget is, at 6,666,666.67.

## Formula

Kelly: f = mu / sigma^2, allowed = fraction x f x NAV. Vol budget: budget x NAV / sigma. Stop: budget x NAV / stop. Volume: participation x ADV x days_to_build. Impact in bps = coeff x daily vol x sqrt(size / ADV) x 10000, daily vol = sigma / sqrt(trading days). Days to exit = size / (participation x ADV). Flip: mu* = next limit / NAV x sigma^2 / fraction.

## Assumptions

- mu and sigma are annual fractions in the Kelly formula: 8% and 30% give 0.08 / 0.09 = 0.89 of NAV before the fraction.
- expected_return_pct is read as the return over the funding cost, as the Kelly formula needs. It is the caller's estimate.
- Below zero expected return, the Kelly limit is zero on this side. A short has its own expected return to send.
- The risk budget means one year of vol for the vol budget, and the loss at the stop for the stop limit.
- Daily vol is annual vol / sqrt(trading_days_per_year), 252 unless sent. Impact is one way, for the whole size traded against one day's ADV, and a round trip pays it twice.
- Each limit is figured alone, with no leverage cap. A limit over NAV means borrowed exposure, and a flag says so.
- On a tie for the smallest, the first in the order Kelly, vol budget, stop, volume is named, and the note names the others.

## Not modeled

- Correlation with the rest of the book. Each limit sees this one position alone.
- Gaps through a stop. The stop limit assumes the exit is at the stop.
- Error in the estimates. Kelly moves one for one with expected return and with the inverse square of vol.
- Financing, borrow, margin, taxes and fees.
- How impact builds and decays over days, or the effect of showing the trade.
- A fall in ADV when the position needs to exit.

## Call it

Every result has the same fields: summary, readings, tables, charts, flags, flips, formula, assumptions, not_modeled, hypothetical and inputs_hash. Read flags, flips and not_modeled with the summary, and pass them along together.

### HTTP

No key. The tools keep nothing you send. Send positions by POST, because a URL can land in a server log.

```bash
curl -s https://hedgefund.md/api/v1/size_position \
  -H 'content-type: application/json' \
  -d '{"nav":100000000,"vol_pct":30,"expected_return_pct":8,"kelly_fraction":0.25,"risk_budget_pct_nav":2,"stop_pct":10,"adv_value":5000000,"max_participation_pct":15,"days_to_build":5,"impact_coeff":1}' \
  | jq '{summary, flags, flips, not_modeled, inputs_hash}'
```

### MCP

The tool is `size_position` on the server at https://hedgefund.md/mcp.

```bash
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":"size_position","arguments":{"nav":100000000,"vol_pct":30,"expected_return_pct":8,"kelly_fraction":0.25,"risk_budget_pct_nav":2,"stop_pct":10,"adv_value":5000000,"max_participation_pct":15,"days_to_build":5,"impact_coeff":1}}}' \
  | jq '.result.structuredContent | {summary, flags, flips, not_modeled, inputs_hash}'
```

### The library

The same code on your own machine, with no dependencies, and nothing is sent anywhere.

```bash
curl -fsSL https://hedgefund.md/hedgefund.mjs -o hedgefund.mjs   # read it before you run it
node hedgefund.mjs template size_position > mine.json           # replace every number in it
node hedgefund.mjs run size_position mine.json | jq '{summary, flags, flips, not_modeled, inputs_hash}'
```

In a script:

```js
import { run, template } from "./hedgefund.mjs";

const inputs = template("size_position"); // replace every number in it
const { summary, flags, flips, not_modeled } = run("size_position", inputs);
```
