Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #-------------------------------------------------------------------------------
- # Name: input
- # Purpose:
- #
- # Author: Vaibhav Kapoor and Adrian Barbur
- #
- # Created: 22/11/2012
- # Licence: GPL
- #-------------------------------------------------------------------------------
- #!/usr/bin/env python
- # roi.py
- import dateutil.parser as dateutil,input,datetime,math,collections
- class BenchInvalidException(Exception):
- def __init__(self):
- print "Error: Benchmarks are invalid"
- class DatesNumException(Exception):
- def __init__(self):
- print "Error: Not enough dates for calculation"
- class EvalException(Exception):
- def __init__(self):
- print "Error: Evaluation period not valid"
- class Roi:
- def __init__(self,tr,dates,start,end):
- try:
- self.tr = tr
- self.dates = dates
- self.start = start
- self.end = end
- if self.tr:
- if len(tr) < 2:
- raise DatesNumException
- for row in self.tr:
- if row[1] <= 0:
- raise Exception('Error: Market Value must be greater 0')
- if row[3] < 0:
- raise Exception('Error: Agent fees must be positive')
- withdrawal = abs(row[2] - row[3])
- if (row[1] + row[2]) < 0:
- raise Exception('Error: Withdrawal must be greater than market value')
- if self.dates:
- for d, e in zip(dates[:-1], dates[1:]):
- if not d < e:
- raise Exception('Error: Dates are not unique and/or in chronological order')
- self.query()
- except DatesNumException, e:
- print e
- except Exception, e:
- print e
- finally:
- pass
- def di(self, a_date):
- return self.dates.index(a_date)
- def duration(self, a_start, a_end):
- delta = a_end - a_start
- duration = delta.days / 365.2422
- return duration
- def query(self):
- try:
- try:
- if not self.start or not self.end or self.start >= self.end:
- raise EvalException
- if self.start not in self.dates or self.end not in self.dates:
- raise EvalException
- except EvalException, e:
- print e
- for row in self.tr:
- if (row[0] != self.dates[0] and row[0].month == 1 and row[0].day == 1) or row[0] == self.dates[-1]:
- if not row[4]:
- raise BenchInvalidException
- else:
- if row[4]:
- raise BenchInvalidException
- except BenchInvalidException, e:
- print e
- if self.start and self.end:
- print '--------------EV---------------------------'
- print 'Evaluation Period: ' + str(self.start.date()) + ' to ' + str(self.end.date())
- print 'TWR: ' + str(self.twr(self.start,self.end))
- print 'ROI: ' + str(self.roi(self.start,self.end))
- print 'Benchmark: '
- if self.dates and self.tr:
- print '--------------CP---------------------------'
- print 'Evaluation Period: ' + str(self.dates[0].date()) + ' to ' + str(self.dates[-1].date())
- #print self.tr
- print 'TWR: ' + str(self.twr(self.dates[0],self.dates[-1]))
- print 'ROI: ' + str(self.roi(self.dates[0],self.dates[-1]))
- print 'Benchmark: '
- print '-------------------------------------------'
- def roi(self, start, end):
- x = 1
- for i in range(1,10):
- #print fx(x,a_start,a_end,dates,tr)
- #print fxdx(x,a_start,a_end,dates,tr)
- x = x - (self.fx(x, start, end) / self.fxdx(x,start,end))
- #print x
- return x
- def twr(self, startDate, endDate):
- begin = self.di(startDate)
- end = self.di(endDate)
- wealth = 1
- #1 = mv 2 = cf 3 = af
- for i in range (begin + 1,end + 1):
- w = self.tr[i][1] / (self.tr[i-1][1] + self.tr[i-1][2] + self.tr[i-1][3])
- wealth = wealth * w
- A_twr = wealth-1
- time = self.duration(startDate, endDate)
- if time >= 1:
- AC_TWR = (math.pow((1+ A_twr),(1/time)) - 1) * 100
- else:
- AC_TWR = A_twr * 100
- return AC_TWR
- def fx(self, x, startDate, endDate):
- begin = self.di(startDate)
- end = self.di(endDate)
- sum_cf = 0
- sum_af = 0
- for i in range (begin+1,end):
- #print tr[i][2] * math.pow(x,duration(a_end,tr[i][0]))
- sum_cf = self.tr[i][2] * math.pow(x,self.duration(self.tr[i][0],endDate)) + sum_cf
- for i in range (begin+1,end):
- #print tr[i][3] * math.pow(x,duration(a_end,tr[i][0]))
- sum_af = self.tr[i][3] * math.pow(x,self.duration(self.tr[i][0],endDate)) + sum_af
- fx = self.tr[begin][1] * math.pow(x,self.duration(startDate,endDate)) + sum_cf + sum_af - self.tr[end][1]
- return fx
- def fxdx(self,x,startDate,endDate):
- begin = self.di(startDate)
- end = self.di(endDate)
- sum_cf = 0
- sum_af = 0
- for i in range (begin+1,end):
- #print tr[i][2] * math.pow(x,duration(a_end,tr[i][0]))
- 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
- for i in range (begin+1,end):
- #print tr[i][3] * math.pow(x,duration(a_end,tr[i][0]))
- 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
- fxdx = self.tr[begin][1] *self.duration(startDate,endDate) * math.pow(x,(self.duration(startDate,endDate)-1)) + sum_cf + sum_af
- return fxdx
- def fv(self,start,end):
- begin = self.di(start)
- end = self.di(end)
- bv = self.tr[begin][1] * self.bb(self.tr[begin][0])
- for i in range (begin+1,end):
- bv = self.tr[i][2] * self.bb(self.tr[i][0]) + bv
- return bv
- def roiBM(self,startDate,endDate,fv):
- x = 1
- end = self.di(endDate,self.dates)
- for i in range(1,10):
- #print fx(x,a_start,a_end,dates,tr)
- #print fxdx(x,a_start,a_end,dates,tr)
- x = x - (self.fx(x,startDate,endDate,fv) / self.fxdx(x,startDate,endDate))
- #print x
- return x
- def bb(self,date):
- bb = 1
- end = self.di(self.end)
- yr = date.year
- first = 1
- while yr <= self.tr[end][0].year:
- if first == 1:
- row = self.getbmrow(yr)
- bb = math.pow((row[4]+1),self.duration(date,row[0]))* bb
- yr = yr + 1
- first = first + 1
- if yr < self.tr[end][0].year:
- row = self.getbmrow(yr)
- row_prev = self.getbmrow(yr-1)
- bb = math.pow((row[4]+1),self.duration(row_prev[0],row[0]))*bb
- yr = yr + 1
- if yr >= self.tr[end][0].year:
- checkdate = datetime.datetime(yr,1,1,0,0)
- if checkdate == self.tr[end][0]:
- bb = bb
- yr = yr + 1
- else:
- row = self.getbmrow(yr)
- bb = math.pow((row[4]+1),self.duration(checkdate,self.tr[end][0]))*bb
- yr = yr + 1
- return bb
- def getbmrow(self,year):
- yr = year + 1
- if (yr > self.tr[len(self.tr)-1][0].year):
- bm = self.tr[len(self.tr)-1]
- else:
- date = datetime.datetime(yr,1,1,0,0)
- index = self.dates.index(date)
- return self.tr[index]
- return bm
- def main():
- inp = input.Input('input.csv')
- roi = Roi(inp.tr,inp.dates,inp.start,inp.end)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment