# swap to forward rates

4 messages
Open this post in threaded view
|

## swap to forward rates

 Again, I want to calculate forward rates from swap rates. Krishna Kumar was already very kind to help me here (24.1.06) and he provided an algorithm, I did not understand. So I now figured out my own one and unfortunately the two results do not coincide but both appear very plausible. How can you help me? If you have a lot of time, check my algorithm or my formula. If you have already implemented this yourself somewhere, please compare my results with yours and with those of Kris. And let me know about your results. Perhaps you can have a quick look at this and verify the results. I have EUR-swap rates for 2Y, 3Y, 5Y, 7Y, 10Y, 20Y and 30Y, eg for 2005-12-13: sc=list(   maturity=c(2,3,5,7,10,20),   tenors=c(2,1,2,2,3,10),    #the difference between two dates (=\tau_i)   rate=c(0.02982,0.03074,0.03230,0.03354,0.03533,0.03861),   date="2005-12-13"   ); #Kris' way from swap via discount to forward rates: swap2discount<-function(swapcrv) {   n<-length(swapcrv$rate) dfcrv<-list() dfcrv$maturity    <- swapcrv$maturity dfcrv$discount    <- 1/(1+swapcrv$tenors*swapcrv$rate)   dfcrv$discount[-1]<- dfcrv$discount[-1]*(1-(cumsum(swapcrv$tenors[-n]*dfcrv$discount[-n]))*swapcrv$rate[-1]) dfcrv$date=swapcrv$date return(dfcrv) } discount2fwd<-function(dfcurve,times=dfcurve$maturity) {   times<-c(0,times)   n<-length(times)   fwd<-array(0,n)   df.tenor<-array(0,n)   df.tenor<-approx(x=dfcurve$maturity,y=dfcurve$discount,xout=times,rule=2)$y df.tenor[1]<-1 fwd<-(df.tenor[-n]/df.tenor[-1] -1)/diff(times) fwd<-c(fwd[1],fwd) return(list(maturity=times,rate=fwd,date=dfcurve$date)) } dc=swap2discount(sc) discount2fwd(dc) #gives rates:  0.02982000 0.03264006 0.03592894 0.04081783 0.04582491 0.05007956 #my function: # from Brigo/Mercurio, p.15; solve the last equation on this page for F_\beta: # $$\1+\tau_\beta F_\beta = \frac{1+S_{\alpha,\beta}(t) \tau_\beta}{\Pi_{j=\alpha+1}^{\beta-1}(1+\tau_jF_j) - S_{\alpha,\beta}(t)\Sum_{i=\alpha+1}^{\beta-1}\tau_i\Pi_{j=i+1}^{\beta-1}(1+\tau_jF_j) }$$ swap2fwd<-function(sc) {   fwd=array(dim=length(sc$rate)) fwd[1]=sc$rate[1]   fwd[2]=( (1+sc$rate[2]*sc$tenors[2])/(1+sc$tenors[1]*fwd[1]-sc$rate[2]*sc$tenors[1])-1 ) / sc$tenors[2]   n<-length(sc$maturity) for (t in 3:n) { cumpr=rev(c(1, cumprod(1+sc$tenors[(t-1):2]*fwd[(t-1):2]) ))     su=sum( sc$tenors[1:(t-1)] * cumpr ) fwd[t]=(1+sc$rate[t]*sc$tenors[t]) / ( prod(1+sc$tenors[1:(t-1)]*fwd[1:(t-1)])-sc$rate[t]*su ) fwd[t]=(fwd[t]-1)/sc$tenors[t]   }   return(list(     maturity=sc$maturity,rate=fwd,date=sc$date     )) } swap2fwd(sc) #gives 0.02982000 0.03264006 0.03485760 0.03705553 0.04046209 0.04409305 My results are a bit lower then Kris'. What do you suggest me to use now? A pro's solution I don't understand or my own answer? If I add the 30Y swap rate (0.03922), results are strage again in both cases (too high and to low respectively). What I did not take into account are daycount conventions and the fact the the very first point in the swap curve should be a cash rate. This will come later... Any help, hint and comparison is very welcome. Thomas _______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance
Open this post in threaded view
|

## Re: swap to forward rates

 Dear David, thanks for you answer. > There are many algorithms for constructing a yield curve from market > data. > They all give different answers, some wildly. But why? Describing the term structure of interest rates by forward rates is mathematically equivalent (no market model assumed, just no arbitrage) to tell the swap rates. So there should be an exact way in principle, no? > I don't see how you can get the first fwd rate without at least one > cash. I mentioned this at the end of my message: I will add this later, right now I assume that the first point in the swap curve is a cash yield. > You will also get quite different results by not taking market > conventions into account. Thanks, I didn't know that - I thought that results should be at about the same (not 60bps difference). > This is one big reason why people are willing > to spend serious money for yield curve sotware. I am working at university and I try to find the cheapest way possible... Can you give any of your results with my rates, just to compare? Any other comments, hints? Thomas _______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance
 In reply to this post by Thomas Steiner To re-emphasize what David has mentioned and what was in the earlier West-Hagan paper, depending on the interpolation technique used one can get completely different set of rates. And people use smoothness and other criteria to pick the method. If you play around with different interpolation like cubic spline in akima and other interpolation methods that are in CRAN you will notice that the forward is smooth for some and jagged for others. What I sent is a very rudimentary - curve-101, perhaps you should also look at these additional documents as well , http://www.fincad.com/newsletter.asp?i=1180&a=2180http://www.bankofcanada.ca/en/res/wp/2000/wp00-17.pdfhttp://www.hfb.de/Dateien/Arbeitsbericht2.pdf{Most banks have people who are specialized in just building curves..} The reason why it is good to go via discount factors is that some of the curves are blended meaning they have a mix of instrument like repos or muni instruments. In other cases people use E$futures or other market instruments. The criteria on what instruments to use in your curve, is typically a) liquidity and b) your positions in the markets. Because you want to compute the correct funding for your positions. Finally you need to get the day counts right that is important and the recent email on seq.date might help you on this. Hope this helps, Kris Thomas Steiner wrote: >Again, I want to calculate forward rates from swap rates. >Krishna Kumar was already very kind to help me here (24.1.06) and he >provided an algorithm, I did not understand. So I now figured out my >own one and unfortunately the two results do not coincide but both >appear very plausible. > >How can you help me? >If you have a lot of time, check my algorithm or my formula. >If you have already implemented this yourself somewhere, please >compare my results with yours and with those of Kris. And let me know >about your results. > >Perhaps you can have a quick look at this and verify the results. > >I have EUR-swap rates for 2Y, 3Y, 5Y, 7Y, 10Y, 20Y and 30Y, eg for 2005-12-13: > >sc=list( > maturity=c(2,3,5,7,10,20), > tenors=c(2,1,2,2,3,10), #the difference between two dates (=\tau_i) > rate=c(0.02982,0.03074,0.03230,0.03354,0.03533,0.03861), > date="2005-12-13" > ); > >#Kris' way from swap via discount to forward rates: >swap2discount<-function(swapcrv) { > n<-length(swapcrv$rate) >  dfcrv<-list() >  dfcrv$maturity <- swapcrv$maturity >  dfcrv$discount <- 1/(1+swapcrv$tenors*swapcrv$rate) > dfcrv$discount[-1]<- >dfcrv$discount[-1]*(1-(cumsum(swapcrv$tenors[-n]*dfcrv$discount[-n]))*swapcrv$rate[-1]) >  dfcrv$date=swapcrv$date >  return(dfcrv) >} >discount2fwd<-function(dfcurve,times=dfcurve$maturity) { > times<-c(0,times) > n<-length(times) > fwd<-array(0,n) > df.tenor<-array(0,n) > df.tenor<-approx(x=dfcurve$maturity,y=dfcurve$discount,xout=times,rule=2)$y >  df.tenor[1]<-1 >  fwd<-(df.tenor[-n]/df.tenor[-1] -1)/diff(times) >  fwd<-c(fwd[1],fwd) >  return(list(maturity=times,rate=fwd,date=dfcurve$date)) >} >dc=swap2discount(sc) >discount2fwd(dc) >#gives rates: 0.02982000 0.03264006 0.03592894 0.04081783 0.04582491 0.05007956 > >#my function: ># from Brigo/Mercurio, p.15; solve the last equation on this page for F_\beta: ># $$\1+\tau_\beta F_\beta = \frac{1+S_{\alpha,\beta}(t) >\tau_\beta}{\Pi_{j=\alpha+1}^{\beta-1}(1+\tau_jF_j) - >S_{\alpha,\beta}(t)\Sum_{i=\alpha+1}^{\beta-1}\tau_i\Pi_{j=i+1}^{\beta-1}(1+\tau_jF_j) >}$$ >swap2fwd<-function(sc) { > fwd=array(dim=length(sc$rate)) >  fwd[1]=sc$rate[1] > fwd[2]=( (1+sc$rate[2]*sc$tenors[2])/(1+sc$tenors[1]*fwd[1]-sc$rate[2]*sc$tenors[1])-1 >) / sc$tenors[2] > n<-length(sc$maturity) >  for (t in 3:n) { >    cumpr=rev(c(1, cumprod(1+sc$tenors[(t-1):2]*fwd[(t-1):2]) )) > su=sum( sc$tenors[1:(t-1)] * cumpr ) >    fwd[t]=(1+sc$rate[t]*sc$tenors[t]) / ( >prod(1+sc$tenors[1:(t-1)]*fwd[1:(t-1)])-sc$rate[t]*su ) >    fwd[t]=(fwd[t]-1)/sc$tenors[t] > } > return(list( > maturity=sc$maturity,rate=fwd,date=sc\$date >    )) >} >swap2fwd(sc) >#gives 0.02982000 0.03264006 0.03485760 0.03705553 0.04046209 0.04409305 > >My results are a bit lower then Kris'. What do you suggest me to use >now? A pro's solution I don't understand or my own answer? >If I add the 30Y swap rate (0.03922), results are strage again in both >cases (too high and to low respectively). > >What I did not take into account are daycount conventions and the fact >the the very first point in the swap curve should be a cash rate. This >will come later... > >Any help, hint and comparison is very welcome. >Thomas > >_______________________________________________ >[hidden email] mailing list >https://stat.ethz.ch/mailman/listinfo/r-sig-finance> >   > _______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance