def calc_ytm(self): tvm = TVM(self.ttm() * self.freq, 0, -self.mid(), self.couponRate / self.freq, 1) #semiannual payment try: return tvm.calc_r() * self.freq except Exception: return None
def calc_duration(self): price = (self.bid+self.ask)/2 tvm = TVM(n=ttm*self.freq, pv=-price, pmt=self.couponRate/self.freq, fv=1) ytm = tvm.calc_r() * self.freq ytmDelta = .001 tvm.r = (ytm-ytmDelta)/b.freq priceHigh = -tvm.calc_pv() tvm.r = (ytm+ytmDelta)/b.freq priceLow = -tvm.calc_pv() duration = ((priceHigh-priceLow)*2 / (priceHigh+priceLow)) / (ytmDelta*2) return duration
def calc_duration(self): price = (self.bid + self.ask) / 2 tvm = TVM(n=ttm * self.freq, pv=-price, pmt=self.couponRate / self.freq, fv=1) ytm = tvm.calc_r() * self.freq ytmDelta = .001 tvm.r = (ytm - ytmDelta) / b.freq priceHigh = -tvm.calc_pv() tvm.r = (ytm + ytmDelta) / b.freq priceLow = -tvm.calc_pv() duration = ((priceHigh - priceLow) * 2 / (priceHigh + priceLow)) / (ytmDelta * 2) return duration
import io #local time localtime = datetime(2012,9,19) #load bonds bonds = readfromfile('data/gilts_2012_09_19.csv') #calculate yield curve # Calculated YTMs doesn't necessarily correspond to those quoted in data file (source: Bondscape.net), due to accrued interest # and a fact that coupon payment are bound to some specific calendar date, not necessarily, one semiannually tr, yr = [], [] for b in bonds: ttm = (b.maturity - localtime).days / 360 price = (b.bid+b.ask)/2 ytm = TVM(n=ttm*b.freq, pv=-price, pmt=b.couponRate/b.freq, fv=1).calc_r() * b.freq tr.append(ttm) yr.append(ytm) print('Raw yield curve') for i in range(0, len(tr)): print("%.2f\t%.2f%%" % (tr[i], 100*yr[i])) # interpolation t = list(i for i in range(1,41)) y = [] interp = scipy.interpolate.interp1d(tr, yr, bounds_error=False, fill_value=scipy.nan) for i in t: value = float(interp(i)) if not scipy.isnan(value): y.append(value)
def calc_ytm(self): tvm = TVM(self.ttm()*self.freq, 0, -self.mid(), self.couponRate/self.freq, 1) #semiannual payment try: return tvm.calc_r() * self.freq except Exception: return None
if (self.mode==TVM.bgn): pva += self.pmt z = (-pva-self.pv) / (self.fv-pva) return -log(z) / log(1+self.r) def calc_r(self): def function_fv(r, self): z = pow(1+r, -self.n) pva = self.pmt / r if (self.mode==TVM.bgn): pva += self.pmt return -(self.pv + (1-z) * pva)/z return newton(f=function_fv, fArg=self, x0=.05, y=self.fv, maxIter=1000, minError=0.0001) ## example #1 Mortgage payments from quant.tvm import TVM pmt = TVM(n=25*12, r=.04/12, pv=500000, fv=0).calc_pmt() print("Payment = %f" % pmt) ## Example #2 Yield to Maturity r = 2*TVM(n=10*2, pmt=6/2, pv=-80, fv=100).calc_r() print("Interest Rate = %f" % r) ### Example 3: Arbitrage-free Bond Pricing pv = TVM(r=.06, n=8, pmt=5, fv=100).calc_pv() print("Present Value = %f" % pv) ## Example of boostrapping ''' epic, description, coupon, maturity, bid, ask TR13, Uk Gilt Treasury Stk, 4.5, 07-Mar-13, 101.92, 102.07 T813, Uk Gilt Treasury Stk, 8, 27-Sep-13, 107.86, 107.98
# Copyright (c) 2012 Quantitative & Financial, All rights reserved # www.quantandfinancial.com from quant.tvm import TVM pmt = TVM(n=25 * 12, r=.04 / 12, pv=500000, fv=0).calc_pmt() print("Payment = %f" % pmt) i = TVM(n=10 * 2, pmt=6 / 2, pv=-80, fv=100).calc_r() print("r = %f" % i)