Interest Rate Swap Valuation and Applications › Swap Risk Measures
Quantitative FinanceAll chapters Interest Rate Swap Valuation and Applications › Swap Risk MeasuresOne section · Sections in this chapter12 / 17 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Understanding how swap values respond to rate changes matters for risk management. You need to know how much money could be gained or lost as interest rates fluctuate. The key measures are DV01 (dollar value of a basis point) and swap duration, both of which quantify interest rate sensitivity.
DV01: Dollar Value of a Basis Point
DV01 is the signed local, first-order value sensitivity per one basis point (0.01%) parallel shift in the specified yield curve. It approximates a small value change; finite moves are repriced and can differ because of curvature. Comparisons across positions require the same shock, fixing convention and normalization, or explicit conversion to a common basis. The mathematical definition is:
where:
- : dollar value of a basis point
- : value of the swap
- : yield curve level (interest rate)
- : one basis point scaling factor
The minus sign makes DV01 positive for a position that gains from a small decline in the specified curve. The five-year receive-fixed example below has positive DV01 under its stated curve and fixed-current-coupon convention. That is a property of its remaining cash-flow exposure, not of the receive-fixed label alone. Preserve any already observed floating fixing in rate scenarios.
For a counterexample, take one remaining annual payment with notional , fixed rate , known floating rate , and discount factor . The net cash flow is , so its value is . A lower continuous zero rate increases and makes this negative value more negative. With one year remaining, the signed local DV01 is per 100 notional.
def calculate_swap_dv01(notional, fixed_rate, maturities, zero_rates, bump=0.0001):
"""Signed one-basis-point sensitivity for this annual-coupon example.
Value immediately after the current annual floating fixing. Set that
fixing from the base curve once and preserve the known coupon in every
parallel continuous-zero-rate shock. Future floating coupons continue
to reset. The supplied dates are the complete annual grid 1,...,T.
"""
maturities = np.asarray(maturities, dtype=float)
zero_rates = np.asarray(zero_rates, dtype=float)
if (
maturities.ndim != 1
or zero_rates.ndim != 1
or len(maturities) != len(zero_rates)
or not len(maturities)
or not np.all(np.isfinite(maturities))
or not np.all(np.isfinite(zero_rates))
or not np.allclose(maturities, np.arange(1, len(maturities) + 1))
or not np.isfinite(notional)
or notional <= 0
or not np.isfinite(fixed_rate)
or not np.isfinite(bump)
or bump <= 0
):
raise ValueError(
"Use a full annual grid, finite inputs, positive notional and bump."
)
df_original = np.exp(-zero_rates * maturities)
df_up = np.exp(-(zero_rates + bump) * maturities)
df_down = np.exp(-(zero_rates - bump) * maturities)
known_first_fixing = np.expm1(zero_rates[0] * maturities[0])
def swap_value(discounts):
fixed_bond = notional * (fixed_rate * np.sum(discounts) + discounts[-1])
floating_bond = notional * (1 + known_first_fixing) * discounts[0]
return fixed_bond - floating_bond
v_original = swap_value(df_original)
v_up = swap_value(df_up)
v_down = swap_value(df_down)
dv01 = (v_down - v_up) / (2 * bump) * 0.0001
return dv01, v_original, v_up, v_down
# Calculate DV01 for a 5-year swap
maturities_5y = np.array([1, 2, 3, 4, 5])
rates_5y = np.array([0.045, 0.048, 0.050, 0.052, 0.053])
dv01, v_base, v_up, v_down = calculate_swap_dv01(
10_000_000, 0.052, maturities_5y, rates_5y
)Swap DV01 Calculation ================================================== 5-Year Receive-Fixed Swap Notional: $10,000,000 Fixed Rate: 5.20% Scenario Analysis: Base Value: $ -89,557.62 Rates +1bp: $ -93,039.50 Rates -1bp: $ -86,073.69 DV01: $ 3,482.91
Swap Duration
A par swap has zero net market value, so ordinary modified duration, , is undefined there. We use a different, explicit reference: notional-normalized rate sensitivity,
This has units of years and does not depend on the position's notional scale. Net dollar sensitivity is fixed-bond sensitivity minus floating-bond sensitivity. In this annual example, the current floating coupon is already fixed, so the corresponding floating bond retains exposure through its next payment. It is not held at par in every shocked scenario. A short time to the next reset can justify a small-floating-duration approximation, but that is a separate stated approximation.
# Calculate notional-normalized sensitivity D_N
def calculate_swap_duration(dv01, notional):
"""Return D_N = DV01 / (notional * 0.0001), not duration divided by net MTM."""
if not np.isfinite(notional) or notional <= 0 or not np.isfinite(dv01):
raise ValueError("Use finite DV01 and positive finite notional.")
return dv01 / (notional * 0.0001)
swap_duration = calculate_swap_duration(dv01, 10_000_000)Swap Duration Analysis ================================================== 5-Year Notional-Normalized Sensitivity: 3.48 years

