def __init__(self, curve: Curve, MRV, MRS, val_date: Date, t: Periods, flag: bool, **kwargs): super().__init__(val_date=val_date, t=t, flag=flag, **kwargs) if not isinstance(curve, Curve): raise ValueError("Curve is not a Curve class") self.curve = curve self.MRV = MRV self.MRS = MRS self.dt = self.curve.base.yearFraction(d1=self.val_date, d2=self.val_date + self.t, calendar=self.curve.calendar) dfT = self.curve.discount(val_date=self.val_date, date=self.val_date + self.t)[0] dftt = self.curve.discount(val_date=self.val_date, date=self.val_date + self.t + Days(1))[0] self.fm0t = -(log(dftt) - log(dfT)) * 365 dfT = self.curve.discount(val_date=self.val_date, date=self.val_date)[0] dftt = self.curve.discount(val_date=self.val_date, date=self.val_date + Days(1))[0] fm0s = -(log(dftt) - log(dfT)) * 365 alfat = self.fm0t + self.MRV**2 / (2 * self.MRS**2) * ( 1 - exp(-self.MRS * self.dt))**2 alfas = fm0s rs = self.curve.rates[0] self.ert = rs * exp(-self.MRS * self.dt) + alfat - alfas * exp( -self.MRS * self.dt) self.vart = self.MRV**2 / (2 * self.MRS) * ( 1 - exp(-2 * self.MRS * self.dt))
def PBO(self): curve = self.curve_irr + self.curve_spread m = self.val_date.month() inf = self.curve_inf.rate(self.val_date + Days(self.duration))[0] r = curve.rate(self.val_date + Days(self.duration))[0] u_i = round_d(round_up(inf * 4) / 4, 4) l_i = round_d(round_down(inf * 4) / 4, 4) l = len(self.dates) d = 0 td = [0] * l if inf <= self.RLPI.RPI.max(): inf_a = (inf - l_i) / 0.0025 * (float(self.RLPI['LPI-A'][self.RLPI.RPI == u_i]) - float(self.RLPI['LPI-A'][self.RLPI.RPI == l_i])) + \ float(self.RLPI['LPI-A'][self.RLPI.RPI == l_i]) else: inf_a = self.RLPI['LPI-A'].max() if inf <= self.RLPI.RPI.max(): inf_d = (inf - l_i) / 0.0025 * (float(self.RLPI['LPI-D'][self.RLPI.RPI == u_i]) - float(self.RLPI['LPI-D'][self.RLPI.RPI == l_i])) + \ float(self.RLPI['LPI-D'][self.RLPI.RPI == l_i]) else: inf_d = self.RLPI['LPI-D'].max() if inf <= self.RLPI.RPI.max(): inf_p = (inf - l_i) / 0.0025 * (float(self.RLPI['LPI-P'][self.RLPI.RPI == u_i]) - float(self.RLPI['LPI-P'][self.RLPI.RPI == l_i])) + \ float(self.RLPI['LPI-P'][self.RLPI.RPI == l_i]) else: inf_p = self.RLPI['LPI-P'].max() for i in range(0, l): td[i] = Thirty360.yearFraction(self.dates[0], self.dates[i] + Years(1), Calendar()) for i in range(0, l - 1): d += ((((12 - m) / 12) * self.active[i] * ((1 + inf_a) ** td[i])) + ((m / 12) * self.active[i + 1] * ((1 + inf_a) ** td[i + 1]))) / \ ((1 + r) ** (td[i] - 0.5)) d += ((((12 - m) / 12) * self.deferred[i] * ((1 + inf_d) ** td[i])) + ((m / 12) * self.deferred[i + 1] * ((1 + inf_d) ** td[i + 1]))) / \ ((1 + r) ** (td[i] - 0.5)) d += ((((12 - m) / 12) * self.pensioner[i] * ((1 + inf_p) ** td[i])) + ((m / 12) * self.pensioner[i + 1] * ((1 + inf_p) ** td[i + 1]))) / \ ((1 + r) ** (td[i] - 0.5)) d += (((12 - m) / 12) * self.active[l - 1] * ((1 + inf_a) ** td[l - 1])) / \ ((1 + r) ** td[l - 1]) d += (((12 - m) / 12) * self.deferred[l - 1] * ((1 + inf_d) ** td[l - 1])) / \ ((1 + r) ** td[l - 1]) d += (((12 - m) / 12) * self.pensioner[l - 1] * ((1 + inf_p) ** td[l - 1])) / \ ((1 + r) ** td[l - 1]) return d
def businessDaysBetween(self, date_from: Date, date_to: Date): if (not isinstance(date_from, Date) or not isinstance(date_to, Date)): raise ValueError("Input must be dates") nd = date_to - date_from sd = date_from.weekday() ed = date_to.weekday() nw = (((date_to - Days(ed - 1)) - (date_from - Days(sd - 1))) / 7) - 1 return int(nd - nw * 2 - min(8 - sd, 2) - max(ed - 6, 0))
def businessDaysBetween2(self, date_from, date_to): if (not isinstance(date_from, Date) or not isinstance(date_to, Date)): raise ValueError("Input must be dates") natDays = date_to - date_from busDays = 0 for i in range(0, natDays): busDays += self.isBusinessDay(date_from + Days(i)) return busDays
def PBO(self): curve = self.curve_irr + self.curve_spread m = self.val_date.month() inf = self.curve_inf.rate(self.val_date + Days(self.duration))[0] r = curve.rate(self.val_date + Days(self.duration))[0] l = len(self.dates) d = 0 td = [0] * l for i in range(0, l): td[i] = Thirty360.yearFraction(self.dates[0], self.dates[i] + Years(1), Calendar()) for i in range(0, l - 1): d += ((((12 - m) / 12) * self.flows[i] * (( 1 + inf) ** td[i])) + \ ((m / 12) * self.flows[i + 1] * ((1 + inf) ** td[i + 1]))) / \ ((1 + r) ** (td[i] - 0.5)) d += (((12 - m) / 12) * self.flows[l - 1] * (( 1 + inf) ** td[l - 1])) / \ ((1 + r) ** td[l - 1]) return d
def getCurve(self, name: str): return self.curves[find(self.getCuNames(), name)] if __name__ == "__main__": from src.dates.date import Date, Days factors = [Factor(name="EQ1")] + [Factor(name="EQ2") ] + [Factor(name="EQ3")] val_date = Date(31, 12, 2017) IT_BOND = Curve(name="IT_BOND", dates=[ Date(31, 5, 2018) + Days(90), Date(31, 5, 2018) + Days(180), Date(31, 5, 2018) + Days(360), Date(31, 5, 2018) + Days(720), Date(31, 5, 2018) + Days(1080), Date(31, 5, 2018) + Days(2160), Date(31, 5, 2018) + Days(2520), Date(31, 5, 2018) + Days(2880), Date(31, 5, 2018) + Days(3600), Date(31, 5, 2018) + Days(5400), Date(31, 5, 2018) + Days(5580) ], rates=[ -0.00223, 0.00205, 0.00515, 0.00991, 0.01342, 0.02326, 0.02385, 0.02560, 0.02771, 0.03047, 0.03047 ])
dates, rates, compounding=curve_from.compounding, interpolator=curve_from.interpolator) x.base = curve_from.base return x if __name__ == "__main__": from src.dates.date import Date, Days, Years valDate = Date(31, 12, 2017) days = [ valDate + Days(180), valDate + Days(360), valDate + Days(720), valDate + Days(1080), valDate + Days(1800), valDate + Days(2520), valDate + Days(3600) ] rates = [-0.00326, -0.00382, -0.00172, -0.00035, 0.00401, 0.01029, 0.01908] days1 = [ valDate + Days(180), valDate + Days(365), valDate + Days(725), valDate + Days(1080), valDate + Days(1800), valDate + Days(2525), valDate + Days(3600) ] rates1 = [ -0.00326, -0.00382, -0.00172, -0.00035, 0.00401, 0.01029, 0.01908 ]
return [gb.get_group(x) for x in gb.groups] if __name__ == "__main__": import src.assets.products as pricers from src.assets.products import Portfolio from src.dates.date import Date, Days from src.curves.curve import Curve p = Portfolio() valDate = Date(31, 12, 2017) ES_BOND = Curve(name="ES_BOND", dates=[ valDate + Days(360), valDate + Days(1080), valDate + Days(1440), valDate + Days(1800), valDate + Days(2520), valDate + Days(3240), valDate + Days(3600), valDate + Days(5400), valDate + Days(5580), valDate + Days(7200) ], rates=[ -0.00528, -0.00024, 0.0006, 0.0037, 0.00819, 0.01322, 0.01558, 0.02225, 0.0223, 0.02361 ]) class_ = getattr(pricers, "Bond") args = { 'nominal': 4776736, 'startDate': Date(4, 3, 2015),
rates[i] = self.fwd[i] * exp(-0.5 * self.vol**2 * self.dt + self.vol * sqrt(self.dt) * random) return rates if __name__ == "__main__": from src.dates.date import Days, Months, Years valDate = Date(31, 12, 2017) IPCA = Curve( name="IPCA", dates=[ valDate + Days(365), valDate + Days(720), valDate + Days(1080), valDate + Days(1440), valDate + Days(1800), valDate + Days(2160), valDate + Days(2520), valDate + Days(2880), valDate + Days(3240), valDate + Days(3600), valDate + Days(4320), valDate + Days(5400), valDate + Days(5580), valDate + Days(7200), valDate + Days(9000), valDate + Days(10800) ], rates=[ 0.014095800, 0.013620800, 0.013895800, 0.014095800, 0.014495800, 0.014795800, 0.015045800, 0.015345800, 0.015695800, 0.016020800, 0.016703720, 0.017590600, 0.017704851, 0.018735400, 0.019405200, 0.019725000 ]) IPCA_m = HullWhite(curve=IPCA, MRV=0.0025,
def nextBusinessDay(self, date): day = date while (self.isHoliday(day)): day += Days(1) return day
print("\tCurves:", [i for i in config['curves'].keys()]) print("\tThe next curves will be simulated:", [i for i in imp_curves[imp_curves.flag].index]) #### SET SEED #### print("\tSet seed:", config['seed']) np.random.seed(config['seed']) ##### LOAD CURVES #### if params['curves']: print("Reading curves data...", end="") curves = pd.read_excel(config['file'], sheet_name="Curves") curves.Tenor = curves.Tenor.apply( lambda x: config['valuation_date'] + Days(x)) curves = curves.groupby('Name').\ apply(lambda x: Curve(name=str(x.Name.unique()[0]), dates=x.Tenor.tolist(), rates=x.Rate.tolist())) print("OK") #### LOAD PORTFOLIO #### if params['assets']: print("Reading assets data...", end="") a = pd.read_excel(config['file'], sheet_name="Assets") a[a.select_dtypes(include=['datetime']).columns] = \ a[a.select_dtypes(include=['datetime']).columns].\ applymap(lambda x: Date(x.day, x.month, x.year)) print("OK")
((1 + r) ** td[l - 1]) d += (((12 - m) / 12) * self.deferred[l - 1] * ((1 + inf_d) ** td[l - 1])) / \ ((1 + r) ** td[l - 1]) d += (((12 - m) / 12) * self.pensioner[l - 1] * ((1 + inf_p) ** td[l - 1])) / \ ((1 + r) ** td[l - 1]) return d if __name__ == "__main__": import pandas as pd from src.curves.curve import get_curve from src.dates.date import Days curves = pd.read_excel("../../data/Inputs_Pensiones.xlsx") curves.Tenor = curves.Tenor.apply(lambda x: Date(31, 12, 2017) + Days(x)) curves = curves.groupby('Name'). \ apply(lambda x: Curve(name=str(x.Name.unique()[0]), dates=x.Tenor.tolist(), rates=x.Rate.tolist())) Liabilities( val_date=Date(31, 12, 2017), dates=[Date(31, 12, 2018), Date(31, 12, 2019), Date(31, 12, 2020)], flows=[1000, 2000, 3000], curve_irr=curves[0]) l = pd.read_excel("../../data/Datos_20180531.xlsx",
value = 0 for i in self.products: value += i.NPV() return value if __name__ == "__main__": val_date = Date(31, 12, 2017) t = Years(1) carter = Portfolio() IT_BOND = Curve(name="IT_BOND", dates=[ Date(31, 5, 2018) + Days(90), Date(31, 5, 2018) + Days(180), Date(31, 5, 2018) + Days(360), Date(31, 5, 2018) + Days(720), Date(31, 5, 2018) + Days(1080), Date(31, 5, 2018) + Days(2160), Date(31, 5, 2018) + Days(2520), Date(31, 5, 2018) + Days(2880), Date(31, 5, 2018) + Days(3600), Date(31, 5, 2018) + Days(5400), Date(31, 5, 2018) + Days(5580) ], rates=[ -0.00223, 0.00205, 0.00515, 0.00991, 0.01342, 0.02326, 0.02385, 0.02560, 0.02771, 0.03047, 0.03047 ])