Financial Algorithms Cookbook

Error: Failed to load processor TOC
No macro named [[TOC]] found

Basic Calculations

Solving Equations

Newton-Raphson Method

To calculate the number of compounding periods you will need the following:

  • todo
tolerence=0.000001
limit=100
def newton_raphson(function, estimate, stop, *values): 
  xk = estimate
  fk = function(xk, *values)
  h=0.0001
  xk = estimate + h
  fkh = function(xk, *values) 
  # Stop since estimate was correct. 
  if fk  == stop:
    return estimate
  # Perform iteration process.
  for k in xrange(lim):
    dk = (fkh - fk)/h
    if fabs(dk) <= tol:
      return 0.0
    fk = function(xk, *values)
    fkh = function(xk+h, *values)
    uk = fk/dk
    xk -= uk
    if fabs(uk) < tol:
      return  xk

Example

You want to solve for i using the future value of an anuity.

FVoa = PMT [((1 + i)n - 1) / i]

Where:

  • PMT= 5,000
  • n = 5
  • FV = 28,185.46
    f = lambda i,FV,PMT,n: PMT*(pow(1+i, n)-1)/i - FV
    i = newton_raphson(f, 0.05, 0.00, 28185.46, 5000, 5)
    print i
    >>> 
    0.0599999147035
    

References

  • Gallager, T; Andrew Jr., J., Financial Management: Principals and Practices, Upper Saddle River, NJ: Prentice Hall, 1996
  • HP-12C Business Calculator Owner's Manual, Hewlett Packard, 1984
  • HP-10B Business Calculator Owner's Manual, Hewlett Packard, 1994

Date Calculations

Actual/Actual

GREGORY_YEAR     = 1582
GREGORY_MONTH    = 10
GREGORY_DAY      = 15

def toJulian(year, month, day): 
    " (int, int, double) -> double"
    A = 0L
    B = 0L
    C = 0L
    D = 0L

    y = year
    m = month
    d =day
    
    if m <= 2:
        y -= 1
        m += 12
        
    if ((year > GREGORY_YEAR) or (year == GREGORY_YEAR) and (month > GREGORY_MONTH)) \
      or ((year == GREGORY_YEAR) and (month == GREGORY_MONTH) and (day >= GREGORY_DAY)):

        A = y /100
        B = 2 - A + (A/4)
   
    dummy, C = modf((365.25*y))
    dummy, D = modf(30.6001*(m+1))
    
    julian = B + C + D + d + 1720994.5
    return julian


def fromJulian(j):
    "double -> (int, int, double)"
    F, I = modf(j+0.5)
    
    if I > 2299160.0:
        A = floor((I - 1867216.25)/36524.25)
        B = I+1.0+A-floor(A/4.0)
    else:
        B = I
        
    C = B + 1524.0
    D = floor((C-122.1)/365.25)
    E = floor(365.25*D)
    G = floor((C-E)/30.6001)
    
    day = C - E + F - floor(G*30.6001)
    m=0.0

    if G < 13.5:
        m = G - 1
    else:
        m = G -13

    month = int(floor(m))

    if m < 2.5:
        year = int(floor(D - 4715))
    else:
        year = int(floor(D - 4716))     

    return year, month, day

def getActual(year, month, day, days):
  return fromJulian(toJulian(year, month, day) + days))

def diffActual(y1, m1, d1, y2,m2, d2):
   return toJulian(y1, m1, d1) - toJulian(y2, m2, d2)


Example

You purchased a put option on SUNW on 14 May 2005, what would be its expiry date:

>> getActual(2005,5,14, 120)
2005, 09, 11
>>

30/360

def diff30360(y1, m1, d1, y2,m2, d2):
    if d1 == 31:
       z=30
    else:
       z= d1
   date1 = 360*y1 +30*m1 + z
   if d2 == 31:
      if  d1 >= 30:
        z = 30
      else:
        z = d2
    else:
        z = d2
    date2 = 360*y2 +30*m2 + z 
    return date1 - date2

Easter

def getEaster(year):
  "returns date of easter friday"
  a= year%19
  b = year/100
  c = year%100
  d = b/4
  e = b%4
  f = (b+8)/25
  g = (b -f +1)/3
  h = ((19*a+b-d-g+15)%30)
  i = c/4
  j = c%4 #k = (c%4)
  k = (32+(2*e) + ( 2*i ) -h-j)%7 # l = ((32+2*e+2*i-h-k)%7)
  l = (a+(11*h)+(22*k))/451 # m = (a+11*h+22*l)/451
  month = (h+k-(7*l) +114)/31
  day = (h+k-(7*l) +114)%31 + 1
  "Good Friday is 2 days before the Easter day"
  day-=2 
  return year, month, day

Weekday

def weekday(year, month, day):
  "returns 1..7 1= monday, 7 = sunday"
   j = getJulian(year, month, day)
   A = fmod((j + 1.5),7.0)
   return ceil(A)

Leap Year

def isLeap(year):
   return ((year % 4) ==0)  and ((year % 400) ==0)

Prior Settlement Date

def priorSettlementDate(year, month, day, maturityYear, maturityMonth, maturityDay):
   diff =0
                y = year
                m = maturityMonth
                if (month < maturityMonth) 
                    or ((month == maturityMonth) and (day <= maturityDay)):
                        m -= 6
                        diff =1
                md = maturityMonth - month
                if md > 6 or ((md == 6) and (maturityDay > day)):
                        m +=6
                        y -=diff
                if m < 1:
                        m +=12
                        y -=1
                if m > 12:
                        m -=12
                        y  +=1
                return y, m, maturityDay

After Settlement Date

def afterSettlement(year, month, day):
  m = month+6
  y = year
  if m > 12:
    m -=12
    y +=1
 return y, m, day

Semi-Annual Periods

def semiAnnualPeriods(year, month, day, maturityYear, maturityMonth, maturityDay):
   apyear, apmonth, apday = priorSettlement(maturityYear, maturityMonth, maturityDay)
   opyear, opmonth, opday  = apd.afterSettlement(apyear, apmonth, apday)
   if maturityMonth == opMonth:
      return (maturityYear - opYear)*2
  else:
     return (maturityYear - apYear)*2-1

References

  • Gallager, T; Andrew Jr., J., Financial Management: Principals and Practices, Upper Saddle River, NJ: Prentice Hall, 1996
  • HP-12C Business Calculator Owner's Manual, Hewlett Packard, 1984
  • HP-10B Business Calculator Owner's Manual, Hewlett Packard, 1994
  • http://www.smart.net/~mmontes/ec-cal.html