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:
Calculate Bond Prices and Yields - Apply present value principles to value bonds and compute yields with professional precision
Measure Interest Rate Risk - Calculate duration and convexity to quantify bond price sensitivity to rate changes
Analyze Credit Risk - Evaluate corporate bonds using credit spreads, default probabilities, and recovery rates
Construct Bond Portfolios - Build fixed income portfolios with appropriate duration matching and risk controls
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):
Duration Insights: What surprised you about duration calculations?
Credit vs Rate Risk: Which risk is more important? When?
Portfolio Applications: How would you build a bond portfolio?
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#
Video demonstration showing code execution and analysis
Python code file (.py or .ipynb)
Section 6: Reflect & Connect - Financial Insights Discussion#
Individual Reflection (10 minutes)#
Write your thoughts on:
Duration Understanding:
What clicked about duration for you?
How would you explain it simply?
When is duration most important?
Credit vs Rate Risk:
Which risk worries you more?
How do they interact?
Portfolio implications?
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:
Current Market Views:
Where are rates heading?
Credit cycle stage?
Best opportunities?
Portfolio Strategies:
Share your approaches
Compare risk metrics
Debate active vs passive
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:
Biggest Surprise:
What was unexpected about bonds?
Common misconceptions corrected?
New appreciation for complexity?
Practical Applications:
How would you invest personally?
Advising family members?
Professional usage?
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:
Review Basics:
What is a call option?
What is a put option?
Payoff diagrams?
Think About:
Why would you buy options?
How are they priced?
Connection to bonds?
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#
Semi-Annual Payments:
Students forget to adjust
Solution: Always check frequency
Use period rates and counts
Duration Confusion:
Mac vs Modified
Solution: Mac = time weight
Modified = price sensitivity
Yield Iterations:
No closed form for YTM
Solution: Use approximation
Or numerical methods
Credit Analysis:
Spread vs yield confusion
Solution: Spread = Corp - Treasury
Not absolute yield
Teaching Tips#
Start with Zeros:
Simpler math
Clear duration concept
Build to coupon bonds
Use Excel First:
Visible calculations
Easy to debug
Then code
Real Examples:
Current Treasury rates
Recent bond issues
Market events
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:
Fabozzi - “Bond Markets, Analysis and Strategies”
Tuckman - “Fixed Income Securities”
CFA Institute Fixed Income readings
Online Resources:
FINRA Bond Center - Current prices
Treasury Direct - Government bonds
FRED - Historical yield data
Python Libraries:
numpy
- Calculationspandas
- Data handlingmatplotlib
- Visualizationscipy.optimize
- YTM solving
Career Paths:
Fixed Income Trading
Portfolio Management
Credit Research
Risk Management
ALM/Treasury