def __init__(self, fee, coupon, start, maturity, freq, referencedate, observationdate, rating, notional=1, recovery=0.4): self.numSim = 10 self.t_step = 1.0 / 365 self.fee = fee self.coupon = coupon self.start = start self.maturity = maturity self.freq = freq self.recovery = recovery self.rating = rating self.referencedate = referencedate self.observationdate = observationdate self.myScheduler = Scheduler() self.delay = self.myScheduler.extractDelay(freq=freq) self.referencedate = referencedate self.getScheduleComplete() self.fullDateList = self.datelist self.ntimes = len(self.datelist) self.pvAvg = 0.0 self.cashFlows = DataFrame() self.cashFlowsAvg = [] self.yieldIn = 0.0 self.notional = notional self.errorCurve = [] self.mcSim = MC_Vasicek_Sim()
def __init__(self, start, end, reference, recovery, rating, notional, freq="1M"): self.numSim = 10 self.t_step = 1.0 / 365 #z curve is for discounting self.zCurve = [] #q curve is for survival prob of the reference entity self.qCurve = [] self.start = start self.end = end self.reference = reference self.freq = freq self.rating = rating self.notional = notional # mcSim used for simulating default prob, interest rate # xR should already be calibrated self.xR = [] # xQ we need to calibrate inside CDS self.xQ = [] self.mcSim = MC_Vasicek_Sim() self.mcSimSurvival = MC_Vasicek_Sim() #self.mcSim.setVasicek(minDay=startDate, maxDay=endDate, x=xR, t_step=1.0 / 365, simNumber=self.simNum) #self.mcSimSurvival.setVasicek(minDay=startDate, maxDay=endDate, x=xR, t_step=1.0 / 365, simNumber=self.simNum) self.dateList = pd.date_range(start=start, end=end, freq=freq) self.recovery = recovery
def __init__(self, start, underlyings): myScheduler = Scheduler() myDelays = [] freqs = ['3M', '6M', '1Y', '3Y'] for i in range(0, len(freqs)): myDelays.append(myScheduler.extractDelay(freqs[i])) AAA = {} for i in range(0, len(freqs)): vas = MC_Vasicek_Sim(x=AAAx[freqs[i]], datelist=[start, myDelays[i] + start], t_step=1 / 365., simNumber=500) AAA[freqs[i]] = vas.getLibor()[0].loc[myDelays[i] + start] BBB = { '3M': MC_Vasicek_Sim(x=BBBx[freqs[0]], datelist=[start, myDelays[0] + start], t_step=1 / 365., simNumber=500).getLibor()[0].loc[myDelays[0] + start] } self.probs = {'AAA': AAA, 'BBB': BBB} self.underlyings = underlyings
def changeGuessForSpread(self, x): ''' inputs a x list of guesses for the Vasicek simulator than changes the myQ ''' vasicekMC = MC_Vasicek_Sim( datelist=[self.referenceDate, self.maturity], x=x, simNumber=20, t_step=t_step) self.myQ = vasicekMC.getLibor()[0] self.myQ = pd.DataFrame(self.myQ, index=self.myQ.index) self.myQ.columns = [self.freq] spread = self.bootProtec() / self.bootPrem() return spread.values[0]
def getZ_Vasicek(self): ### Get Z(t,t_i) for t_i in datelist ##### ## Simulate Vasicek model with paramters given in workspace.parameters # xR = [5.0, 0.05, 0.01, 0.05] # kappa = x[0] # theta = x[1] # sigma = x[2] # r0 = x[3] vasicekMC = MC_Vasicek_Sim( datelist=[self.referenceDate, self.end_date], x=xR, simNumber=10, t_step=t_step) self.myZ = vasicekMC.getLibor() self.myZ = self.myZ.loc[:, 0]
def getQ(self, start_date, referenceDate, end_date, freq, coupon, rating, R): ## Use CorporateDaily to get Q for referencedates ## # print("GET Q") # print(self.portfolioScheduleOfCF) if self.bootstrap: print("Q bootstrap") CDSClass = CDS(start_date=start_date, end_date=end_date, freq=freq, coupon=coupon, referenceDate=referenceDate, rating=rating, R=R) myLad = BootstrapperCDSLadder(start=self.start_date, freq=[freq], CDSList=[CDSClass], R=CDSClass.R).getXList(x0Vas)[freq] self.Q1M = MC_Vasicek_Sim( x=myLad, t_step=1 / 365, datelist=[CDSClass.referenceDate, CDSClass.end_date], simNumber=simNumber).getLibor()[0] print(self.Q1M) else: myQ = CorporateRates() myQ.getCorporatesFred(trim_start=referenceDate, trim_end=end_date) ## Return the calculated Q(t,t_i) for bonds ranging over maturities for a given rating daterange = pd.date_range(start=referenceDate, end=end_date).date myQ = myQ.getCorporateQData(rating=rating, datelist=daterange, R=R) Q1M = myQ[freq] print(Q1M) return (Q1M)
def __init__(self, startDate, endDate, referenceDate, effectiveDate, freq, notional, recovery=0.4): """ effective date is the start of the payments, startDate is when the contract is entered, endDate is maturity referenceDate is the date when the PV is taken We are paying a fixed rate to receive a floating rate """ self.recovery = recovery self.simNum = 10 self.xR = [] self.xQ = [] # use MC to generate scenarios for exposure self.mcSim = MC_Vasicek_Sim() #self.mcSim.setVasicek(minDay=startDate,maxDay=endDate,x=xR,t_step=1.0/365, simNumber=self.simNum) # z is discount curve self.zCurve = [] self.swapRate = [] self.freq = freq self.notional = notional self.fixedLeg = [] self.floatingLeg = [] self.startDate = startDate self.endDate = endDate self.referenceDate = referenceDate self.effctiveDate = effectiveDate self.initialSpread = [] self.myScheduler = Scheduler() self.datelist = pd.date_range(start=effectiveDate, end=endDate, freq=freq)
def getSpreadList(self, xQ): spread = {} orderedCDS=[] for i in range(0,len(self.freq)): for j in range(0,len(self.listCDS)): if(self.freq[i] == self.listCDS[j].freq): orderedCDS.append(self.listCDS[j]) for i in range(0,len(orderedCDS)): quotes=orderedCDS[i].getSpread() #print(quotes) myQ=MC_Vasicek_Sim(x=self.CalibrateCurve(x0=xQ,quotes=quotes,myCDS=orderedCDS[i])[0:4],datelist=[orderedCDS[i].referenceDate,orderedCDS[i].maturity],t_step=1/365,simNumber=1000).getLibor()[0] myQ=pd.DataFrame(myQ.values,columns=[orderedCDS[i].freq],index=myQ.index) orderedCDS[i].myQ=myQ #print(myQ) spread[orderedCDS[i].freq]=orderedCDS[i].getSpread() return spread
def __init__(self): self.OIS = [] self.filename = WORKING_DIR + '/CorpData.dat' self.corporates = [] self.ratings = { 'AAA': "BAMLC0A1CAAA", 'AA': "BAMLC0A2CAA", 'A': "BAMLC0A3CA", 'BBB': "BAMLC0A4CBBB", 'BB': "BAMLH0A1HYBB", 'B': "BAMLH0A2HYB", 'CCC': "BAMLH0A3HYC" } self.corpSpreads = {} self.corporates = pd.DataFrame() self.Qcorporates = pd.DataFrame() # survival function for corporates self.tenors = [] self.unPickleMe(file=self.filename) self.myScheduler = Scheduler() self.myVasicek = MC_Vasicek_Sim() self.R = 0.4
#SDE parameter t_step = 1.0/365 r0 = 0.08 sigmaR = 0.09 sigmaRef = 0.03 muR = 0.05 alphaR=3.0 simNumber=1000 muHazardRate = 0.005 k = 0.1 recovery = 0.4 #Bond parameters coupon = 0.08 #Monte Carlo trajectories creation t1 = datetime.datetime.now() myVasicek = MC_Vasicek_Sim(datelist, r0,sigmaR, sigmaRef, muR, muHazardRate,alphaR, k, simNumber,t_step) longLibor = myVasicek.getLibor() libor = myVasicek.getSmallLibor() longsurvival = myVasicek.getSurvival() survival = myVasicek.getSmallSurvival() #myVasicek.saveMeExcel() #Bond Pricing myBond = bond(libor,coupon,datelist,survival, recovery) myCDS = CDS(libor, datelist, survival, recovery) print('Risky Bond Price = ', str(1000*myBond.pv().sum())) print('Riskless Bond Price = ', str(1000*myBond.riskless().sum() )) print ('5 years Par Spread for each quarter= ', str(myCDS.parSpread())) print ('5 years Mark to Market Value for each quarter = ', myCDS.MTM())
t_step = 1.0 / 365 simNumber = 5 coupon = 0.08 fee = 1.0 xR = [3.0, 0.05, 0.04, 0.03] myBond = CouponBond(fee=fee, start=start, maturity=maturity, coupon=coupon, freq="3M", referencedate=referenceDate, observationdate=observationdate) fulllist, datelist = myBond.getScheduleComplete() myMC = MC_Vasicek_Sim() myMC.setVasicek(x=xR, minDay=minDay, maxDay=maxDay, simNumber=simNumber, t_step=t_step) myMC.getLibor() libor = myMC.getSmallLibor(datelist=fulllist) myBond.setLibor(libor) class TestBond(TestCase): def test01_PV(self): myPV = myBond.getPV(referencedate=referenceDate) print(myPV) print(myBond.pv)
freq = '1M' t_step = 1.0 / 365.0 simNumber = 10 trim_start = date(2000, 1, 1) trim_end = date(2000, 12, 31) trim_endMC = date(2001, 12, 31) effDay = date(2000, 4, 1) referenceDate = date(2000, 1, 1) testSched = pd.date_range(trim_start, trim_start) scheduleComplete = pd.date_range(start=trim_start, end=trim_end) xR = [3.0, 0.05, 0.04, 0.03] datelist = myScheduler.getSchedule(start=trim_start, end=trim_end, freq=freq, referencedate=referenceDate) myMC = MC_Vasicek_Sim() myMC.setVasicek(x=xR, minDay=trim_start, maxDay=trim_endMC, simNumber=simNumber, t_step=t_step) myMC.getLibor() myCorp = CorporateRates() myCorp.getCorporatesFred(trim_start, trim_end) testRatings = myCorp.getCorporateData("AAA", testSched) testSurvival = myCorp.getCorporateQData("AAA", scheduleComplete, 0.4) mySwap = IRSwap(zCurve=myMC.getLibor(), startDate=trim_start, endDate=trim_end, referenceDate=referenceDate,
return results.x def fCurve(self, x): calCurve = self.getLiborAvg(x, self.datelist) thisPV = np.multiple(self.cashFlows, calcCurve).mean(axis=1).sum(axis=0) error = 1e4 * (self.price - thisPV)**2 return if (__name__ == "__main__"): coupon = 0.03 myscheduler = Scheduler() datelist = myscheduler(start=trim_start, end=trim_end, freq="3M", referencedate=trim_start) myMC = MC_Vasicek_Sim(x=XR, datelist=datelist, simNumber=simnumber, t_step=t_step) libor = myMC.getSmallLibor(datelist=datelist) myBond = Bond(libor=libor, start=trim_start, maturity=trim_end, coupon=coupon, freq="3M", referencedate=trim_start) myPV = myBond.PV() print(myPV)
class CouponBond(object): def __init__(self, fee, coupon, start, maturity, freq, referencedate, observationdate, rating, notional=1, recovery=0.4): self.numSim = 10 self.t_step = 1.0 / 365 self.fee = fee self.coupon = coupon self.start = start self.maturity = maturity self.freq = freq self.recovery = recovery self.rating = rating self.referencedate = referencedate self.observationdate = observationdate self.myScheduler = Scheduler() self.delay = self.myScheduler.extractDelay(freq=freq) self.referencedate = referencedate self.getScheduleComplete() self.fullDateList = self.datelist self.ntimes = len(self.datelist) self.pvAvg = 0.0 self.cashFlows = DataFrame() self.cashFlowsAvg = [] self.yieldIn = 0.0 self.notional = notional self.errorCurve = [] self.mcSim = MC_Vasicek_Sim() def getScheduleComplete(self): self.datelist = self.myScheduler.getSchedule( start=self.start, end=self.maturity, freq=self.freq, referencedate=self.referencedate) self.ntimes = len(self.datelist) fullset = sorted( set(self.datelist).union([self.referencedate]).union([ self.start ]).union([self.maturity]).union([self.observationdate])) a = 1 return fullset, self.datelist def setLibor(self, libor): self.libor = libor / libor.loc[self.referencedate] #self.ntimes = np.shape(self.datelist)[0] self.ntrajectories = np.shape(self.libor)[1] self.ones = np.ones(shape=[self.ntrajectories]) def getExposure(self, referencedate): if self.referencedate != referencedate: self.referencedate = referencedate self.getScheduleComplete() deltaT = np.zeros(self.ntrajectories) if self.ntimes == 0: pdzeros = pd.DataFrame(data=np.zeros([1, self.ntrajectories]), index=[referencedate]) self.pv = pdzeros self.pvAvg = 0.0 self.cashFlows = pdzeros self.cashFlowsAvg = 0.0 return self.pv for i in range(1, self.ntimes): deltaTrow = ((self.datelist[i] - self.datelist[i - 1]).days / 365) * self.ones deltaT = np.vstack((deltaT, deltaTrow)) self.cashFlows = self.coupon * deltaT principal = self.ones if self.ntimes > 1: self.cashFlows[-1:] += principal else: self.cashFlows = self.cashFlows + principal if (self.datelist[0] <= self.start): self.cashFlows[0] = -self.fee * self.ones if self.ntimes > 1: self.cashFlowsAvg = self.cashFlows.mean(axis=1) * self.notional else: self.cashFlowsAvg = self.cashFlows.mean() * self.notional pv = self.cashFlows * self.libor.loc[self.datelist] self.pv = pv.sum(axis=0) * self.notional self.pvAvg = np.average(self.pv) * self.notional return self.pv def getPV(self, referencedate): self.getExposure(referencedate=referencedate) return self.pv / self.libor.loc[self.referencedate] def getFullExposure(self): fullExposure = pd.DataFrame(data=np.zeros(len(self.fullDateList)), index=self.fullDateList) for days in self.fullDateList: fullExposure.loc[days] = self.getExposure(days) self.fullExposure = fullExposure def setCorpData(self, corpData): self.corpData = corpData.loc[self.rating, :, "1 MO"] def setxQ(self, xQ): res = optimize.fmin(func=self.mcSim.errorFunction, x0=np.array([xQ[0], xQ[1]]), args=(self.corpData.values[:-1], self.corpData.values[1:], self.t_step)) xQSigma = np.std(self.corpData.values[:-1] - self.corpData.values[1:]) self.xQ = np.append(res, np.array([xQSigma, xQ[3]])) self.mcSim.setVasicek(minDay=self.start, maxDay=self.maturity, x=self.xQ, simNumber=self.numSim, t_step=self.t_step) def setQCurve(self): self.qCurve = self.mcSim.getLibor().loc[:, 0] return def getCVA(self): self.CVA = (1 - self.recovery) * self.fullExposure.loc[ self.fullDateList, 0].values * self.qCurve.loc[ self.fullDateList] * self.libor.loc[self.fullDateList, 0] def getLiborAvg(self, yieldIn, datelist): self.yieldIn = yieldIn time0 = datelist[0] # this function is used to calculate exponential single parameter (r or lambda) Survival or Libor Functions Z = np.exp(-self.yieldIn * pd.DataFrame(np.tile([(x - time0).days / 365.0 for x in self.datelist], reps=[self.ntrajectories, 1]).T, index=self.datelist)) return Z def getYield(self, price): # Fit model to curve data yield0 = 0.05 * self.ones self.price = price self.yieldIn = self.fitModel2Curve(x=yield0) return self.yieldIn def fitModel2Curve(self, x): # Minimization procedure to fit curve to model results = optimize.minimize(fun=self.fCurve, x0=x) a = 1 return results.x def fCurve(self, x): # raw data error function calcCurve = self.getLiborAvg(x, self.datelist) thisPV = np.multiply(self.cashFlows, calcCurve).mean(axis=1).sum(axis=0) error = 1e4 * (self.price - thisPV)**2 self.errorCurve = error return error
from pprint import pprint t_step = 1.0 / 365.0 simNumber = 10 trim_start = date(2005, 3, 10) trim_end = date(2010, 12, 31) # Last Date of the Portfolio start = date(2005, 3, 10) referenceDate = date(2005, 3, 10) myScheduler = Scheduler() ReferenceDateList = myScheduler.getSchedule(start=referenceDate, end=trim_end, freq="1M", referencedate=referenceDate) # Create Simulator myVasicek = MC_Vasicek_Sim() xOIS = [3.0, 0.07536509, -0.208477, 0.07536509] myVasicek.setVasicek(x=xOIS, minDay=trim_start, maxDay=trim_end, simNumber=simNumber, t_step=1 / 365.0) myVasicek.getLibor() # Create Coupon Bond with several startDates. SixMonthDelay = myScheduler.extractDelay("6M") TwoYearsDelay = myScheduler.extractDelay("2Y") startDates = [ referenceDate + nprnd.randint(0, 3) * SixMonthDelay for r in range(10) ]
class CDS(object): def __init__(self, start, end, reference, recovery, rating, notional, freq="1M"): self.numSim = 10 self.t_step = 1.0 / 365 #z curve is for discounting self.zCurve = [] #q curve is for survival prob of the reference entity self.qCurve = [] self.start = start self.end = end self.reference = reference self.freq = freq self.rating = rating self.notional = notional # mcSim used for simulating default prob, interest rate # xR should already be calibrated self.xR = [] # xQ we need to calibrate inside CDS self.xQ = [] self.mcSim = MC_Vasicek_Sim() self.mcSimSurvival = MC_Vasicek_Sim() #self.mcSim.setVasicek(minDay=startDate, maxDay=endDate, x=xR, t_step=1.0 / 365, simNumber=self.simNum) #self.mcSimSurvival.setVasicek(minDay=startDate, maxDay=endDate, x=xR, t_step=1.0 / 365, simNumber=self.simNum) self.dateList = pd.date_range(start=start, end=end, freq=freq) self.recovery = recovery def setCorpData(self, corpData): self.corpData = corpData.loc[self.rating, :, "1 MO"] def setLibor(self, libor): self.zCurve = libor / libor.loc[self.reference] def setxR(self, xR): self.xR = xR self.mcSim.setVasicek(minDay=self.start, maxDay=self.end, x=self.xR, simNumber=self.numSim, t_step=self.t_step) def setxQ(self, xQ): res = optimize.fmin(func=self.mcSimSurvival.errorFunction, x0=np.array([xQ[0], xQ[1]]), args=(self.corpData.values[:-1], self.corpData.values[1:], self.t_step)) xQSigma = np.std(self.corpData.values[:-1] - self.corpData.values[1:]) self.xQ = np.append(res, np.array([xQSigma, xQ[3]])) self.mcSimSurvival.setVasicek(minDay=self.start, maxDay=self.end, x=self.xQ, simNumber=self.numSim, t_step=self.t_step) def setQCurve(self): self.qCurve = self.mcSimSurvival.getLibor().loc[:, 0] return def getDefaultLegPV(self): interimSum = 0 for payDates in self.dateList[1:]: interimSum += self.zCurve.loc[payDates.date(), 0] * ( self.qCurve.loc[(payDates - 1).date()] - self.qCurve.loc[payDates.date()]) defaultLeg = (1 - self.recovery) * interimSum return defaultLeg def getFeeLegPV(self): delta = (self.dateList[1] - self.dateList[0]).days / 365 interimSum = 0 for payDate in self.dateList[1:]: interimSum += self.zCurve.loc[payDate.date(), 0] * delta * ( self.qCurve.loc[(payDate - 1).date()] + self.qCurve.loc[payDate.date()]) feeLeg = 0.5 * interimSum return feeLeg def getSpread(self): spread = self.getDefaultLegPV() / self.getFeeLegPV() self.spread = spread return spread def setCF(self): feeLegCF = np.ones(len(self.dateList)) * self.spread defaultLegCF = np.ones(len(self.dateList)) * ( 1 - self.recovery) * self.qCurve.loc[self.dateList].values self.feeLeg = pd.DataFrame(data=feeLegCF, index=self.dateList) self.defaultLeg = pd.DataFrame(data=defaultLegCF, index=self.dateList) return def getExposure(self): #PV of protection leg - fee leg #use survivalCurve passed in as the survival prob of the reference entitity #simulate the default probability of the counterparty - newQcurve fullDate = pd.date_range(start=self.start, end=self.end, freq=self.freq) EE = np.zeros((len(self.dateList), self.numSim)) for i in range(0, self.numSim): row = 0 newZCurve = self.mcSim.getLibor() newQCurve = self.mcSimSurvival.getLibor() survivalCurve = self.qCurve for day in fullDate: if day == fullDate[0]: #feePV - pay fee as long as counter and reference do not default feePV = np.transpose( self.feeLeg.values).ravel() * newZCurve.loc[ self.dateList, 0].values * survivalCurve.loc[ self.dateList].values * newQCurve.loc[ self.dateList, 0].values #defaultPV - recover a portion of the notional given the refernce defaults and the counterparty does NOT defaultPV = (1 - self.recovery) * np.transpose( self.defaultLeg.values).ravel() * self.zCurve.loc[ self.dateList, 0].values * ( np.ones(len(self.dateList)) - survivalCurve.loc[self.dateList].values ) * newQCurve.loc[self.dateList, 0].values elif day > fullDate[0] and day < fullDate[-1]: partialFee = self.feeLeg.loc[day.date():] partialDefault = self.defaultLeg.loc[day.date():] feePV = np.transpose( partialFee.values).ravel() * newZCurve.loc[ partialFee.index, 0].values * survivalCurve.loc[ partialFee.index].values * newQCurve.loc[ partialFee.index, 0].values defaultPV = (1 - self.recovery) * np.transpose( partialDefault.values).ravel() * self.zCurve.loc[ partialFee.index, 0].values * ( np.ones(len(partialFee.index)) - survivalCurve.loc[partialFee.index].values ) * newQCurve.loc[partialFee.index, 0].values else: feePV = 0 defaultPV = 0 npv = np.sum(defaultPV - feePV) if npv < 0: npv = 0 EE[row, i] = npv row += 1 EE = pd.DataFrame(data=EE, index=fullDate) self.fullDate = fullDate self.fullExposure = EE self.avgExposure = EE.mean(axis=1) def getCVA(self): self.CVA = self.notional * ( 1 - self.recovery) * self.avgExposure.values * self.zCurve.loc[ self.fullDate, 0].values * self.qCurve.loc[self.fullDate].values return
simNumber = 5 coupon = 0.08 fee = 1.0 xR = [3.0, 0.05, 0.04, 0.03] myBond = CouponBond(fee=fee, start=start, maturity=maturity, coupon=coupon, freq="3M", referencedate=referenceDate, observationdate=observationdate) fulllist, datelist = myBond.getScheduleComplete() myMC = MC_Vasicek_Sim(datelist=[minDay, maxDay], x=xR, simNumber=simNumber, t_step=t_step) #myMC.setVasicek(x=xR, minDay=minDay, maxDay=maxDay, simNumber=simNumber, t_step=t_step) myMC.getLibor() libor = myMC.getSmallLibor(tenors=fulllist) myBond.setLibor(libor) class TestBond(TestCase): def test01_PV(self): myPV = myBond.getPV(referencedate=referenceDate) print(myPV) print(myBond.pv) def test00_getLiborAvg(self): print(myBond.getLiborAvg(yieldIn=0.05, datelist=datelist))
from parameters import WORKING_DIR periods = '1Y' freq = '1M' t_step = 1.0 / 365.0 simNumber = 10 start = date(2005, 3, 30) trim_start = date(2000, 1, 1) trim_end = date(2000, 12, 31) referenceDate = date(2005, 3, 30) # kappa theta sigma r_0 xR = [3.0, 0.05, 0.09, 0.08] xQ = [0.1, 0.05, 0.13, 0.2] # CashFlow Dates myMC = MC_Vasicek_Sim() myMC.setVasicek(minDay=trim_start, maxDay=trim_end, x=xR, simNumber=simNumber, t_step=t_step) testSched = pd.date_range(trim_start, trim_start) scheduleComplete = pd.date_range(start=trim_start, end=trim_end) myCorp = CorporateRates() myCorp.getCorporatesFred(trim_start, trim_end) myCorp.OIS = OIS() myCorp.OIS.getOIS() rateCurve = myCorp.OIS.OIS.loc[:, "1 MO"].values rateCurveOffset = rateCurve[1:] rateCurveOffset = np.append(rateCurveOffset, rateCurve[-1]) res = optimize.fmin(func=myMC.errorFunction,
class IRSwap(object): def __init__(self, startDate, endDate, referenceDate, effectiveDate, freq, notional, recovery=0.4): """ effective date is the start of the payments, startDate is when the contract is entered, endDate is maturity referenceDate is the date when the PV is taken We are paying a fixed rate to receive a floating rate """ self.recovery = recovery self.simNum = 10 self.xR = [] self.xQ = [] # use MC to generate scenarios for exposure self.mcSim = MC_Vasicek_Sim() #self.mcSim.setVasicek(minDay=startDate,maxDay=endDate,x=xR,t_step=1.0/365, simNumber=self.simNum) # z is discount curve self.zCurve = [] self.swapRate = [] self.freq = freq self.notional = notional self.fixedLeg = [] self.floatingLeg = [] self.startDate = startDate self.endDate = endDate self.referenceDate = referenceDate self.effctiveDate = effectiveDate self.initialSpread = [] self.myScheduler = Scheduler() self.datelist = pd.date_range(start=effectiveDate, end=endDate, freq=freq) def getScheduleComplete(self): self.datelist = self.myScheduler.getSchedule( start=self.startDate, end=self.endDate, freq=self.freq, referencedate=self.referenceDate) self.ntimes = len(self.datelist) fullset = sorted( set(self.datelist).union([self.referenceDate]).union([ self.startDate ]).union([self.endDate]).union([self.referenceDate])) return fullset, self.datelist def setLibor(self, libor): self.zCurve = libor / libor.loc[self.referenceDate] def setxR(self, xR): self.xR = xR self.mcSim.setVasicek(minDay=self.startDate, maxDay=self.endDate, x=xR, t_step=1.0 / 365, simNumber=self.simNum) def setSwapRate(self): # getting initial spread at time zero floatLegPV = (self.zCurve.loc[self.effctiveDate, 0]) - (self.zCurve.loc[self.endDate, 0]) fixedLegPV = 0 delta = (self.datelist[1] - self.datelist[0]).days / 365 for payDate in self.datelist: fixedLegPV += delta * self.zCurve.loc[payDate.date(), 0] swapRate = floatLegPV / fixedLegPV self.swapRate = swapRate return def setCashFlows(self): fixedLegCF = np.ones(len(self.datelist)) * self.swapRate floatLegCF = [] delta = (self.datelist[1] - self.datelist[0]).days / 365 for payDate in self.datelist: if payDate.date() == self.endDate: floatLegCF.append( ((self.zCurve.loc[payDate.date(), 0] / self.zCurve.loc[ payDate.date() + timedelta(delta * 365), 0]) - 1) / delta) else: floatLegCF.append( (self.zCurve.loc[payDate.date(), 0] / self.zCurve.loc[ (payDate + 1).date(), 0] - 1) / delta) fixedLegCF = pd.DataFrame(data=fixedLegCF, index=self.datelist) floatLegCF = pd.DataFrame(data=floatLegCF, index=self.datelist) self.fixedLeg = fixedLegCF self.floatingLeg = floatLegCF return def getExposure(self): fullDate = pd.date_range(start=self.startDate, end=self.endDate, freq=self.freq) EE = np.zeros((len(fullDate), self.simNum)) for i in range(0, self.simNum): zCurveNew = self.mcSim.getLibor() row = 0 for day in fullDate: if day < self.datelist[0]: npv = (np.sum( (self.floatingLeg - self.fixedLeg).values.ravel() * zCurveNew.loc[self.datelist, 0].values)) elif day >= self.datelist[0] and day < self.datelist[-1]: fixedPartial = self.fixedLeg.loc[day.date():] floatPartial = self.floatingLeg.loc[day.date():] npv = (np.sum( (floatPartial - fixedPartial).values.ravel() * zCurveNew.loc[fixedPartial.index, 0].values)) else: npv = 0 #if npv < 0: # npv = 0 EE[row, i] = npv row += 1 EE = pd.DataFrame(data=EE, index=fullDate) self.fullDate = fullDate self.fullExposure = EE self.avgExposure = EE.mean(axis=1) return def getCVA(self, survCurve): # CVA = LGD * EE * PD * Discount, LGD =1-R CVA = self.notional * ( 1 - self.recovery) * self.avgExposure.values * survCurve.loc[ self.fullDate].values * self.zCurve.loc[self.fullDate, 0].values CVA = pd.DataFrame(data=CVA, index=self.fullDate) self.CVA = CVA return
t_step = 1.0 / 365.0 simNumber = 10 trim_start = date(2005, 3, 10) trim_end = date(2010, 12, 31) # Last Date of the Portfolio start = date(2005, 3, 10) referenceDate = date(2005, 3, 10) myScheduler = Scheduler() ReferenceDateList = myScheduler.getSchedule(start=referenceDate, end=trim_end, freq="1M", referencedate=referenceDate) # Create Simulator xOIS = [3.0, 0.07536509, -0.208477, 0.07536509] myVasicek = MC_Vasicek_Sim(datelist=[trim_start, trim_end], x=xOIS, simNumber=simNumber, t_step=1 / 365.0) #myVasicek.setVasicek(x=xOIS,minDay=trim_start,maxDay=trim_end,simNumber=simNumber,t_step=1/365.0) myVasicek.getLibor() # Create Coupon Bond with several startDates. SixMonthDelay = myScheduler.extractDelay("6M") TwoYearsDelay = myScheduler.extractDelay("2Y") startDates = [ referenceDate + nprnd.randint(0, 3) * SixMonthDelay for r in range(10) ] # For debugging uncomment this to choose a single date for the forward bond # print(startDates) startDates = [ date(2005, 3, 10) + SixMonthDelay,
from unittest import TestCase from parameters import xR, simNumber, t_step, trim_start, trim_end, freq, periods, referenceDate, start, inArrears, WORKING_DIR from MonteCarloSimulators.Vasicek.vasicekMCSim import MC_Vasicek_Sim from Scheduler.Scheduler import Scheduler mySchedule = Scheduler() # Global Variables mySchedule = mySchedule.getSchedule(start=trim_start, end=trim_end, freq="M") mySimulator = MC_Vasicek_Sim(datelist=mySchedule, x=xR, simNumber=simNumber, t_step=t_step) mySimulator.getLibor() mySimulator.getSmallLibor() a = 1 class TestMC_Vasicek_Sim(TestCase): def test_getLibor(self): mySimulator.getLibor() def test_getSmallLibor(self): # Monte Carlo trajectories creation - R Libor = mySimulator.getSmallLibor(mySchedule) return Libor
from unittest import TestCase from parameters import xR, simNumber, t_step, trim_start, trim_end, freq, periods, referenceDate, start, inArrears, WORKING_DIR from MonteCarloSimulators.Vasicek.vasicekMCSim import MC_Vasicek_Sim from Scheduler.Scheduler import Scheduler mySchedule = Scheduler() # Global Variables mySchedule = mySchedule.getSchedule(start=trim_start,end=trim_end, freq="M") mySimulator = MC_Vasicek_Sim(datelist=mySchedule,x=xR, simNumber=simNumber,t_step=t_step) class TestMC_Vasicek_Sim(TestCase): def test_getLibor(self): mySimulator.getLibor() def test_getSmallLibor(self): # Monte Carlo trajectories creation - R Libor = mySimulator.getSmallLibor(mySchedule) return Libor