# Basis carry (basis_carry)

Desk: Digital assets. Page: https://hedgefund.md/models/basis_carry

**What it asks.** What does this long spot, short derivative position net after costs, and how far can the price rise before the short is liquidated?

Computes a long spot, short derivative position: annualized basis, net carry after fees and financing, the price rise that liquidates the short, extra margin needed at larger rises, and the funding where net carry is zero. Prices, funding and rates come from the caller. Funding can turn negative. Not a quote, a forecast or advice.

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 |
| --- | --- | --- | --- | --- |
| `instrument` | string | perp \| dated | yes | The short leg: a perpetual with funding, or a future with an expiry. |
| `spot_price` | number | 0.000001 to 1000000000 | yes | Spot price. |
| `derivative_price` | number | 0.000001 to 1000000000 | yes | Price of the short leg at entry. |
| `funding_bps_per_8h` | number | -1000 to 1000 | no | Perp only, and required for it. Funding a short receives per 8 hours, in basis points. Negative means the short pays. |
| `days_to_expiry` | number | 0.01 to 3650 | no | Dated only, and required for it. Calendar days to expiry. |
| `notional` | number | 0.01 to 10000000000000 | yes | Size of the short leg at the derivative price. |
| `short_leverage` | number | 0.01 to 200 | yes | Notional over posted collateral on the short leg. 4 means 4 times. |
| `maintenance_margin_pct` | number | 0 to 100 | yes | Maintenance margin as a share of the short's value at the current price. |
| `fees_bps_round_trip` | number | 0 to 1000 | yes | All entry and exit costs on both legs, in basis points of notional, charged once. |
| `borrow_rate_pct` | number | 0 to 200 | no | Yearly rate on any financed spot. 8 means 8%. Default 0. |
| `financed_share_pct` | number | 0 to 100 | no | Share of the spot cost that is borrowed. Default 0. |
| `collateral_haircut_pct` | number | 0 to 100 | no | Haircut on the posted collateral. Default 0. |
| `holding_days` | number | 0.01 to 3650 | yes | Calendar days the position stays on. |

## 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
{
  "instrument": "perp",
  "spot_price": 1000,
  "derivative_price": 1002,
  "funding_bps_per_8h": 1,
  "notional": 1000000,
  "short_leverage": 4,
  "maintenance_margin_pct": 2,
  "fees_bps_round_trip": 12,
  "borrow_rate_pct": 8,
  "financed_share_pct": 50,
  "collateral_haircut_pct": 15,
  "holding_days": 90
}
```

## What the template gives

On these numbers, the perp position shows an annualized basis of 10.95%, a hypothetical net of 15,956.67 over 90 days after fees and financing, and a price rise of 18.87% from entry liquidates the short.

- Annualized basis: 10.95%
- Gross carry: 27,000
- Fees and financing: 11,043.33
- Hypothetical net carry: 15,956.67
- Hypothetical net carry on capital, annualized: 8.6399%
- Liquidation price: 1,191.1
- Rise to liquidation: 18.87% (watch)

Where it flips, with the other inputs held:

- `funding_bps_per_8h` at 0.4090121128: Net carry is zero at this funding, held flat. Below it, including anywhere negative, the position loses after costs.
- `holding_days` at 6.294926777: It takes this many days of carry to earn back the fees. A shorter stay loses after costs.
- `collateral_haircut_pct` at 53.5: At this haircut the rise to liquidation is half of the 18.87% it is now.
- `short_leverage` at 42.5: At this leverage the short starts at maintenance, with no room for any rise.

## Formula

Q = notional / F. Annualized basis: perp = funding * 3 * 365, dated = (F/S - 1) * 365 / days. Gross carry: perp = notional * funding * 3 * days, dated = Q (F - S) * days / days to expiry. Net = gross - fees - Q S * financed share * rate * days / 365. Collateral C = notional / leverage * (1 - haircut). Liquidation where C - Q (P - F) = m Q P, so P = (C/Q + F) / (1 + m).

## Assumptions

- The position is long Q of spot and short Q of the derivative, where Q = notional / F, so the two legs match in quantity, not in money.
- Funding is the caller's number, held flat for the whole period, paid three times a day on the entry notional. It can turn negative.
- A perp has no expiry, so its entry premium isn't counted as carry. It only pays if it closes by exit, and it's shown as a note.
- A dated future converges at expiry. A shorter stay takes a straight-line share of the basis.
- Fees are charged once, in full, whatever the holding period. Financing is simple interest on Q S * financed share over a 365-day year.
- Collateral keeps its value as the price moves: a haircut is taken once, and the collateral doesn't rise with the underlying. Maintenance margin is measured at the current price.
- Extra margin at a rise is the cash top-up that restores equity to maintenance: max(0, m Q P + Q (P - F) - C). Cash takes no haircut. The spot leg's gain isn't counted, because it's not margin until it's sold or pledged.
- Capital used is the unfinanced spot cost plus the collateral's face value. Annualized net carry on capital is net * 365 / days over that.

## Not modeled

- Funding paths. A flat number stands in for one that resets every 8 hours.
- Liquidation mechanics: auctions, slippage, partial closes and insurance funds. After a liquidation the spot leg would be unhedged, and that's not priced.
- A margin call on the financed spot when the price falls.
- Basis moves before exit, on the marks of both legs.
- Collateral that moves with the price, and haircuts that change in stress.
- Counterparty, custody, venue and transfer delays between legs.
- Whether this person may trade this derivative or use this venue. That is a legal question for counsel.
- Taxes.

## 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/basis_carry \
  -H 'content-type: application/json' \
  -d '{"instrument":"perp","spot_price":1000,"derivative_price":1002,"funding_bps_per_8h":1,"notional":1000000,"short_leverage":4,"maintenance_margin_pct":2,"fees_bps_round_trip":12,"borrow_rate_pct":8,"financed_share_pct":50,"collateral_haircut_pct":15,"holding_days":90}' \
  | jq '{summary, flags, flips, not_modeled, inputs_hash}'
```

### MCP

The tool is `basis_carry` 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":"basis_carry","arguments":{"instrument":"perp","spot_price":1000,"derivative_price":1002,"funding_bps_per_8h":1,"notional":1000000,"short_leverage":4,"maintenance_margin_pct":2,"fees_bps_round_trip":12,"borrow_rate_pct":8,"financed_share_pct":50,"collateral_haircut_pct":15,"holding_days":90}}}' \
  | 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 basis_carry > mine.json           # replace every number in it
node hedgefund.mjs run basis_carry mine.json | jq '{summary, flags, flips, not_modeled, inputs_hash}'
```

In a script:

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

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