Functional Weave
Code in Rust

invest.cagr@1.0.0

vectors.json

4,877 bytes · view raw

[
 {
  "name": "doubling over ten years is 7.18% a year (7.1773...%)",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 20000,
    "currency": "GBP"
   },
   10,
   1
  ],
  "expect": 718
 },
 {
  "name": "121 from 100 over two years is exactly 10%",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 12100,
    "currency": "GBP"
   },
   2,
   1
  ],
  "expect": 1000
 },
 {
  "name": "one year is the simple return",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 10725,
    "currency": "GBP"
   },
   1,
   1
  ],
  "expect": 725
 },
 {
  "name": "18 months as 3/2 years: 1.21^(2/3) - 1 = 13.55%",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 12100,
    "currency": "GBP"
   },
   3,
   2
  ],
  "expect": 1355
 },
 {
  "name": "six months of 5% annualises to 10.25%, not 10%",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 10500,
    "currency": "GBP"
   },
   1,
   2
  ],
  "expect": 1025
 },
 {
  "name": "one month of 1% compounds to 12.68% a year",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 101,
    "currency": "GBP"
   },
   1,
   12
  ],
  "expect": 1268
 },
 {
  "name": "30 days as 30/365 years",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 10100,
    "currency": "GBP"
   },
   30,
   365
  ],
  "expect": 1287
 },
 {
  "name": "halving over five years is -12.94% a year",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 5000,
    "currency": "GBP"
   },
   5,
   1
  ],
  "expect": -1294
 },
 {
  "name": "a total loss is -100% whatever the period",
  "args": [
   {
    "minor": 10000,
    "currency": "GBP"
   },
   {
    "minor": 0,
    "currency": "GBP"
   },
   7,
   1
  ],
  "expect": -10000
 },
 {
  "name": "no change is zero",
  "args": [
   {
    "minor": 55555,
    "currency": "GBP"
   },
   {
    "minor": 55555,
    "currency": "GBP"
   },
   3,
   1
  ],
  "expect": 0
 },
 {
  "name": "exactly +0.5 bp rounds away from zero to 1",
  "args": [
   {
    "minor": 1000000,
    "currency": "GBP"
   },
   {
    "minor": 1000050,
    "currency": "GBP"
   },
   1,
   1
  ],
  "expect": 1
 },
 {
  "name": "exactly -0.5 bp rounds away from zero to -1",
  "args": [
   {
    "minor": 1000000,
    "currency": "GBP"
   },
   {
    "minor": 999950,
    "currency": "GBP"
   },
   1,
   1
  ],
  "expect": -1
 },
 {
  "name": "a third up in a year: 33.33% (repeating ratio)",
  "args": [
   {
    "minor": 300,
    "currency": "GBP"
   },
   {
    "minor": 400,
    "currency": "GBP"
   },
   1,
   1
  ],
  "expect": 3333
 },
 {
  "name": "seven-year growth from awkward amounts",
  "args": [
   {
    "minor": 12345678,
    "currency": "GBP"
   },
   {
    "minor": 98765432,
    "currency": "GBP"
   },
   7,
   1
  ],
  "expect": 3459
 },
 {
  "name": "works in any currency, yen included",
  "args": [
   {
    "minor": 1000000,
    "currency": "JPY"
   },
   {
    "minor": 2000000,
    "currency": "JPY"
   },
   10,
   1
  ],
  "expect": 718
 },
 {
  "name": "a start of zero is an error",
  "args": [
   {
    "minor": 0,
    "currency": "GBP"
   },
   {
    "minor": 100,
    "currency": "GBP"
   },
   1,
   1
  ],
  "expectError": "startValue must be greater than zero"
 },
 {
  "name": "a negative end value is an error",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": -1,
    "currency": "GBP"
   },
   1,
   1
  ],
  "expectError": "endValue must not be negative"
 },
 {
  "name": "mixed currencies are an error",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 200,
    "currency": "EUR"
   },
   1,
   1
  ],
  "expectError": "currency mismatch"
 },
 {
  "name": "zero years is an error",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 200,
    "currency": "GBP"
   },
   0,
   1
  ],
  "expectError": "yearsNumerator must be a whole number from 1 to 100000"
 },
 {
  "name": "a zero denominator is an error",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 200,
    "currency": "GBP"
   },
   1,
   0
  ],
  "expectError": "yearsDenominator must be a whole number from 1 to 100000"
 },
 {
  "name": "a fractional number of years must be written as a fraction",
  "args": [
   {
    "minor": 100,
    "currency": "GBP"
   },
   {
    "minor": 200,
    "currency": "GBP"
   },
   1.5,
   1
  ],
  "expectError": "yearsNumerator must be a whole number from 1 to 100000"
 },
 {
  "name": "fractional minor units are refused",
  "args": [
   {
    "minor": 100.5,
    "currency": "GBP"
   },
   {
    "minor": 200,
    "currency": "GBP"
   },
   1,
   1
  ],
  "expectError": "amounts must be whole minor units"
 }
]