Functional Weave
Code in TypeScript

finance.markup-price@1.0.0

README.md

1,666 bytes · view raw

# finance.markup-price

The inverse of `finance.margin`: given a cost and a target, the price.

- **markup** is profit over cost: `price = cost × (1 + markup)`. A 50% markup
  on 100.00 is 150.00.
- **margin** is profit over price: `price = cost / (1 - margin)`. A 50% margin
  on 100.00 is 200.00, not 150.00.

Confusing the two is the classic pricing mistake - a retailer aiming for a 40%
margin who adds 40% to cost gets a 28.57% margin - so the basis is a required
argument with no default.

The price is rounded once, to the currency's minor unit, with the
`math.round-div` mode you pass. Rounding can land a fraction of a basis point
either side of the target. Use `up` for a margin or markup target you must not
fall below: 1,000 at a 30% margin is 1,428.57..., and `down` gives 1,428,
which is a 29.97% margin, while `up` gives 1,429.

The results agree with `finance.margin`: several vectors here are that
capability's vectors run backwards (60.00 at a 40% margin is 100.00; 6.99 at a
30.03% margin is 9.99; 120.00 at a -20% margin is 100.00), and feeding the
price back into `finance.margin` returns the target to within its rounding.

Edges: a margin of 100% or more has no finite price and is an error. A
negative margin or markup is a price below cost and is allowed (clearance,
loss leaders); a markup of -100% is a price of zero, and below that the price
would be negative, which is an error. A negative cost is an error. Zero cost
gives a zero price on either basis. `cost × 10000` (or `cost × (10000 +
markup)`) must stay within 2^53 - 1, which is costs up to about 900 million
pounds; beyond that the calculation is refused rather than rounded.