Moving all of my Emacs-related files into their own directory at the root of this repository.
		
			
				
	
	
		
			119 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
| ;;; 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
 |