Last active
August 4, 2022 06:30
-
-
Save dam6pl/dcd8b751fbb07b74d5db4283525f640e to your computer and use it in GitHub Desktop.
Bonds compound interest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* --- 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