Modeling Amortizing Swaps and Previously Fixed Floating Coupons
Summary
The question concerns valuing an interest rate swap whose schedule began before the valuation date. It raises two implementation issues: representing a declining notional and including a floating coupon whose rate was fixed earlier. The response gives a QuantLib construction approach rather than a pricing derivation.
For amortization, the standard VanillaSwap class does not accept a schedule of changing notionals. The answer recommends building the fixed and floating legs separately with leg constructors that accept a list of notionals, then combining them into a Swap. For the already fixed floating coupon, it recommends recording the observed historical fixing in the index so the cash flow can be calculated. The guidance is concise and does not provide a complete worked example, address curve setup, or discuss valuation conventions; details such as dates, calendars, and coupon definitions still need to match the instrument.
Key ideas
- VanillaSwap does not directly represent an amortizing notional schedule.
- Construct fixed and floating legs separately when notionals vary over time.
- Combine the constructed legs into a Swap for valuation.
- Record a known historical floating-rate fixing in the index so the past fixing can determine the coupon.
Tags
Full text
# Quantlib: Interest rate swap starting before valuation date
# Quantlib: Interest rate swap starting before valuation date
I am trying to evaluate an interest rate swap starting before the valuation date with an amortizing schedule(in Python). I am using your (i.e. Quantilb) codes but i can't figure out how to solve my problem. I am following this example http://gouthamanbalaraman.com/blog/interest-rate-swap-quantlib-python.html. The first problem is that i have nominal amount decreasing with ammortization schedule. The second, I have an evaluation date following the first reference date. So I have the first coupon of the floating rate leg already defined and I need to discount its crashflow in the swap
Thanks in advance
```
from QuantLib import *
import matplotlib.pyplot as plt
import numpy
from cookielib import MONTHS
today = Date(1,1,2017)
Settings.instance().evaluationDate = today
from matplotlib.ticker import FuncFormatter
from utils import *
def format_rate(r):
return '{0:.4f}'.format(r.rate()*100.00)
def plot_curves(*curves):
fig, ax = plt.subplots()
ax.set_xticks([0,5,10,15,20,25,30,35,40,45,50,55,60,65,100])
times = numpy.linspace(0, 61, 4000)
for curve, style in curves:
rates = [ curve.zeroRate(t, Continuous).rate() for t in times ]
plt.plot(times, rates, style)
#print zip(times, rates)
#print curve.zeroRate(1, Continuous).rate()
plt.show()
def plot_curve(curve):
plot_curves((curve,'-'))
quotes = [SimpleQuote(-0.00373), SimpleQuote(-0.00329), SimpleQuote(-0.00271)]
helpers = [SwapRateHelper(QuoteHandle(quotes[0]),Period(1, Months), TARGET(),Months, Preceding, Actual360(),Euribor1M())]
helpers.append(SwapRateHelper(QuoteHandle(quotes[1]),Period(3, Months), TARGET(),Months, Preceding, Actual360(),Euribor3M()))
helpers.append(SwapRateHelper(QuoteHandle(quotes[2]),Period(6, Months), TARGET(),Months, Preceding, Actual360(),Euribor6M()))
for rate, tenor in [(-0.00252, 1), (-0.00187, 2), (-0.00096, 3), (0.0001, 4), (0.00127, 5), (0.00247, 6), (0.00369, 7), (0.00505, 8), (0.00623, 9), (0.00732, 10), (0.00917, 12), (0.01116, 15), (0.01286, 20), (0.01349, 25), (0.01373, 30), (0.01378, 40), (0.01331, 50), (0.013, 61)]:
quotes.append(SimpleQuote(rate))
helpers.append(SwapRateHelper(QuoteHandle(quotes[-1]),Period(tenor, Years), TARGET(),Annual, Preceding, Actual360(),Euribor1Y()))
rate_curve = PiecewiseLinearZero(0, TARGET(), helpers, Actual360())
print 'reference'
print rate_curve.referenceDate()
print '-------rate_curve.dates---------------'
for i, d in enumerate(rate_curve.dates()):
print i+1, d, d.weekday()
curve_handle = RelinkableYieldTermStructureHandle(rate_curve)
fixed_schedule = Schedule(Date(22, 6, 2017), Date(22, 6, 2020),Period(6, Months), TARGET(), Preceding, Preceding, DateGeneration.Forward, False)
floating_schedule = Schedule(Date(22, 6, 2017), Date(22, 6, 2020),Period(6, Months), TARGET(), Preceding, Preceding, DateGeneration.Forward, False)
print '----------fixed_schedule----------------'
for i, d in enumerate(fixed_schedule):
print i+1, d
print '----------floating_schedule-------------'
for i, d in enumerate(floating_schedule):
print i+1, d
index = Euribor1Y(curve_handle)
discountTermStructure = RelinkableYieldTermStructureHandle()
swap = VanillaSwap(VanillaSwap.Receiver,1000000, fixed_schedule, 0.2, Actual360(), floating_schedule, index, 0.185, Actual360())
swap_engine = DiscountingSwapEngine(curve_handle)
swap.setPricingEngine(swap_engine)
print '-----leg 0 ----------------------'
for i, cf in enumerate(swap.leg(0)):
print "%2d %-18s %10.4f"%(i+1, cf.date(), cf.amount())
print '-----leg 1 ----------------------'
for i, cf in enumerate(swap.leg(1)):
print "%2d %-18s %10.4f"%(i+1, cf.date(), cf.amount())
swap.setPricingEngine(DiscountingSwapEngine(curve_handle))
P0 = swap.NPV()
print '----floatingLegNPV-----'
print swap.floatingLegNPV()
print '----fixedLegNPV-----'
print swap.fixedLegNPV()
print '----NPV-----'
print P0
plot_curve(rate_curve)
```
Best regards Matteo
## Answer by Luigi Ballabio (score 0)
https://quant.stackexchange.com/a/35334
For the first problem: `VanillaSwap` doesn't allow amortization. You'll have to create the fixed and floating legs with `FixedRateLeg` and `IborLeg` (which take a list of notionals) and use them to build an instance of the `Swap` class.
For the second, if the rate of the floating cashflow has been fixed on date `d` to a rate `r`, you can run
```
index.addFixing(d, r);
```
to store the information and make it available for calculation.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.