TheLegace

roi.py

Dec 2nd, 2012
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.39 KB | None | 0 0
  1. #-------------------------------------------------------------------------------
  2. # Name:        input
  3. # Purpose:
  4. #
  5. # Author:      Vaibhav Kapoor and Adrian Barbur
  6. #
  7. # Created:     22/11/2012
  8. # Licence:     GPL
  9. #-------------------------------------------------------------------------------
  10. #!/usr/bin/env python
  11. # roi.py
  12.  
  13.  
  14. import dateutil.parser as dateutil,input,datetime,math,collections
  15.  
  16. class BenchInvalidException(Exception):
  17.     def __init__(self):
  18.         print "Error: Benchmarks are invalid"
  19. class DatesNumException(Exception):
  20.     def __init__(self):
  21.         print "Error: Not enough dates for calculation"      
  22. class EvalException(Exception):
  23.     def __init__(self):
  24.         print "Error: Evaluation period not valid"            
  25.  
  26.  
  27. class Roi:
  28.     def __init__(self,tr,dates,start,end):
  29.         try:
  30.             self.tr = tr
  31.             self.dates = dates
  32.             self.start = start
  33.             self.end = end
  34.                
  35.             if self.tr:
  36.                 if len(tr) < 2:
  37.                     raise DatesNumException
  38.                 for row in self.tr:
  39.                     if row[1] <= 0:
  40.                         raise Exception('Error: Market Value must be greater 0')
  41.                     if row[3] < 0:
  42.                         raise Exception('Error: Agent fees must be positive')
  43.                     withdrawal = abs(row[2] - row[3])
  44.                     if (row[1] + row[2]) < 0:
  45.                         raise Exception('Error: Withdrawal must be greater than market value')
  46.             if self.dates:
  47.                 for d, e in zip(dates[:-1], dates[1:]):
  48.                     if not d < e:
  49.                         raise Exception('Error: Dates are not unique and/or in chronological order')
  50.             self.query()
  51.         except DatesNumException, e:
  52.             print e
  53.         except Exception, e:
  54.             print e
  55.         finally:
  56.             pass
  57.     def di(self, a_date):
  58.         return self.dates.index(a_date)
  59.  
  60.     def duration(self, a_start, a_end):
  61.         delta = a_end - a_start
  62.         duration = delta.days / 365.2422
  63.         return duration
  64.     def query(self):
  65.         try:
  66.             try:
  67.                 if not self.start or not self.end or self.start >= self.end:
  68.                     raise EvalException
  69.                 if self.start not in self.dates or self.end not in self.dates:
  70.                     raise EvalException
  71.             except EvalException, e:
  72.                 print e
  73.                
  74.             for row in self.tr:
  75.                 if (row[0] != self.dates[0] and row[0].month == 1 and row[0].day == 1) or row[0] == self.dates[-1]:
  76.                     if not row[4]:
  77.                         raise BenchInvalidException
  78.                 else:
  79.                     if row[4]:
  80.                         raise BenchInvalidException                  
  81.         except BenchInvalidException, e:
  82.             print e
  83.        
  84.        
  85.         if self.start and self.end:
  86.             print '--------------EV---------------------------'
  87.             print 'Evaluation Period: ' + str(self.start.date()) + ' to ' + str(self.end.date())
  88.             print 'TWR: ' + str(self.twr(self.start,self.end))
  89.             print 'ROI: ' + str(self.roi(self.start,self.end))
  90.             print 'Benchmark: '
  91.                
  92.         if self.dates and self.tr:
  93.             print '--------------CP---------------------------'
  94.             print 'Evaluation Period: ' + str(self.dates[0].date()) + ' to ' + str(self.dates[-1].date())
  95.             #print self.tr
  96.             print 'TWR: ' + str(self.twr(self.dates[0],self.dates[-1]))
  97.             print 'ROI: ' + str(self.roi(self.dates[0],self.dates[-1]))
  98.             print 'Benchmark: '
  99.             print '-------------------------------------------'        
  100.        
  101.        
  102.     def roi(self, start, end):  
  103.         x = 1  
  104.         for i in range(1,10):
  105.             #print fx(x,a_start,a_end,dates,tr)
  106.             #print fxdx(x,a_start,a_end,dates,tr)
  107.             x = x - (self.fx(x, start, end) / self.fxdx(x,start,end))  
  108.             #print x    
  109.    
  110.         return x
  111.     def twr(self, startDate, endDate):
  112.         begin = self.di(startDate)
  113.         end = self.di(endDate)
  114.         wealth = 1
  115.         #1 = mv 2 = cf 3 = af
  116.         for i in range (begin + 1,end + 1):
  117.             w = self.tr[i][1] / (self.tr[i-1][1] + self.tr[i-1][2] +  self.tr[i-1][3])
  118.             wealth = wealth * w
  119.                
  120.         A_twr = wealth-1
  121.         time = self.duration(startDate, endDate)
  122.      
  123.         if time >= 1:
  124.             AC_TWR = (math.pow((1+ A_twr),(1/time)) - 1) * 100
  125.         else:
  126.             AC_TWR = A_twr * 100
  127.            
  128.         return  AC_TWR
  129.     def fx(self, x, startDate, endDate):
  130.         begin = self.di(startDate)
  131.         end = self.di(endDate)
  132.         sum_cf = 0
  133.         sum_af = 0
  134.        
  135.         for i in range (begin+1,end):
  136.             #print tr[i][2] * math.pow(x,duration(a_end,tr[i][0]))
  137.             sum_cf = self.tr[i][2] * math.pow(x,self.duration(self.tr[i][0],endDate)) + sum_cf
  138.        
  139.         for i in range (begin+1,end):
  140.             #print tr[i][3] * math.pow(x,duration(a_end,tr[i][0]))
  141.             sum_af = self.tr[i][3] * math.pow(x,self.duration(self.tr[i][0],endDate)) + sum_af
  142.        
  143.      
  144.        
  145.         fx = self.tr[begin][1] * math.pow(x,self.duration(startDate,endDate)) + sum_cf + sum_af - self.tr[end][1]
  146.         return fx
  147.     def fxdx(self,x,startDate,endDate):
  148.         begin = self.di(startDate)
  149.         end = self.di(endDate)
  150.         sum_cf = 0
  151.         sum_af = 0
  152.        
  153.         for i in range (begin+1,end):
  154.             #print tr[i][2] * math.pow(x,duration(a_end,tr[i][0]))
  155.             sum_cf = self.tr[i][2] * self.duration(self.tr[i][0],endDate)* math.pow(x,(self.duration(self.tr[i][0],endDate)-1)) + sum_cf
  156.            
  157.         for i in range (begin+1,end):
  158.             #print tr[i][3] * math.pow(x,duration(a_end,tr[i][0]))
  159.             sum_af = self.tr[i][3] * self.duration(self.tr[i][0],endDate)* math.pow(x,(self.duration(self.tr[i][0],endDate)-1)) + sum_af
  160.        
  161.         fxdx = self.tr[begin][1] *self.duration(startDate,endDate) * math.pow(x,(self.duration(startDate,endDate)-1)) + sum_cf + sum_af
  162.         return fxdx  
  163.    
  164.     def fv(self,start,end):
  165.         begin = self.di(start)
  166.         end = self.di(end)
  167.         bv = self.tr[begin][1] * self.bb(self.tr[begin][0])
  168.         for i in range (begin+1,end):
  169.             bv = self.tr[i][2] * self.bb(self.tr[i][0]) + bv
  170.         return bv
  171.    
  172.     def roiBM(self,startDate,endDate,fv):  
  173.         x = 1  
  174.         end = self.di(endDate,self.dates)
  175.         for i in range(1,10):
  176.             #print fx(x,a_start,a_end,dates,tr)
  177.             #print fxdx(x,a_start,a_end,dates,tr)
  178.             x = x - (self.fx(x,startDate,endDate,fv) / self.fxdx(x,startDate,endDate))  
  179.             #print x    
  180.         return x    
  181.     def bb(self,date):
  182.         bb = 1
  183.         end = self.di(self.end)
  184.         yr = date.year
  185.         first = 1
  186.         while yr <= self.tr[end][0].year:
  187.             if first == 1:
  188.                 row = self.getbmrow(yr)
  189.                 bb = math.pow((row[4]+1),self.duration(date,row[0]))* bb
  190.                 yr = yr + 1
  191.                 first = first + 1
  192.                
  193.                
  194.             if yr < self.tr[end][0].year:
  195.                 row = self.getbmrow(yr)
  196.                 row_prev = self.getbmrow(yr-1)
  197.                 bb = math.pow((row[4]+1),self.duration(row_prev[0],row[0]))*bb
  198.                 yr = yr + 1
  199.    
  200.            
  201.             if yr >= self.tr[end][0].year:
  202.                 checkdate = datetime.datetime(yr,1,1,0,0)
  203.      
  204.                 if checkdate == self.tr[end][0]:
  205.                     bb = bb
  206.                     yr = yr + 1
  207.                 else:
  208.                     row = self.getbmrow(yr)
  209.                     bb = math.pow((row[4]+1),self.duration(checkdate,self.tr[end][0]))*bb
  210.                     yr = yr + 1
  211.         return bb
  212.     def getbmrow(self,year):
  213.         yr = year + 1
  214.         if (yr > self.tr[len(self.tr)-1][0].year):
  215.             bm = self.tr[len(self.tr)-1]
  216.         else:
  217.             date = datetime.datetime(yr,1,1,0,0)
  218.             index = self.dates.index(date)
  219.             return self.tr[index]
  220.         return bm    
  221.        
  222. def main():
  223.    
  224.     inp = input.Input('input.csv')
  225.    
  226.     roi = Roi(inp.tr,inp.dates,inp.start,inp.end)
  227.    
  228.        
  229. if __name__ == '__main__':
  230.     main()
Advertisement
Add Comment
Please, Sign In to add comment