FinanceRoutines.jl

Financial data routines for Julia
Log | Files | Refs | README | LICENSE

yield_curve_gsw.md (6429B)


      1 # Import Yield Curve Data
      2 
      3 Some utilities for working with Gürkaynak-Sack-Wright (GSW) yield curve data from the New York Fed and Nelson-Siegel-Svensson model calculations.
      4 Note that some of the code was first written by hand and then reimplemented using AI; while I have tested some functions, you may want to do your own sanity checks. 
      5 
      6 ## Overview
      7 
      8 This package provides tools to:
      9 - Import daily GSW yield curve parameters from the Federal Reserve
     10 - Calculate yields, prices, and returns using Nelson-Siegel-Svensson models
     11 - Handle both 3-factor (Nelson-Siegel) and 4-factor (Svensson) model periods
     12 - Work with time series of bond returns and risk premiums
     13 
     14 
     15 ## Installation
     16 
     17 ```julia
     18 using FinanceRoutines; 
     19 ```
     20 
     21 ## Quick Start
     22 
     23 ```julia
     24 # Import GSW parameters from the Fed
     25 df = import_gsw_parameters(date_range=(Date("1960-01-01"), Dates.today()) )
     26 
     27 # Add yield calculations for multiple maturities
     28 FinanceRoutines.add_yields!(df, [1, 2, 5, 10, 30])
     29 
     30 # Add bond prices
     31 FinanceRoutines.add_prices!(df, [1, 5, 10])
     32 
     33 # Calculate daily returns for 10-year bonds
     34 FinanceRoutines.add_returns!(df, 10.0, frequency=:daily, return_type=:log)
     35 # Calculate excess returns over 3-month rate
     36 FinanceRoutines.add_excess_returns!(df, 10.0, risk_free_maturity=0.25)
     37 ```
     38 
     39 
     40 ## Core Types
     41 
     42 ### GSWParameters
     43 
     44 Structure to hold Nelson-Siegel-Svensson model parameters:
     45 
     46 ```julia
     47 # 4-factor Svensson model
     48 params = GSWParameters(5.0, -2.0, 1.5, 0.8, 2.5, 0.5)
     49 
     50 # 3-factor Nelson-Siegel model (missing β₃, τ₂)
     51 params_3f = GSWParameters(5.0, -2.0, 1.5, missing, 2.5, missing)
     52 
     53 # From DataFrame row
     54 params = GSWParameters(df[1, :])
     55 ```
     56 
     57 ## Core Functions
     58 
     59 ### Data Import
     60 
     61 ```julia
     62 # Import all available data
     63 df = import_gsw_parameters()
     64 
     65 # Import specific date range
     66 df = import_gsw_parameters(date_range=(Date("2010-01-01"), Date("2020-12-31")))
     67 ```
     68 
     69 ### Yield Calculations
     70 
     71 ```julia
     72 # Single yield calculation
     73 yield = gsw_yield(10.0, params)  # 10-year yield
     74 yield = gsw_yield(10.0, 5.0, -2.0, 1.5, 0.8, 2.5, 0.5)  # Using individual parameters
     75 
     76 # Yield curve
     77 maturities = [0.25, 0.5, 1, 2, 5, 10, 30]
     78 yields = gsw_yield_curve(maturities, params)
     79 ```
     80 
     81 ### Price Calculations
     82 
     83 ```julia
     84 # Zero-coupon bond prices
     85 price = gsw_price(10.0, params)  # 10-year zero price
     86 price = gsw_price(10.0, params, face_value=100.0)  # Custom face value
     87 
     88 # Price curve
     89 prices = gsw_price_curve(maturities, params)
     90 ```
     91 
     92 ### Return Calculations
     93 
     94 ```julia
     95 # Bond returns between two periods
     96 params_today = GSWParameters(5.0, -2.0, 1.5, 0.8, 2.5, 0.5)
     97 params_yesterday = GSWParameters(4.9, -1.9, 1.4, 0.9, 2.4, 0.6)
     98 
     99 # Daily log return
    100 ret = gsw_return(10.0, params_today, params_yesterday)
    101 
    102 # Monthly arithmetic return
    103 ret = gsw_return(10.0, params_today, params_yesterday, 
    104                 frequency=:monthly, return_type=:arithmetic)
    105 
    106 # Excess return over risk-free rate
    107 excess_ret = gsw_excess_return(10.0, params_today, params_yesterday)
    108 ```
    109 
    110 ### Forward Rates
    111 
    112 ```julia
    113 # 1-year forward rate starting in 2 years
    114 fwd_rate = gsw_forward_rate(2.0, 3.0, params)
    115 ```
    116 
    117 ## DataFrame Operations
    118 
    119 ### Adding Calculations to DataFrames
    120 
    121 ```julia
    122 # Add yields for multiple maturities
    123 FinanceRoutines.add_yields!(df, [1, 2, 5, 10, 30])
    124 
    125 # Add prices with custom face value
    126 FinanceRoutines.add_prices!(df, [1, 5, 10], face_value=100.0)
    127 
    128 # Add daily log returns
    129 FinanceRoutines.add_returns!(df, 10.0, frequency=:daily, return_type=:log)
    130 
    131 # Add monthly arithmetic returns
    132 FinanceRoutines.add_returns!(df, 5.0, frequency=:monthly, return_type=:arithmetic)
    133 
    134 # Add excess returns
    135 FinanceRoutines.add_excess_returns!(df, 10.0, risk_free_maturity=0.25)
    136 ```
    137 
    138 ### Column Names
    139 
    140 The package creates standardized column names:
    141 - Yields: `yield_1y`, `yield_10y`, `yield_0.5y`
    142 - Prices: `price_1y`, `price_10y`, `price_0.5y`
    143 - Returns: `ret_10y_daily`, `ret_5y_monthly`
    144 - Excess returns: `excess_ret_10y_daily`
    145 
    146 ## Convenience Functions
    147 
    148 ### Yield Curve Snapshots
    149 
    150 ```julia
    151 # Create yield curve for a single date
    152 curve = FinanceRoutines.gsw_curve_snapshot(params)
    153 curve = FinanceRoutines.gsw_curve_snapshot(5.0, -2.0, 1.5, 0.8, 2.5, 0.5)
    154 
    155 # Custom maturities
    156 curve = FinanceRoutines.gsw_curve_snapshot(params, maturities=[1, 3, 5, 7, 10, 20, 30])
    157 ```
    158 
    159 ## Model Specifications
    160 
    161 The package automatically handles two model types:
    162 
    163 ### 4-Factor Svensson Model
    164 - Uses all 6 parameters: β₀, β₁, β₂, β₃, τ₁, τ₂
    165 - More flexible yield curve shapes
    166 - Used in recent periods
    167 
    168 ### 3-Factor Nelson-Siegel Model
    169 - Uses 4 parameters: β₀, β₁, β₂, τ₁ (β₃=0, τ₂=τ₁)
    170 - Simpler model specification
    171 - Used in earlier periods or when data is missing
    172 
    173 The package automatically detects which model to use based on available parameters.
    174 
    175 ## Missing Data Handling
    176 
    177 - Automatically converts common flag values to `missing`: `-999.99`, `-999`, `-9999`, `-99.99`
    178 - Gracefully handles periods with missing τ₂/β₃ parameters
    179 - Propagates missing values through calculations appropriately
    180 
    181 ## Example Analysis
    182 
    183 ```julia
    184 using DataFrames, Statistics
    185 
    186 # Import data for 1970s and 1980s
    187 df = import_gsw_parameters(date_range=(Date("1970-01-01"), Date("1989-12-31")))
    188 
    189 # Add calculations
    190 FinanceRoutines.add_yields!(df, 1)  # 1-year yields
    191 FinanceRoutines.add_prices!(df, 1)  # 1-year prices  
    192 FinanceRoutines.add_returns!(df, 2, frequency=:daily, return_type=:log)  # 2-year daily returns
    193 
    194 # Analyze by decade
    195 transform!(df, :date => (x -> year.(x) .÷ 10 * 10) => :decade)
    196 
    197 # Summary statistics
    198 stats = combine(
    199     groupby(df, :decade),
    200     :yield_1y => (x -> mean(skipmissing(x))) => :mean_yield,
    201     :yield_1y => (x -> std(skipmissing(x))) => :vol_yield,
    202     :ret_2y_daily => (x -> mean(skipmissing(x))) => :mean_return,
    203     :ret_2y_daily => (x -> std(skipmissing(x))) => :vol_return
    204 )
    205 ```
    206 
    207 
    208 ## Data Source
    209 
    210 GSW yield curve parameters are downloaded from the Federal Reserve Economic Data (FRED):
    211 - URL: https://www.federalreserve.gov/data/yield-curve-tables/feds200628.csv
    212 - Updated daily
    213 - Historical data available from 1961
    214 
    215 ## References
    216 
    217 - Gürkaynak, R. S., B. Sack, and J. H. Wright (2007). "The U.S. Treasury yield curve: 1961 to the present." Journal of Monetary Economics 54(8), 2291-2304.
    218 - Nelson, C. R. and A. F. Siegel (1987). "Parsimonious modeling of yield curves." Journal of Business 60(4), 473-489.
    219 - Svensson, L. E. (1994). "Estimating and interpreting forward interest rates: Sweden 1992-1994." NBER Working Paper No. 4871.
    220 
    221 
    222 
    223 
    224 
    225 
    226 
    227 
    228 
    229 
    230 
    231 
    232 
    233 
    234