Functional Weave
Code in TypeScript

invest.portfolio-weights@1.0.1

README.md

2,855 bytes · view raw

# invest.portfolio-weights

Each holding's weight in a portfolio, the weight it is meant to have, and how
far it has drifted, in basis points (10000 = 100%) and in money. It is the
first step of any rebalancing policy: "rebalance when anything drifts more
than 5 percentage points" is `maxAbsDriftBasisPoints > 500`.

## Why it is shaped this way

- **Integer arithmetic throughout.** Values are `Money` in minor units and
  every ratio is computed from them exactly (with 128-bit or arbitrary-size
  integers inside, so a portfolio of billions does not overflow), then
  rounded once.
- **Each weight is rounded on its own**, half-up to a whole basis point. The
  weights therefore need not add up to exactly 10000: three equal holdings
  are 3333 bp each. Forcing them to sum (largest remainder) would move one
  holding's weight by a basis point it does not have, and the drift of that
  holding would be wrong. If you need weights that sum for a pie chart, use
  `money.allocate` on the values.
- **Drift is computed from the exact values**, (value x 10000 - target x
  total) / total, and rounded once, half away from zero. At an exact half
  basis point this can differ by one from `weightBasisPoints -
  targetBasisPoints`, which rounds twice.
- **`driftValue` is the money to sell (positive) or buy (negative)** to hit
  the target exactly, before any whole-unit or minimum-trade constraint;
  `invest.rebalance` applies those.

## Edge cases

- Targets must sum to exactly 10000. A holding may have a target of 0
  (something to sell out of) and a holding may be worth 0 (something to buy).
- A portfolio worth nothing has no weights and is an error, as are negative
  values (short positions are out of scope), duplicate ids, mixed currencies
  and an empty list.

## Before you rely on this

**Not professional advice.** This capability calculates investment figures from published rules. It is a software component for developers, not financial advice. Rules change and every rate here has an effective date. Check that the dates cover your case. Verify results against the official sources listed above, and have a tax adviser review how you use it, before anyone relies on the output. Provided "as is" under its licence, without warranty.

**Unreviewed.** This capability's implementations agree in every language and pass its published test vectors, which were worked out from the official sources cited. But no qualified tax adviser has yet checked those vectors, or confirmed that the capability covers the cases it claims. Treat it as a draft. Do not use it for real people, money or decisions without your own expert review. Once a qualified reviewer signs off, this notice is replaced with their name, qualification and the date. Each new version needs fresh sign-off.

1.0.1 marks it unreviewed. The code and the tests are unchanged.