Functional Weave
Code in Python

invest.money-weighted-return@1.0.0

vectors.json

10,291 bytes · view raw

[
 {
  "name": "Microsoft's XIRR example is 37.34% (exact root 0.37336253352)",
  "args": [
   [
    {
     "date": "2008-01-01",
     "amount": {
      "minor": -1000000,
      "currency": "GBP"
     }
    },
    {
     "date": "2008-03-01",
     "amount": {
      "minor": 275000,
      "currency": "GBP"
     }
    },
    {
     "date": "2008-10-30",
     "amount": {
      "minor": 425000,
      "currency": "GBP"
     }
    },
    {
     "date": "2009-02-15",
     "amount": {
      "minor": 325000,
      "currency": "GBP"
     }
    },
    {
     "date": "2009-04-01",
     "amount": {
      "minor": 275000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 3734,
   "rate": "0.373362534"
  }
 },
 {
  "name": "the same flows in any order give the same rate",
  "args": [
   [
    {
     "date": "2009-02-15",
     "amount": {
      "minor": 325000,
      "currency": "GBP"
     }
    },
    {
     "date": "2008-01-01",
     "amount": {
      "minor": -1000000,
      "currency": "GBP"
     }
    },
    {
     "date": "2009-04-01",
     "amount": {
      "minor": 275000,
      "currency": "GBP"
     }
    },
    {
     "date": "2008-10-30",
     "amount": {
      "minor": 425000,
      "currency": "GBP"
     }
    },
    {
     "date": "2008-03-01",
     "amount": {
      "minor": 275000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 3734,
   "rate": "0.373362534"
  }
 },
 {
  "name": "+10% over a 365-day year is exactly 10%",
  "args": [
   [
    {
     "date": "2025-01-01",
     "amount": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2026-01-01",
     "amount": {
      "minor": 110000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 1000,
   "rate": "0.100000000"
  }
 },
 {
  "name": "+10% over 2024, a 366-day year, is 9.97% on a 365-day year",
  "args": [
   [
    {
     "date": "2024-01-01",
     "amount": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2025-01-01",
     "amount": {
      "minor": 110000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 997,
   "rate": "0.099713586"
  }
 },
 {
  "name": "a loss over two years (731 days) is negative",
  "args": [
   [
    {
     "date": "2020-01-01",
     "amount": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": 81000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": -999,
   "rate": "-0.099870272"
  }
 },
 {
  "name": "two deposits then a closing value",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -50000,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-07-01",
     "amount": {
      "minor": -50000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": -20000,
      "currency": "GBP"
     }
    },
    {
     "date": "2023-01-01",
     "amount": {
      "minor": 135000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 749,
   "rate": "0.074868597"
  }
 },
 {
  "name": "a deposit, a withdrawal, another deposit and the closing value",
  "args": [
   [
    {
     "date": "2020-01-01",
     "amount": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-01-01",
     "amount": {
      "minor": 20000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": -30000,
      "currency": "GBP"
     }
    },
    {
     "date": "2023-01-01",
     "amount": {
      "minor": 130000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 648,
   "rate": "0.064752089"
  }
 },
 {
  "name": "a loan seen from the borrower: in first, out later",
  "args": [
   [
    {
     "date": "2020-01-01",
     "amount": {
      "minor": 100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -110000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 997,
   "rate": "0.099713586"
  }
 },
 {
  "name": "30 days at 1% compounds to 12.87% a year",
  "args": [
   [
    {
     "date": "2024-03-01",
     "amount": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2024-03-31",
     "amount": {
      "minor": 101000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 1287,
   "rate": "0.128695294"
  }
 },
 {
  "name": "a tenfold gain in a leap year",
  "args": [
   [
    {
     "date": "2020-01-01",
     "amount": {
      "minor": -100,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-01-01",
     "amount": {
      "minor": 1000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 89373,
   "rate": "8.937285322"
  }
 },
 {
  "name": "almost everything lost",
  "args": [
   [
    {
     "date": "2020-01-01",
     "amount": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-01-01",
     "amount": {
      "minor": 1,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": -10000,
   "rate": "-0.999989680"
  }
 },
 {
  "name": "getting back exactly what was paid in is 0",
  "args": [
   [
    {
     "date": "2020-01-01",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2023-06-30",
     "amount": {
      "minor": 10000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 0,
   "rate": "0.000000000"
  }
 },
 {
  "name": "two payments on one day are netted",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -50000,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -50000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": 110000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 1000,
   "rate": "0.100000000"
  }
 },
 {
  "name": "flows netting to zero on the first date are dropped",
  "args": [
   [
    {
     "date": "2020-01-01",
     "amount": {
      "minor": 100,
      "currency": "GBP"
     }
    },
    {
     "date": "2020-01-01",
     "amount": {
      "minor": -100,
      "currency": "GBP"
     }
    },
    {
     "date": "2020-06-01",
     "amount": {
      "minor": -100000,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-06-01",
     "amount": {
      "minor": 110000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 1000,
   "rate": "0.100000000"
  }
 },
 {
  "name": "amounts in yen",
  "args": [
   [
    {
     "date": "2025-01-01",
     "amount": {
      "minor": -1000000,
      "currency": "GBP"
     }
    },
    {
     "date": "2026-01-01",
     "amount": {
      "minor": 1100000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expect": {
   "basisPoints": 1000,
   "rate": "0.100000000"
  }
 },
 {
  "name": "10% and 20% both solve -100, +230, -132: refused",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": 23000,
      "currency": "GBP"
     }
    },
    {
     "date": "2023-01-01",
     "amount": {
      "minor": -13200,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expectError": "no single rate of return solves these cash flows"
 },
 {
  "name": "more paid in than out, at every date, has no rate",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": 5000,
      "currency": "GBP"
     }
    },
    {
     "date": "2023-01-01",
     "amount": {
      "minor": -6000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expectError": "no single rate of return solves these cash flows"
 },
 {
  "name": "payments only is Excel's #NUM",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": -5000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expectError": "flows need at least one payment and one receipt"
 },
 {
  "name": "flows that net to nothing on one side",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2021-01-01",
     "amount": {
      "minor": 10000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expectError": "flows need at least one payment and one receipt"
 },
 {
  "name": "no flows",
  "args": [
   []
  ],
  "expectError": "flows must not be empty"
 },
 {
  "name": "mixed currencies",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": 11000,
      "currency": "EUR"
     }
    }
   ]
  ],
  "expectError": "currency mismatch"
 },
 {
  "name": "an impossible date",
  "args": [
   [
    {
     "date": "2021-02-30",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": 11000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expectError": "is not a real calendar date"
 },
 {
  "name": "flows more than 100 years apart",
  "args": [
   [
    {
     "date": "1900-01-01",
     "amount": {
      "minor": -10000,
      "currency": "GBP"
     }
    },
    {
     "date": "2001-01-01",
     "amount": {
      "minor": 11000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expectError": "flows must fall within 36500 days of each other"
 },
 {
  "name": "fractional minor units",
  "args": [
   [
    {
     "date": "2021-01-01",
     "amount": {
      "minor": -10000.5,
      "currency": "GBP"
     }
    },
    {
     "date": "2022-01-01",
     "amount": {
      "minor": 11000,
      "currency": "GBP"
     }
    }
   ]
  ],
  "expectError": "amounts must be whole minor units"
 }
]