Session 10: Fixed Income Analysis

Contents

Session 10: Fixed Income Analysis#

Understanding Bonds, Yields, and Interest Rate Risk#

Learning Objectives#

By the end of this session, you will be able to:

  1. Calculate Bond Prices and Yields - Apply present value principles to value bonds and compute yields with professional precision

  2. Measure Interest Rate Risk - Calculate duration and convexity to quantify bond price sensitivity to rate changes

  3. Analyze Credit Risk - Evaluate corporate bonds using credit spreads, default probabilities, and recovery rates

  4. Construct Bond Portfolios - Build fixed income portfolios with appropriate duration matching and risk controls

  5. Present Fixed Income Analysis Professionally - Communicate bond valuation and risk analysis clearly in video presentations


Section 1: The Financial Hook - The $30 Billion Duration Disaster#

Two Portfolio Managers, Two Outcomes#

In early 2022, two pension fund managers faced the same challenge - managing $10 billion fixed income portfolios as interest rates began to rise:

Manager A (Silicon Valley Pension Fund):

  • “Bonds are safe - I’ll buy long-term for higher yields”

  • Loaded up on 30-year bonds at 2% yields

  • Ignored duration risk (20+ years duration)

  • Result: Lost $3 billion (-30%) when rates hit 4%

  • Forced to sell at losses to meet pension payments

Manager B (Texas Teachers Retirement):

  • “I manage duration risk systematically”

  • Built bond ladder with 5-year average duration

  • Implemented duration matching to liabilities

  • Result: Lost $800 million (-8%) but met all obligations

  • Rebalanced into higher yields opportunistically

The Lesson: Understanding duration and systematic bond analysis is the difference between catastrophic losses and professional risk management.

What Makes Bonds Complex?#

Bonds vs. Stocks - The Hidden Complexity:

📊 BOND COMPLEXITY FACTORS

Price Drivers:
├── Interest Rate Changes (biggest risk)
├── Credit Quality Changes
├── Time to Maturity (pull to par)
├── Reinvestment of Coupons
└── Embedded Options (calls, puts)

Risk Dimensions:
├── Duration Risk (rate sensitivity)
├── Convexity (non-linear effects)
├── Credit Risk (default probability)
├── Liquidity Risk (can you sell?)
└── Inflation Risk (real returns)

Market Structure:
├── OTC Trading (no central exchange)
├── \$1,000+ minimums
├── Dirty vs Clean Prices
├── Accrued Interest
└── Day Count Conventions

Real-World Impact#

2022 Bond Market Crash:

  • 10-year Treasury yields: 1.5% → 4.0%

  • Long-term bond ETF (TLT): -31% loss

  • Investment grade corporate bonds: -18%

  • Even “safe” bonds lost massive value

Who Got Hurt:

  • Banks with long-duration assets (SVB collapse)

  • Insurance companies with asset-liability mismatches

  • Retail investors in target-date funds

  • Anyone who thought “bonds = safe”

Why Duration Matters#

What is Duration? Duration measures how sensitive a bond’s price is to interest rate changes. Think of it like a seesaw - the longer the duration, the more the price moves when rates change. A 10-year duration means a 1% rate rise causes approximately 10% price decline.

The Math That Matters:

  • 30-year bond at 2%: Duration ≈ 20 years

  • If rates rise to 4%: Price falls ≈ 20 × 2% = 40%

  • Your “safe” bond just lost 40% of value!

🎯 AI Learning Support - Understanding Bond Risks#

Learning Goal: Develop intuition for why interest rate changes devastate bond prices

Starting Prompt: “Explain why bond prices fall when interest rates rise”

🚀 Hints to Improve Your Prompt:

  • Add specific bond examples (30-year vs 2-year)

  • Include numerical calculations

  • Ask about duration’s role

  • Request real 2022 examples

💡 Better Version Hints:

  • Compare different bond types’ sensitivity

  • Include credit risk interaction

  • Ask about portfolio implications

  • Request risk management strategies

🎯 Your Challenge: Create a prompt that helps you explain to a client why their “safe” bond fund lost 20% in 2022


Section 2: Foundational Financial Concepts & Models#

Core Bond Mathematics#

1. Bond Pricing Fundamentals#

What is Present Value? Present value is today’s worth of future cash flows. For bonds, we discount all future coupon payments and the final principal payment back to today. It’s like asking: “How much would I pay today to receive these future payments?”

Bond Price Formula: $\(P = \sum_{t=1}^{n} \frac{C}{(1+y)^t} + \frac{M}{(1+y)^n}\)$

Where:

  • \(P\) = Bond price

  • \(C\) = Coupon payment

  • \(y\) = Yield to maturity (per period)

  • \(M\) = Maturity value (face value)

  • \(n\) = Number of periods

Key Relationships:

  • When Coupon Rate > Yield → Premium Bond (Price > Par)

  • When Coupon Rate < Yield → Discount Bond (Price < Par)

  • When Coupon Rate = Yield → Par Bond (Price = Par)

2. Yield Measures#

Current Yield: $\(\text{Current Yield} = \frac{\text{Annual Coupon}}{\text{Current Price}}\)$

Yield to Maturity (YTM): The discount rate that makes the present value of cash flows equal to the bond price. Solved iteratively - no closed-form solution.

Tax-Equivalent Yield (for municipal bonds): $\(\text{TEY} = \frac{\text{Municipal Yield}}{1 - \text{Tax Rate}}\)$

3. Duration Analysis#

What is Duration? Duration is the weighted average time to receive cash flows, but more importantly, it measures price sensitivity to yield changes. Think of it as the “center of gravity” of a bond’s cash flows.

Macaulay Duration: $\(D_{Mac} = \frac{\sum_{t=1}^{n} t \times \frac{CF_t}{(1+y)^t}}{P}\)$

Modified Duration (price sensitivity): $\(D_{Mod} = \frac{D_{Mac}}{1 + \frac{y}{m}}\)$

Where \(m\) = compounding frequency per year

Price Change Approximation: $\(\%\Delta P \approx -D_{Mod} \times \Delta y\)$

Convexity (second-order effect): $\(\text{Convexity} = \frac{1}{P} \times \frac{\sum_{t=1}^{n} t(t+1) \times \frac{CF_t}{(1+y)^{t+2}}}{(1+y)^2}\)$

4. Credit Risk Framework#

Credit Spread: $\(\text{Credit Spread} = \text{Corporate Yield} - \text{Treasury Yield}\)$

Expected Loss: $\(\text{Expected Loss} = \text{PD} \times \text{LGD}\)$

Where:

  • PD = Probability of Default

  • LGD = Loss Given Default = (1 - Recovery Rate)

Bond Categories#

Government Bonds:

  • Treasury Securities: “Risk-free” benchmark

  • TIPS: Inflation protection

  • Municipal Bonds: Tax advantages

  • Agency Bonds: Quasi-government

Corporate Bonds:

  • Investment Grade (BBB- and above)

  • High Yield (Below BBB-)

  • Convertible Bonds

  • Callable/Putable Bonds

Rating Scale:

  • AAA: Highest quality

  • AA, A: High quality

  • BBB: Medium quality (lowest investment grade)

  • BB, B: Speculative

  • CCC, CC, C: High default risk

  • D: In default

🎯 AI Learning Support - Bond Mathematics#

Learning Goal: Master the mathematical relationships in bond pricing

Starting Prompt: “Show me how to calculate a bond’s price step by step”

🚀 Hints to Improve Your Prompt:

  • Specify bond parameters (coupon, maturity, yield)

  • Ask for Excel/calculator steps

  • Include semi-annual payments

  • Request price change examples

💡 Better Version Hints:

  • Compare premium vs discount bonds

  • Include duration in calculation

  • Ask about reinvestment assumptions

  • Request sensitivity analysis

🎯 Your Challenge: Create a prompt that helps you build a bond pricing calculator from scratch


Section 3: The Financial Gym - Partner Practice & AI Copilot Learning#

Exercise 1: Bond Pricing Basics#

Individual Task (15 minutes): Calculate prices for these bonds (assume annual coupons, $1,000 face value):

# Bond specifications
bonds = {
    'Bond A': {'coupon_rate': 0.05, 'years': 5, 'yield': 0.04},
    'Bond B': {'coupon_rate': 0.03, 'years': 10, 'yield': 0.05},
    'Bond C': {'coupon_rate': 0.06, 'years': 3, 'yield': 0.06}
}

# Your task:
# 1. Calculate each bond's price
# 2. Identify premium/discount/par
# 3. Calculate current yield

🎯 AI Learning Support - Bond Calculations#

Learning Goal: Master manual bond pricing calculations

Starting Prompt: “Walk me through calculating Bond A’s price by hand”

🚀 Hints to Improve Your Prompt:

  • Ask for year-by-year cash flows

  • Request present value of each flow

  • Include summation steps

  • Ask for Excel formula equivalent

💡 Better Version Hints:

  • Compare different calculation methods

  • Include financial calculator steps

  • Ask about common mistakes

  • Request validation checks

🎯 Your Challenge: Calculate all three bonds’ prices and teach your partner the shortcut method

Exercise 2: Duration Calculation#

Partner Exercise (20 minutes):

Step 1: Each partner calculates duration for one bond

  • Partner A: 5% coupon, 10-year bond at 4% yield

  • Partner B: 2% coupon, 10-year bond at 4% yield

Step 2: Compare results and discuss:

  • Why are the durations different?

  • Which bond is riskier?

  • What happens if rates rise 1%?

Step 3: Teach each other:

  • Partner A explains Macaulay duration

  • Partner B explains Modified duration

🎯 AI Learning Support - Duration Analysis#

Learning Goal: Understand duration as a risk measure

Starting Prompt: “Help me calculate duration for a 10-year bond”

🚀 Hints to Improve Your Prompt:

  • Specify all bond parameters

  • Ask for intuitive explanation

  • Request Excel implementation

  • Include price sensitivity check

💡 Better Version Hints:

  • Compare different bonds’ durations

  • Ask about duration rules of thumb

  • Request portfolio duration

  • Include convexity effects

🎯 Your Challenge: Create a duration comparison table and explain which bonds are riskiest

Exercise 3: Credit Analysis#

Group Challenge (25 minutes):

Analyze these corporate bonds:

# Corporate bond data
corporate_bonds = {
    'AAA Corp': {'yield': 0.045, 'treasury_yield': 0.04, 'rating': 'AAA'},
    'BBB Corp': {'yield': 0.055, 'treasury_yield': 0.04, 'rating': 'BBB'},
    'B Corp': {'yield': 0.08, 'treasury_yield': 0.04, 'rating': 'B'}
}

# Tasks:
# 1. Calculate credit spreads
# 2. Estimate default probabilities
# 3. Which offers best risk-adjusted return?

🎯 AI Learning Support - Credit Analysis#

Learning Goal: Evaluate credit risk systematically

Starting Prompt: “How do I analyze credit risk for corporate bonds?”

🚀 Hints to Improve Your Prompt:

  • Include specific ratings

  • Ask for default probability data

  • Request spread analysis

  • Include recovery rate assumptions

💡 Better Version Hints:

  • Compare across rating categories

  • Ask about spread changes

  • Request downgrade risks

  • Include portfolio implications

🎯 Your Challenge: Build a credit analysis framework and present to the class

Reflection & Discussion#

Class Discussion (10 minutes):

  1. Duration Insights: What surprised you about duration calculations?

  2. Credit vs Rate Risk: Which risk is more important? When?

  3. Portfolio Applications: How would you build a bond portfolio?

  4. Market Conditions: What’s happening in bond markets now?

Key Takeaways:

  • Duration quantifies interest rate risk

  • Credit spreads compensate for default risk

  • Bond math is precise but tedious

  • Systematic analysis beats intuition


Section 4: The Financial Coaching - Your DRIVER Learning Guide#

Let’s build a complete bond analysis system using the DRIVER framework.

Case Study: Managing a Corporate Bond Portfolio#

Scenario: You’re a fixed income analyst at a $50 billion pension fund. The CIO wants you to analyze potential bond investments and recommend a portfolio strategy as rates are expected to rise.

D - Discover: Understanding Bond Markets#

Your Task: Explore current bond market conditions and risks.

# DISCOVER: Bond market analysis
print("=== DISCOVERING BOND MARKET DYNAMICS ===")

# Current market conditions (late 2024)
market_data = {
    '2Y_Treasury': 0.045,
    '10Y_Treasury': 0.042,
    '30Y_Treasury': 0.044,
    'IG_Spread': 0.012,   # Investment Grade spread
    'HY_Spread': 0.035,   # High Yield spread
    'Fed_Funds': 0.05
}

# Key questions to explore:
# 1. Why is yield curve inverted?
# 2. What drives credit spreads?
# 3. How do rate changes impact bonds?
# 4. What are current market risks?

print("Market Analysis:")
print(f"  Yield Curve Shape: Inverted")
print(f"  10Y-2Y Spread: {(market_data['10Y_Treasury'] - market_data['2Y_Treasury'])*100:.0f} bps")
print(f"  Credit Conditions: Tight spreads")
print(f"  Rate Environment: Restrictive")

🎯 AI Learning Support - Discover#

Learning Goal: Understand current bond market dynamics

Starting Prompt: “Explain what an inverted yield curve means for bond investors”

🚀 Hints to Improve Your Prompt:

  • Ask about recession implications

  • Include duration strategy impacts

  • Request historical examples

  • Ask about credit spread behavior

💡 Better Version Hints:

  • Compare different curve environments

  • Include international perspectives

  • Ask about central bank impacts

  • Request portfolio strategies

🎯 Your Challenge: Identify three risks and three opportunities in current bond markets

R - Represent: Design Bond Analysis Framework#

Your Task: Create systematic bond evaluation process.

# REPRESENT: Bond analysis framework
print("\n=== REPRESENTING BOND FRAMEWORK ===")

# Analysis framework
bond_framework = {
    'valuation': {
        'price_calculation': 'PV of cash flows',
        'yield_measures': ['YTM', 'Current', 'TEY'],
        'relative_value': 'Spread analysis'
    },
    'risk_metrics': {
        'duration': 'Interest rate sensitivity',
        'convexity': 'Non-linear effects',
        'credit': 'Default probability',
        'liquidity': 'Trading volume'
    },
    'portfolio_fit': {
        'duration_match': 'Liability alignment',
        'credit_quality': 'Risk budget',
        'diversification': 'Sector/issuer limits'
    }
}

# Investment criteria
criteria = {
    'min_yield': 0.04,      # 4% minimum
    'max_duration': 7,      # Years
    'min_rating': 'BBB',    # Investment grade
    'max_position': 0.05    # 5% concentration
}

print("Analysis Framework:")
for category, items in bond_framework.items():
    print(f"\n{category.title()}:")
    for metric, description in items.items():
        print(f"  {metric}: {description}")

🎯 AI Learning Support - Represent#

Learning Goal: Design comprehensive bond analysis process

Starting Prompt: “Help me create a bond evaluation checklist for institutional investors”

🚀 Hints to Improve Your Prompt:

  • Specify investor type (pension, insurance)

  • Include risk constraints

  • Ask for relative value metrics

  • Request red flags to avoid

💡 Better Version Hints:

  • Include scenario analysis

  • Ask about benchmark comparison

  • Request ESG considerations

  • Include liquidity assessment

🎯 Your Challenge: Create a one-page bond scorecard for investment committee

I - Implement: Build Bond Analysis System#

Your Task: Implement bond valuation and risk analysis.

# IMPLEMENT: Bond analysis system
print("\n=== IMPLEMENTING BOND ANALYSIS ===")

# Step 1: Set up bond parameters
face_value = 1000         # Bond face value in dollars
coupon_rate = 0.05        # 5% annual coupon rate
years = 10                # 10 years to maturity
market_yield = 0.06       # 6% market yield (YTM)
frequency = 2             # Semi-annual payments

print("Bond Analysis:")
print(f"  Face Value: ${face_value}")
print(f"  Coupon: {coupon_rate:.1%}")
print(f"  Maturity: {years} years")
print(f"  Market Yield: {market_yield:.1%}")

# Step 2: Calculate basic bond metrics
periods = years * frequency  # Total number of payment periods
coupon_payment = (coupon_rate * face_value) / frequency  # Payment per period
yield_per_period = market_yield / frequency  # Yield per period

print(f"\nPayment Details:")
print(f"  Coupon Payment: ${coupon_payment:.2f} every 6 months")
print(f"  Total Periods: {periods}")
print(f"  Yield per Period: {yield_per_period:.3%}")

# Step 3: Calculate present value of all coupon payments
pv_coupons = 0  # Initialize sum of present values
for t in range(1, periods + 1):
    # Calculate PV of each coupon payment
    pv = coupon_payment / ((1 + yield_per_period) ** t)
    pv_coupons = pv_coupons + pv  # Add to running total

print(f"\nPresent Value Calculations:")
print(f"  PV of Coupons: ${pv_coupons:.2f}")

# Step 4: Calculate present value of principal repayment
pv_principal = face_value / ((1 + yield_per_period) ** periods)
print(f"  PV of Principal: ${pv_principal:.2f}")

# Step 5: Calculate total bond price
bond_price = pv_coupons + pv_principal
premium_discount = bond_price - face_value

print(f"\nBond Pricing Results:")
print(f"  Bond Price: ${bond_price:.2f}")
if premium_discount > 0:
    print(f"  Trading at Premium: ${premium_discount:.2f}")
else:
    print(f"  Trading at Discount: ${abs(premium_discount):.2f}")

# Step 6: Calculate duration (price sensitivity)
# Duration measures how sensitive bond price is to interest rate changes
duration_numerator = 0  # Weighted average time
for t in range(1, periods + 1):
    time_in_years = t / frequency  # Convert period to years
    
    # Cash flow for this period
    cash_flow = coupon_payment
    if t == periods:  # Last period includes principal
        cash_flow = cash_flow + face_value
    
    # Present value of this cash flow
    pv_cash_flow = cash_flow / ((1 + yield_per_period) ** t)
    
    # Weight of this cash flow relative to bond price
    weight = pv_cash_flow / bond_price
    
    # Add weighted time to duration
    duration_numerator = duration_numerator + (time_in_years * weight)

# Duration is the weighted average time
duration = duration_numerator

# Modified duration (better measure of price sensitivity)
mod_duration = duration / (1 + yield_per_period)

print(f"\nDuration Analysis:")
print(f"  Macaulay Duration: {duration:.2f} years")
print(f"  Modified Duration: {mod_duration:.2f}")
print(f"  Price Change per 1% Rate Change: {-mod_duration:.1f}%")

# Step 7: Build a bond portfolio
print("\n=== PORTFOLIO CONSTRUCTION ===")

# Portfolio holdings
bond1_weight = 0.3  # 30% in 2Y Treasury
bond1_duration = 1.9
bond1_value = bond1_weight * 1000000  # $1M portfolio

bond2_weight = 0.4  # 40% in 10Y Treasury  
bond2_duration = 8.5
bond2_value = bond2_weight * 1000000

bond3_weight = 0.3  # 30% in IG Corporate
bond3_duration = 6.2
bond3_value = bond3_weight * 1000000

# Calculate portfolio duration
portfolio_duration = (bond1_weight * bond1_duration + 
                     bond2_weight * bond2_duration + 
                     bond3_weight * bond3_duration)

print(f"Portfolio Composition:")
print(f"  2Y Treasury: {bond1_weight:.0%} (${bond1_value:,.0f})")
print(f"  10Y Treasury: {bond2_weight:.0%} (${bond2_value:,.0f})")
print(f"  IG Corporate: {bond3_weight:.0%} (${bond3_value:,.0f})")
print(f"\nPortfolio Duration: {portfolio_duration:.2f} years")
print(f"Expected Loss if rates +1%: {-portfolio_duration:.1f}%")

🎯 AI Learning Support - Implement#

Learning Goal: Build working bond analysis tools

Starting Prompt: “Help me code a bond price calculator in Python”

🚀 Hints to Improve Your Prompt:

  • Include semi-annual payments

  • Ask for vectorized approach

  • Request error handling

  • Include validation checks

💡 Better Version Hints:

  • Add multiple bond comparison

  • Include scenario analysis

  • Ask for performance optimization

  • Request visualization code

🎯 Your Challenge: Implement a bond screener that finds bonds meeting specific criteria

V - Validate: Test Analysis Accuracy#

Your Task: Validate calculations and assumptions.

# VALIDATE: Check calculations
print("\n=== VALIDATING ANALYSIS ===")

# Test 1: Price-yield relationship
print("Price-Yield Validation:")
test_yields = [0.04, 0.05, 0.06, 0.07]
test_prices = [1081.11, 1000.00, 925.61, 858.99]  # Known values

print("Yield | Calculated | Expected | Error")
print("-" * 40)
# Would calculate and compare here

# Test 2: Duration approximation
print("\nDuration Approximation Test:")
rate_shock = 0.01  # 1% increase
actual_price_change = -0.074  # -7.4%
duration_estimate = -duration * rate_shock
error = abs(duration_estimate - actual_price_change)

print(f"  Rate Shock: +{rate_shock:.1%}")
print(f"  Duration Estimate: {duration_estimate:.1%}")
print(f"  Actual Change: {actual_price_change:.1%}")
print(f"  Approximation Error: {error:.2%}")

# Test 3: Credit spread logic
print("\nCredit Spread Validation:")
spreads = {
    'AAA': 0.002,  # 20 bps
    'AA': 0.004,   # 40 bps
    'A': 0.008,    # 80 bps
    'BBB': 0.015   # 150 bps
}

print("Rating | Spread | Status")
print("-" * 30)
for rating, spread in spreads.items():
    status = "✓ Normal" if spread < 0.02 else "⚠ Wide"
    print(f"{rating:>6} | {spread:.1%} | {status}")

🎯 AI Learning Support - Validate#

Learning Goal: Ensure analysis accuracy and reliability

Starting Prompt: “What tests should I run to validate bond calculations?”

🚀 Hints to Improve Your Prompt:

  • Ask for specific test cases

  • Include edge scenarios

  • Request benchmark comparisons

  • Ask about common errors

💡 Better Version Hints:

  • Include market data validation

  • Ask about model assumptions

  • Request stress test scenarios

  • Include back-testing methods

🎯 Your Challenge: Design three validation tests that would satisfy risk management

E - Evolve: Enhance Analysis#

Your Task: Identify advanced features and improvements.

# EVOLVE: Advanced features
print("\n=== EVOLVING ANALYSIS ===")

print("Enhancement Options:")

print("\n1. Yield Curve Strategies:")
print("   - Bullet: Concentrate at one maturity")
print("   - Barbell: Mix short and long")
print("   - Ladder: Even distribution")

print("\n2. Credit Analysis:")
print("   - Fundamental ratios")
print("   - Relative value models") 
print("   - Default probability models")

print("\n3. Risk Management:")
print("   - Key rate durations")
print("   - Scenario analysis")
print("   - VaR calculations")

print("\n4. Portfolio Optimization:")
print("   - Duration matching")
print("   - Yield maximization")
print("   - Risk parity approach")

# Implementation priorities
priorities = [
    "Add callable bond analysis",
    "Include inflation-linked bonds",
    "Build sector rotation model",
    "Create liquidity scoring"
]

print("\n🎯 Next Development Steps:")
for i, priority in enumerate(priorities, 1):
    print(f"  {i}. {priority}")

🎯 AI Learning Support - Evolve#

Learning Goal: Identify sophisticated enhancements

Starting Prompt: “What advanced features should institutional bond systems have?”

🚀 Hints to Improve Your Prompt:

  • Specify institution type

  • Include regulatory requirements

  • Ask about market trends

  • Request automation ideas

💡 Better Version Hints:

  • Include AI/ML applications

  • Ask about real-time features

  • Request integration needs

  • Include ESG considerations

🎯 Your Challenge: Design one advanced feature that would differentiate your system

R - Reflect: Synthesize Learning#

Your Task: Extract key insights and plan applications.

# REFLECT: Key learnings
print("\n=== REFLECTING ON INSIGHTS ===")

print("Key Insights Gained:")
print("1. Duration Management:")
print("   - Critical for rate risk control")
print("   - Must match to liabilities")
print("   - Active management in volatile markets")

print("\n2. Credit Analysis:")
print("   - Spread compensates for risk")
print("   - Ratings lag market pricing")
print("   - Diversification essential")

print("\n3. Portfolio Construction:")
print("   - No single 'best' strategy")
print("   - Depends on objectives/constraints")
print("   - Dynamic rebalancing needed")

print("\n4. Market Dynamics:")
print("   - Rates drive short-term returns")
print("   - Credit drives long-term returns")
print("   - Liquidity matters in stress")

print("\nCareer Applications:")
print("  → Portfolio Management")
print("  → Credit Research")
print("  → Risk Management")
print("  → Trading/Market Making")

🎯 AI Learning Support - Reflect#

Learning Goal: Connect learning to career goals

Starting Prompt: “What fixed income careers match my analytical skills?”

🚀 Hints to Improve Your Prompt:

  • Include your interests

  • Specify firm types

  • Ask about skill requirements

  • Request career paths

💡 Better Version Hints:

  • Include compensation data

  • Ask about certifications

  • Request interview tips

  • Include networking advice

🎯 Your Challenge: Write three ways you’ll apply bond analysis in your career


Section 5: Assignment#

Scenario#

You’re a junior analyst at Pension Partners LLC, managing fixed income portfolios. Your supervisor assigns you to build a $10 million bond portfolio for MegaCorp’s pension fund, which has 8,000 retirees receiving monthly benefits. The fund needs steady income with appropriate duration matching.

Requirements#

Create a video (approximately 10-15 minutes) demonstrating:

  • Construction of a bond portfolio with at least 8 different bonds

  • Duration calculations and liability matching analysis

  • Yield optimization while maintaining credit quality standards

  • Stress testing for interest rate and credit spread changes

Execution Format#

  • Use your completed Jupyter notebook or Python script

  • Run your code cell-by-cell while explaining what each part does

  • Show outputs including portfolio composition, duration, and yield metrics

  • Discuss trade-offs between yield, safety, and duration matching

Deliverables#

  1. Video demonstration showing code execution and analysis

  2. Python code file (.py or .ipynb)


Section 6: Reflect & Connect - Financial Insights Discussion#

Individual Reflection (10 minutes)#

Write your thoughts on:

  1. Duration Understanding:

    • What clicked about duration for you?

    • How would you explain it simply?

    • When is duration most important?

  2. Credit vs Rate Risk:

    • Which risk worries you more?

    • How do they interact?

    • Portfolio implications?

  3. Career Applications:

    • Where do you see yourself using this?

    • What additional skills do you need?

    • Industry applications?

Small Group Discussion (15 minutes)#

In groups of 3-4, discuss:

  1. Current Market Views:

    • Where are rates heading?

    • Credit cycle stage?

    • Best opportunities?

  2. Portfolio Strategies:

    • Share your approaches

    • Compare risk metrics

    • Debate active vs passive

  3. Technology Impact:

    • How is AI changing bond analysis?

    • What can’t be automated?

    • Future of fixed income?

Class Synthesis (15 minutes)#

Key Questions for Discussion:

  1. Biggest Surprise:

    • What was unexpected about bonds?

    • Common misconceptions corrected?

    • New appreciation for complexity?

  2. Practical Applications:

    • How would you invest personally?

    • Advising family members?

    • Professional usage?

  3. Market Evolution:

    • Impact of Fed policy?

    • Credit cycle concerns?

    • Structural changes?

🎯 AI Learning Support - Synthesis#

Learning Goal: Connect bond analysis to broader finance

Starting Prompt: “How does fixed income fit into modern portfolio theory?”

🚀 Hints to Improve Your Prompt:

  • Include equity correlation

  • Ask about alternatives

  • Request allocation models

  • Include risk parity

💡 Better Version Hints:

  • Compare traditional 60/40

  • Include factor approaches

  • Ask about tail risks

  • Request regime analysis

🎯 Your Challenge: Explain why every portfolio needs bonds despite recent losses

Key Takeaways#

Technical Skills Acquired: ✅ Bond pricing mathematics ✅ Duration and convexity ✅ Credit spread analysis ✅ Portfolio construction ✅ Risk measurement

Professional Capabilities: ✅ Evaluate fixed income securities ✅ Manage interest rate risk ✅ Construct bond portfolios ✅ Communicate recommendations ✅ Monitor and rebalance

Career Applications:

  • Fixed income portfolio management

  • Credit research analyst

  • Risk management

  • Treasury/ALM roles

  • Investment consulting


Section 7: Looking Ahead#

From Fixed Income to Options#

You’ve mastered: Bond valuation, duration analysis, and systematic fixed income portfolio construction.

Next, you’ll discover: How option pricing models extend these concepts to derivatives, enabling sophisticated risk management and trading strategies.

Connection Points#

Mathematical Foundations:

  • Present value → Option pricing

  • Duration → Greeks (delta, gamma)

  • Yield curves → Forward rates

  • Volatility → Option premiums

Risk Concepts:

  • Linear risk (duration) → Non-linear risk (gamma)

  • Credit spreads → Volatility spreads

  • Scenario analysis → Monte Carlo

  • Static hedging → Dynamic hedging

Portfolio Applications:

  • Buy bonds → Buy bonds + protective puts

  • Duration hedging → Delta hedging

  • Credit protection → Credit derivatives

  • Yield enhancement → Covered calls

Preparation for Session 11#

Before next class:

  1. Review Basics:

    • What is a call option?

    • What is a put option?

    • Payoff diagrams?

  2. Think About:

    • Why would you buy options?

    • How are they priced?

    • Connection to bonds?

  3. Real World:

    • Find one news story about options

    • Note the terminology used

🎯 AI Learning Support - Looking Forward#

Learning Goal: Connect bond concepts to derivatives

Starting Prompt: “How do options relate to bonds mathematically?”

🚀 Hints to Improve Your Prompt:

  • Ask about embedded options

  • Include callable bonds

  • Request pricing parallels

  • Ask about risk similarities

💡 Better Version Hints:

  • Compare duration and delta

  • Include volatility role

  • Ask about hedging uses

  • Request career connections

🎯 Your Challenge: Identify one way options could enhance a bond portfolio

The Journey Continues#

You’ve mastered the massive fixed income markets - larger than equities globally. These mathematical tools and risk concepts form the foundation for all advanced finance. Next, we’ll explore how options add flexibility and precision to portfolio management.

Remember: The best investors understand both stocks AND bonds. You’re building complete market knowledge!


Section 8: Appendix - Solutions & Implementation Guide#

Complete Code Solutions#

Exercise 1 Solution: Bond Pricing#

def calculate_bond_prices():
    """Complete solution for bond pricing exercise"""
    
    bonds = {
        'Bond A': {'coupon_rate': 0.05, 'years': 5, 'yield': 0.04},
        'Bond B': {'coupon_rate': 0.03, 'years': 10, 'yield': 0.05},
        'Bond C': {'coupon_rate': 0.06, 'years': 3, 'yield': 0.06}
    }
    
    results = {}
    
    for name, bond in bonds.items():
        face_value = 1000
        coupon = bond['coupon_rate'] * face_value
        n = bond['years']
        y = bond['yield']
        
        # Calculate PV of coupons
        pv_coupons = 0
        for t in range(1, n + 1):
            pv_coupons += coupon / ((1 + y) ** t)
        
        # Calculate PV of principal
        pv_principal = face_value / ((1 + y) ** n)
        
        # Total price
        price = pv_coupons + pv_principal
        
        # Current yield
        current_yield = coupon / price
        
        # Premium/Discount/Par
        if price > face_value:
            status = "Premium"
        elif price < face_value:
            status = "Discount"
        else:
            status = "Par"
        
        results[name] = {
            'price': price,
            'current_yield': current_yield,
            'status': status
        }
        
        print(f"\n{name}:")
        print(f"  Price: ${price:.2f}")
        print(f"  Current Yield: {current_yield:.3%}")
        print(f"  Status: {status}")
    
    return results

# Execute solution
results = calculate_bond_prices()

Complete Bond Analysis System#

def bond_analysis_system():
    """Complete institutional bond analysis system"""
    import numpy as np
    import pandas as pd
    
    # Bond class for analysis
    class BondAnalyzer:
        def __init__(self, face_value, coupon_rate, years, frequency=2):
            self.face_value = face_value
            self.coupon_rate = coupon_rate
            self.years = years
            self.frequency = frequency
            self.periods = years * frequency
            self.coupon_payment = (coupon_rate * face_value) / frequency
        
        def calculate_price(self, ytm):
            """Calculate bond price given YTM"""
            y = ytm / self.frequency
            
            # PV of coupons
            pv_coupons = sum(self.coupon_payment / ((1 + y) ** t) 
                           for t in range(1, self.periods + 1))
            
            # PV of principal
            pv_principal = self.face_value / ((1 + y) ** self.periods)
            
            return pv_coupons + pv_principal
        
        def calculate_duration(self, ytm):
            """Calculate Macaulay and Modified duration"""
            y = ytm / self.frequency
            price = self.calculate_price(ytm)
            
            # Macaulay duration
            mac_duration = 0
            for t in range(1, self.periods + 1):
                cf = self.coupon_payment
                if t == self.periods:
                    cf += self.face_value
                
                pv = cf / ((1 + y) ** t)
                time_years = t / self.frequency
                mac_duration += (pv / price) * time_years
            
            # Modified duration
            mod_duration = mac_duration / (1 + y)
            
            return mac_duration, mod_duration
        
        def calculate_convexity(self, ytm):
            """Calculate convexity"""
            y = ytm / self.frequency
            price = self.calculate_price(ytm)
            
            convexity = 0
            for t in range(1, self.periods + 1):
                cf = self.coupon_payment
                if t == self.periods:
                    cf += self.face_value
                
                pv = cf / ((1 + y) ** t)
                time_years = t / self.frequency
                convexity += (pv / price) * time_years * (time_years + 1/self.frequency)
            
            convexity = convexity / ((1 + y) ** 2)
            
            return convexity
    
    # Portfolio analysis
    def analyze_portfolio(bonds_list, weights, ytm_list):
        """Analyze bond portfolio"""
        portfolio_duration = 0
        portfolio_convexity = 0
        
        print("PORTFOLIO ANALYSIS")
        print("=" * 50)
        
        for i, (bond, weight, ytm) in enumerate(zip(bonds_list, weights, ytm_list)):
            price = bond.calculate_price(ytm)
            mac_dur, mod_dur = bond.calculate_duration(ytm)
            convexity = bond.calculate_convexity(ytm)
            
            portfolio_duration += weight * mod_dur
            portfolio_convexity += weight * convexity
            
            print(f"\nBond {i+1}:")
            print(f"  Price: ${price:.2f}")
            print(f"  YTM: {ytm:.3%}")
            print(f"  Modified Duration: {mod_dur:.2f}")
            print(f"  Weight: {weight:.1%}")
        
        print(f"\nPORTFOLIO METRICS:")
        print(f"  Portfolio Duration: {portfolio_duration:.2f}")
        print(f"  Portfolio Convexity: {portfolio_convexity:.2f}")
        
        # Scenario analysis
        print(f"\nSCENARIO ANALYSIS:")
        scenarios = [-0.02, -0.01, 0, 0.01, 0.02]
        
        for scenario in scenarios:
            # Duration approximation
            duration_effect = -portfolio_duration * scenario
            # Convexity adjustment
            convexity_effect = 0.5 * portfolio_convexity * (scenario ** 2)
            # Total effect
            total_effect = duration_effect + convexity_effect
            
            print(f"  Rates {scenario:+.1%}: {total_effect:+.2%}")
    
    # Example usage
    bonds = [
        BondAnalyzer(1000, 0.04, 5),
        BondAnalyzer(1000, 0.05, 10),
        BondAnalyzer(1000, 0.03, 2)
    ]
    
    weights = [0.3, 0.5, 0.2]
    yields = [0.045, 0.055, 0.035]
    
    analyze_portfolio(bonds, weights, yields)

Credit Analysis Functions#

def credit_analysis_system():
    """Credit spread and default probability analysis"""
    
    # Historical default rates by rating
    default_rates = {
        'AAA': {'1Y': 0.00, '5Y': 0.04, '10Y': 0.52},
        'AA': {'1Y': 0.02, '5Y': 0.14, '10Y': 0.52},
        'A': {'1Y': 0.05, '5Y': 0.48, '10Y': 1.39},
        'BBB': {'1Y': 0.17, '5Y': 1.64, '10Y': 4.28},
        'BB': {'1Y': 0.73, '5Y': 7.27, '10Y': 16.48},
        'B': {'1Y': 3.24, '5Y': 17.57, '10Y': 31.24},
        'CCC': {'1Y': 26.82, '5Y': 45.10, '10Y': 54.68}
    }
    
    # Recovery rates
    recovery_rates = {
        'Senior Secured': 0.65,
        'Senior Unsecured': 0.43,
        'Subordinated': 0.28
    }
    
    def analyze_credit_bond(rating, years, spread, seniority='Senior Unsecured'):
        """Analyze credit risk and expected return"""
        
        # Get default probability
        if years <= 1:
            default_prob = default_rates[rating]['1Y'] / 100
        elif years <= 5:
            default_prob = default_rates[rating]['5Y'] / 100
        else:
            default_prob = default_rates[rating]['10Y'] / 100
        
        # Recovery rate
        recovery = recovery_rates.get(seniority, 0.40)
        
        # Expected loss
        expected_loss = default_prob * (1 - recovery)
        
        # Risk-adjusted spread
        risk_adjusted_spread = spread - expected_loss
        
        print(f"\nCREDIT ANALYSIS - {rating} BOND")
        print("=" * 40)
        print(f"Maturity: {years} years")
        print(f"Credit Spread: {spread:.2%}")
        print(f"Default Probability: {default_prob:.2%}")
        print(f"Recovery Rate: {recovery:.1%}")
        print(f"Expected Loss: {expected_loss:.2%}")
        print(f"Risk-Adjusted Spread: {risk_adjusted_spread:.2%}")
        
        if risk_adjusted_spread > 0:
            print("✓ Positive expected excess return")
        else:
            print("✗ Negative expected excess return")
        
        return {
            'default_prob': default_prob,
            'expected_loss': expected_loss,
            'risk_adjusted_spread': risk_adjusted_spread
        }
    
    # Analyze different bonds
    bonds_to_analyze = [
        ('AA', 5, 0.004),
        ('BBB', 5, 0.015),
        ('BB', 5, 0.035)
    ]
    
    for rating, years, spread in bonds_to_analyze:
        analyze_credit_bond(rating, years, spread)

Implementation Notes for Instructors#

Common Student Challenges#

  1. Semi-Annual Payments:

    • Students forget to adjust

    • Solution: Always check frequency

    • Use period rates and counts

  2. Duration Confusion:

    • Mac vs Modified

    • Solution: Mac = time weight

    • Modified = price sensitivity

  3. Yield Iterations:

    • No closed form for YTM

    • Solution: Use approximation

    • Or numerical methods

  4. Credit Analysis:

    • Spread vs yield confusion

    • Solution: Spread = Corp - Treasury

    • Not absolute yield

Teaching Tips#

  1. Start with Zeros:

    • Simpler math

    • Clear duration concept

    • Build to coupon bonds

  2. Use Excel First:

    • Visible calculations

    • Easy to debug

    • Then code

  3. Real Examples:

    • Current Treasury rates

    • Recent bond issues

    • Market events

  4. Interactive Demos:

    • Change yields live

    • Show price impact

    • Duration in action

Assessment Rubric Details#

Video Presentation (100 points)#

Technical Analysis (40 points):

  • Bond pricing correct (10)

  • Duration calculated properly (10)

  • Credit analysis sound (10)

  • Portfolio metrics accurate (10)

Investment Strategy (30 points):

  • Clear objectives (10)

  • Risk assessment (10)

  • Appropriate selection (10)

Communication (20 points):

  • Professional presentation (10)

  • Clear explanations (5)

  • Good visuals (5)

Code Quality (10 points):

  • Runs correctly (5)

  • Well documented (3)

  • Efficient (2)

Grading Guidelines#

A (90-100):

  • Sophisticated analysis with multiple metrics

  • Optimal portfolio with clear strategy

  • Professional presentation

  • Perfect calculations

B (80-89):

  • Good analysis with key metrics

  • Reasonable portfolio

  • Clear communication

  • Minor errors only

C (70-79):

  • Basic calculations work

  • Simple portfolio

  • Adequate presentation

  • Some conceptual gaps

D/F (<70):

  • Major errors

  • Poor strategy

  • Unclear presentation

  • Weak understanding

Additional Resources#

Textbooks:

  1. Fabozzi - “Bond Markets, Analysis and Strategies”

  2. Tuckman - “Fixed Income Securities”

  3. CFA Institute Fixed Income readings

Online Resources:

  1. FINRA Bond Center - Current prices

  2. Treasury Direct - Government bonds

  3. FRED - Historical yield data

Python Libraries:

  • numpy - Calculations

  • pandas - Data handling

  • matplotlib - Visualization

  • scipy.optimize - YTM solving

Career Paths:

  1. Fixed Income Trading

  2. Portfolio Management

  3. Credit Research

  4. Risk Management

  5. ALM/Treasury