Skip to content

Instantly share code, notes, and snippets.

@dam6pl
Last active August 4, 2022 06:30
Show Gist options
  • Save dam6pl/dcd8b751fbb07b74d5db4283525f640e to your computer and use it in GitHub Desktop.
Save dam6pl/dcd8b751fbb07b74d5db4283525f640e to your computer and use it in GitHub Desktop.
Bonds compound interest
/**
* --- WHAT IS IT?
*
* This is a custom function for use in Google Sheets and allows you to count
* the compound interest of bonds from provided date to today.
*
* --- HOW TO USE IT?
*
* 1. Create a new one or open an existing Google Sheet.
* 2. Navigate to `Extensions => Apps Scripts` in the navigation bar.
* 3. Paste the function into the Script editor.
* 4. Click `Run`.
* 5. Back to the sheet, now you can use the `BONDS` function like any other function.
*
* --- EXAMPLES
*
* =BONDS(100; '2021-05-18'; 1.7) //18 Nov 2021 will return 100.85
* =BONDS(100; '2020-11-18'; 1.7) //18 Nov 2021 will return 101.70
* =BONDS(100; '2019-11-18'; 1.7; 5.0) //18 Nov 2021 will return 106.78
* =BONDS(100; '2018-11-18'; 1.7; 5.0; 4.5) //18 Nov 2021 will return 111.59
*/
/**
* Returns the bonds compound interest since date.
*
* @param {number} buyPrice The buying price.
* @param {date} buyDate The buying date.
* @param {...number} yearsInterests An infinite number of parameters with each year interest.
*
* @customfunction
*
* @author Damian Nowak <me@dnowak.dev>
*/
function BONDS(buyPrice, buyDate, ...yearsInterests) {
const today = new Date(new Date().setHours(0, 0, 0, 0))
const dayInSeconds = 1000 * 60 * 60 * 24
let price = parseFloat(buyPrice)
let date = new Date(new Date(buyDate).setHours(0, 0, 0, 0))
if (0 >= price) {
throw new Error('Invalid buy price')
}
if (false === date instanceof Date || isNaN(date) || date > today) {
throw new Error('Invalid buy date')
}
let i = 0
do {
const datePlusYear = new Date(
date.getFullYear() + 1,
date.getMonth(),
date.getDate()
)
const dateTo = datePlusYear >= today ? today : datePlusYear
const numberOfDays = Math.round((datePlusYear - date) / dayInSeconds)
const numberOfToDate = Math.round((dateTo - date) / dayInSeconds)
const percentPerDay =
parseFloat((yearsInterests[i++] || '1').toString().replace(',', '.')) /
numberOfDays /
100
price = price + price * numberOfToDate * percentPerDay
date = datePlusYear
} while (date < today)
return parseFloat(price.toFixed(2))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment