Interest Rate Swaps - Fundamentals › Building a Swap Cash Flow Calculator

Michael BrenndoerferNovember 16, 20255 min read
Quantitative FinanceAll chapters
Part 4 of 15Swaps and Credit Derivatives
Chapter 20Interest Rate Swaps - Fundamentals › Building a Swap Cash Flow Calculator
Reading section 7 of 10 · Building a Swap Cash Flow Calculator · 5 minSection 7 of 10 · 5 min

Book contents

Section 7 of 10 · 5 min read

Interest Rate Swaps - Fundamentals › Building a Swap Cash Flow CalculatorOne section · Sections in this chapter7 / 10 ↓
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

Let's build a more complete implementation that can generate swap cash flow schedules for analysis. This calculator demonstrates how the concepts we have discussed translate into practical computation. The function takes swap parameters as inputs and produces a detailed schedule showing each payment throughout the swap's life.

In[20]:
Code
from datetime import date

import pandas as pd
from dateutil.relativedelta import relativedelta


def generate_swap_schedule(
    notional: float,
    fixed_rate: float,
    start_date: date,
    maturity_years: int,
    floating_rates: list,
    fixed_frequency: str = "semi-annual",
    floating_frequency: str = "quarterly",
) -> pd.DataFrame:
    """
    Generate cash flow schedule for a pay-fixed, receive-floating swap.

    Parameters:
    -----------
    notional : float
        Notional principal amount
    fixed_rate : float
        Annual fixed rate (e.g., 0.04 for 4%)
    start_date : date
        Effective date of the swap
    maturity_years : int
        Number of years until maturity
    floating_rates : list
        Observed floating rates for each floating payment period
    fixed_frequency : str
        'semi-annual' or 'annual' for fixed leg
    floating_frequency : str
        'quarterly' or 'semi-annual' for floating leg

    Returns:
    --------
    pd.DataFrame with detailed cash flow schedule
    """
    # Determine number of periods
    if floating_frequency == "quarterly":
        float_periods = maturity_years * 4
        float_months = 3
    else:  # semi-annual
        float_periods = maturity_years * 2
        float_months = 6

    if fixed_frequency == "semi-annual":
        fixed_periods_per_year = 2
        fixed_months = 6
    else:  # annual
        fixed_periods_per_year = 1
        fixed_months = 12

    # Calculate day count fractions
    # Fixed: 30/360
    fixed_dcf = (30 * fixed_months) / 360
    fixed_payment = notional * fixed_rate * fixed_dcf

    # Build schedule
    schedule = []
    current_date = start_date

    for i in range(float_periods):
        period_end = current_date + relativedelta(months=float_months)
        actual_days = (period_end - current_date).days

        # Floating payment (Actual/360)
        float_dcf = actual_days / 360
        float_payment = notional * floating_rates[i] * float_dcf

        # Fixed payment (only on fixed payment dates)
        if (
            floating_frequency == "quarterly"
            and fixed_frequency == "semi-annual"
        ):
            # Fixed pays every 2 floating periods
            is_fixed_payment = (i + 1) % 2 == 0
        else:
            is_fixed_payment = True

        fixed_pay = fixed_payment if is_fixed_payment else 0
        net_cf = float_payment - fixed_pay

        schedule.append(
            {
                "Period": i + 1,
                "Start Date": current_date,
                "End Date": period_end,
                "Days": actual_days,
                "Floating Rate": floating_rates[i],
                "Floating DCF": float_dcf,
                "Floating Payment": float_payment,
                "Fixed Payment": fixed_pay,
                "Net Cash Flow": net_cf,
            }
        )

        current_date = period_end

    return pd.DataFrame(schedule)

Now let's use this function to analyze a swap:

In[21]:
Code
# Example swap parameters
swap_notional = 100_000_000
swap_fixed = 0.0425
swap_start = date(2024, 3, 15)
swap_maturity = 3  # years

# Generate realistic floating rate path
np.random.seed(123)
initial_sofr = 0.0420
n_quarters = swap_maturity * 4

# Simple rate path with mean reversion
rates = [initial_sofr]
for _ in range(n_quarters - 1):
    # Mean-reverting process
    drift = 0.1 * (0.04 - rates[-1])  # Revert toward 4%
    shock = np.random.normal(0, 0.004)
    new_rate = max(0, rates[-1] + drift + shock)
    rates.append(new_rate)

# Generate the schedule
swap_schedule = generate_swap_schedule(
    notional=swap_notional,
    fixed_rate=swap_fixed,
    start_date=swap_start,
    maturity_years=swap_maturity,
    floating_rates=rates,
    fixed_frequency="semi-annual",
    floating_frequency="quarterly",
)
Out[22]:
Console
3-Year Interest Rate Swap Analysis
Notional: $100 million
Fixed Rate: 4.25% (semi-annual, 30/360)
Floating: Quarterly resets, Actual/360
==========================================================================================
 Period   End Date  Days Floating Rate Floating Payment Fixed Payment Net Cash Flow
      1 2024-06-15    92        4.200%       $1,073,333             -    $1,073,333
      2 2024-09-15    92        3.746%         $957,247    $2,125,000   $-1,167,753
      3 2024-12-15    91        4.170%       $1,054,111             -    $1,054,111
      4 2025-03-15    90        4.266%       $1,066,573    $2,125,000   $-1,058,427
      5 2025-06-15    92        3.637%         $929,492             -      $929,492
      6 2025-09-15    92        3.442%         $879,620    $2,125,000   $-1,245,380
      7 2025-12-15    91        4.158%       $1,051,142             -    $1,051,142
      8 2026-03-15    90        3.172%         $792,964    $2,125,000   $-1,332,036
      9 2026-06-15    92        3.083%         $787,905             -      $787,905
     10 2026-09-15    92        3.681%         $940,744    $2,125,000   $-1,184,256
     11 2026-12-15    91        3.366%         $850,940             -      $850,940
     12 2027-03-15    90        3.158%         $789,542    $2,125,000   $-1,335,458
==========================================================================================
Total Floating Received: $11,173,614
Total Fixed Paid: $12,750,000
Net Total (undiscounted): $-1,576,386

Visualizing the Swap Profile

Out[23]:
Visualization
Line chart showing floating rate fluctuating around a fixed rate line.
Comparison of floating and fixed rates over the three-year swap term. Separate shaded areas identify periods where the floating rate is above or below the fixed rate.
Bar chart displaying positive and negative net cash flows corresponding to rate differences.
Net cash flows for the fixed-rate payer. Positive flows occur when the floating rate is higher, offsetting negative flows when the floating rate drops below the fixed rate.

The visualization shows the relationship between the fixed and floating rates and the resulting net cash flows. Green regions indicate periods where floating rates exceed the fixed rate, generating positive net cash flows for the fixed-rate payer. Red regions show the opposite situation.