diff options
Diffstat (limited to 'emacs/.emacs.d/wpc/finance.el')
-rw-r--r-- | emacs/.emacs.d/wpc/finance.el | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/emacs/.emacs.d/wpc/finance.el b/emacs/.emacs.d/wpc/finance.el new file mode 100644 index 000000000000..b124061ccba3 --- /dev/null +++ b/emacs/.emacs.d/wpc/finance.el @@ -0,0 +1,119 @@ +;;; finance.el --- Functions to help me organize my finances -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; Using functions to organize my financial thinking. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dependencies +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'prelude) +(require 'math) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Library +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar finance/enable-tests? t + "When t, run the tests defined herein.") + +;; TODO: Support printing an org-table of these amount in a similar format to: +;; https://keisan.casio.com/exec/system/1234231998 +(cl-defun finance/future-value (amt + &key + num-years + (frequency 'monthly) + (interest-rate 0.06) + (payment-due-at 'beg) + (present-value 0)) + "Compute the Future Value of AMT. + +This function assumes that the interest rate is applied annually and not +monthly. + +This function will attempt to provide the following defaults: +- frequency: 'monthly +- interest-rate: 6% +- payment-due-at: 'beg +- present-value: 0.00" + (prelude/assert (set/contains? payment-due-at (set/new 'beg 'end))) + (prelude/assert (set/contains? frequency (set/new 'annually + 'semiannually + 'quarterly + 'monthly))) + (let ((pmt amt) + (k (alist/get frequency '((annually . 1) + (semiannually . 2) + (quarterly . 4) + (monthly . 12)))) + (r interest-rate) + (n num-years) + (pv present-value)) + (if (= 0 r) + (+ pv (* pmt n k)) + (if (equal 'beg payment-due-at) + (+ (* pv (math/exp (+ 1 (/ r k)) (* n k))) + (* pmt + (/ (- (math/exp (+ 1 (/ r k)) (* n k)) 1) + (/ r k)) + (+ 1 (/ r k)))) + (+ (* pv (math/exp (+ 1 (/ r k)) (* n k))) + (* pmt + (/ (- (math/exp (+ 1 (/ r k)) (* n k)) 1) + (/ r k)))))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Tests +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(when finance/enable-tests? + (prelude/assert + (equal "1551.27" + (string/format "%0.2f" + (finance/future-value + 9.99 + :interest-rate 0.05 + :num-years 10 + :frequency 'monthly + :payment-due-at 'end + :present-value 0)))) + (prelude/assert + (equal "14318.34" + (string/format "%0.2f" + (finance/future-value 10.0 :num-years 35)))) + (prelude/assert + (equal "4200.00" + (string/format "%0.2f" + (finance/future-value + 10.0 + :interest-rate 0.0 + :num-years 35 + :frequency 'monthly + :payment-due-at 'beg + :present-value 0)))) + (prelude/assert + (equal "14318.34" + (string/format "%0.2f" + (finance/future-value + 10.0 + :interest-rate 0.06 + :num-years 35 + :frequency 'monthly + :payment-due-at 'beg + :present-value 0)))) + (prelude/assert + (equal "38282.77" + (string/format "%0.2f" + (finance/future-value + 10.0 + :interest-rate 0.1 + :num-years 35 + :frequency 'monthly + :payment-due-at 'beg + :present-value 0))))) + +(provide 'finance) +;;; finance.el ends here |