<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Tom Roth</title>
<link>https://tomroth.dev/</link>
<atom:link href="https://tomroth.dev/index.xml" rel="self" type="application/rss+xml"/>
<description>Markets, financial mathematics, and code.</description>
<generator>quarto-1.10.18</generator>
<lastBuildDate>Tue, 03 Mar 2026 23:00:00 GMT</lastBuildDate>
<item>
  <title>Why the term premium stopped explaining the long end</title>
  <dc:creator>Tom Roth</dc:creator>
  <link>https://tomroth.dev/posts/term-premium/</link>
  <description><![CDATA[ 




<div class="post-meta" kind="ESSAY">

</div>
<div class="callout callout-style-default callout-note callout-titled" title="The takeaway">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>The takeaway
</div>
</div>
<div class="callout-body-container callout-body">
<p>A term-premium estimate depends on the assumptions used to forecast short rates. This illustrative simulation shows how changing those assumptions moves the residual. Read the estimate alongside a sensitivity range; the synthetic data here do not establish what drove actual yields after 2022.</p>
</div>
</div>
<p>Every rates desk runs some version of the same sentence: the ten-year is up because the term premium is back. It is a comfortable sentence, because the term premium is not observed. It is whatever is left once you subtract the part of the yield you claim to understand.</p>
<p>That residual has been carrying an uncomfortable share of the variance since 2022. This post walks the decomposition, fits it, and then argues that what changed is the identification, not the compensation investors demand.</p>
<section id="the-claim" class="level2">
<h2 class="anchored" data-anchor-id="the-claim">The claim</h2>
<p>The affine no-arbitrage story says a nominal yield of maturity <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>τ</mi><annotation encoding="application/x-tex">\tau</annotation></semantics></math> is the average short rate the market expects over that horizon, plus compensation for bearing the risk that the expectation is wrong:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>y</mi><mi>t</mi></msub><mo stretchy="false" form="prefix">(</mo><mi>τ</mi><mo stretchy="false" form="postfix">)</mo><mspace width="0.278em"></mspace><mo>=</mo><mspace width="0.278em"></mspace><munder><munder><mrow><mfrac><mn>1</mn><mi>τ</mi></mfrac><mspace width="0.167em"></mspace><msub><mi mathvariant="double-struck">𝔼</mi><mi>t</mi></msub><mspace width="-0.167em"></mspace><mrow><mo stretchy="true" form="prefix">[</mo><msubsup><mo>∫</mo><mn>0</mn><mi>τ</mi></msubsup><msub><mi>r</mi><mrow><mi>t</mi><mo>+</mo><mi>s</mi></mrow></msub><mspace width="0.167em"></mspace><mi>d</mi><mi>s</mi><mo stretchy="true" form="postfix">]</mo></mrow></mrow><mo accent="true">⏟</mo></munder><mtext mathvariant="normal">expected policy</mtext></munder><mspace width="0.278em"></mspace><mo>+</mo><mspace width="0.278em"></mspace><munder><munder><mrow><msub><mi>ϕ</mi><mi>t</mi></msub><mo stretchy="false" form="prefix">(</mo><mi>τ</mi><mo stretchy="false" form="postfix">)</mo></mrow><mo accent="true">⏟</mo></munder><mtext mathvariant="normal">term premium</mtext></munder><mspace width="0.278em"></mspace><mo>+</mo><mspace width="0.278em"></mspace><msub><mi>ε</mi><mi>t</mi></msub><mo stretchy="false" form="prefix">(</mo><mi>τ</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">
y_t(\tau) \;=\; \underbrace{\frac{1}{\tau}\,\mathbb{E}_t\!\left[\int_0^{\tau} r_{t+s}\,ds\right]}_{\text{expected policy}} \;+\; \underbrace{\phi_t(\tau)}_{\text{term premium}} \;+\; \varepsilon_t(\tau)
</annotation></semantics></math></p>
<p>Only <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>y</mi><mi>t</mi></msub><mo stretchy="false" form="prefix">(</mo><mi>τ</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">y_t(\tau)</annotation></semantics></math> is in the data. The expectation term is produced by a model of the short rate, and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>ϕ</mi><mi>t</mi></msub><mo stretchy="false" form="prefix">(</mo><mi>τ</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\phi_t(\tau)</annotation></semantics></math> is the difference. So the term premium inherits every misspecification in the expectations model — if your short-rate dynamics mean-revert too fast, the expectation component is too flat, and the premium absorbs the slack.</p>
<p>The usual functional form for the fitted curve is Nelson–Siegel, three factors standing in for level, slope, and curvature:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo stretchy="false" form="prefix">(</mo><mi>τ</mi><mo stretchy="false" form="postfix">)</mo><mspace width="0.278em"></mspace><mo>=</mo><mspace width="0.278em"></mspace><msub><mi>β</mi><mn>0</mn></msub><mspace width="0.278em"></mspace><mo>+</mo><mspace width="0.278em"></mspace><msub><mi>β</mi><mn>1</mn></msub><mspace width="0.167em"></mspace><mfrac><mrow><mn>1</mn><mo>−</mo><msup><mi>e</mi><mrow><mi>−</mi><mi>τ</mi><mi>/</mi><mi>λ</mi></mrow></msup></mrow><mrow><mi>τ</mi><mi>/</mi><mi>λ</mi></mrow></mfrac><mspace width="0.278em"></mspace><mo>+</mo><mspace width="0.278em"></mspace><msub><mi>β</mi><mn>2</mn></msub><mrow><mo stretchy="true" form="prefix">(</mo><mfrac><mrow><mn>1</mn><mo>−</mo><msup><mi>e</mi><mrow><mi>−</mi><mi>τ</mi><mi>/</mi><mi>λ</mi></mrow></msup></mrow><mrow><mi>τ</mi><mi>/</mi><mi>λ</mi></mrow></mfrac><mo>−</mo><msup><mi>e</mi><mrow><mi>−</mi><mi>τ</mi><mi>/</mi><mi>λ</mi></mrow></msup><mo stretchy="true" form="postfix">)</mo></mrow></mrow><annotation encoding="application/x-tex">
y(\tau) \;=\; \beta_0 \;+\; \beta_1\,\frac{1 - e^{-\tau/\lambda}}{\tau/\lambda} \;+\; \beta_2\left(\frac{1 - e^{-\tau/\lambda}}{\tau/\lambda} - e^{-\tau/\lambda}\right)
</annotation></semantics></math></p>
<p>with <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>λ</mi><annotation encoding="application/x-tex">\lambda</annotation></semantics></math> setting where the curvature loading peaks.</p>
</section>
<section id="decomposition" class="level2">
<h2 class="anchored" data-anchor-id="decomposition">Decomposition</h2>
<p>The mechanical part is easy. Fit the curve, project the short rate forward under a mean-reverting process, integrate, subtract. Below is the fit itself — a Levenberg–Marquardt least squares on the three betas, with <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>λ</mi><annotation encoding="application/x-tex">\lambda</annotation></semantics></math> held at the conventional 1.37 so that curvature peaks near the 2–3 year point.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> scipy.optimize <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> least_squares</span>
<span id="cb1-3"></span>
<span id="cb1-4">LAMBDA <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.37</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># curvature loading peaks near the 2y-3y point</span></span>
<span id="cb1-5"></span>
<span id="cb1-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> ns_loadings(tau, lam<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>LAMBDA):</span>
<span id="cb1-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""Nelson-Siegel factor loadings for maturities `tau` (in years)."""</span></span>
<span id="cb1-8">    x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tau <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> lam</span>
<span id="cb1-9">    slope <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>x)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> x</span>
<span id="cb1-10">    curve <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> slope <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>x)</span>
<span id="cb1-11">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.column_stack([np.ones_like(tau), slope, curve])</span>
<span id="cb1-12"></span>
<span id="cb1-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> fit_ns(tau, yields, lam<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>LAMBDA):</span>
<span id="cb1-14">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""Least-squares fit of (beta0, beta1, beta2) to an observed curve."""</span></span>
<span id="cb1-15">    L <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ns_loadings(tau, lam)</span>
<span id="cb1-16">    resid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> b: L <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> yields</span>
<span id="cb1-17">    out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> least_squares(resid, x0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>np.array([<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>]), method<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lm"</span>)</span>
<span id="cb1-18">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out.x</span></code></pre></div></div>
<p>The expectations leg is where the judgement lives. Project the policy rate under an Ornstein–Uhlenbeck process with speed <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>κ</mi><annotation encoding="application/x-tex">\kappa</annotation></semantics></math> toward a neutral rate <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mi>r</mi><mo>*</mo></msup><annotation encoding="application/x-tex">r^{\ast}</annotation></semantics></math>, and the average expected short rate over <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>τ</mi><annotation encoding="application/x-tex">\tau</annotation></semantics></math> has a closed form:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mn>1</mn><mi>τ</mi></mfrac><mspace width="0.167em"></mspace><msub><mi mathvariant="double-struck">𝔼</mi><mi>t</mi></msub><mspace width="-0.167em"></mspace><mrow><mo stretchy="true" form="prefix">[</mo><msubsup><mo>∫</mo><mn>0</mn><mi>τ</mi></msubsup><msub><mi>r</mi><mrow><mi>t</mi><mo>+</mo><mi>s</mi></mrow></msub><mspace width="0.167em"></mspace><mi>d</mi><mi>s</mi><mo stretchy="true" form="postfix">]</mo></mrow><mspace width="0.278em"></mspace><mo>=</mo><mspace width="0.278em"></mspace><msup><mi>r</mi><mo>*</mo></msup><mspace width="0.278em"></mspace><mo>+</mo><mspace width="0.278em"></mspace><mo stretchy="false" form="prefix">(</mo><msub><mi>r</mi><mi>t</mi></msub><mo>−</mo><msup><mi>r</mi><mo>*</mo></msup><mo stretchy="false" form="postfix">)</mo><mspace width="0.167em"></mspace><mfrac><mrow><mn>1</mn><mo>−</mo><msup><mi>e</mi><mrow><mi>−</mi><mi>κ</mi><mi>τ</mi></mrow></msup></mrow><mrow><mi>κ</mi><mi>τ</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">
\frac{1}{\tau}\,\mathbb{E}_t\!\left[\int_0^{\tau} r_{t+s}\,ds\right] \;=\; r^{\ast} \;+\; (r_t - r^{\ast})\,\frac{1 - e^{-\kappa\tau}}{\kappa\tau}
</annotation></semantics></math></p>
<p>Everything contentious is now in two numbers: <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>κ</mi><annotation encoding="application/x-tex">\kappa</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mi>r</mi><mo>*</mo></msup><annotation encoding="application/x-tex">r^{\ast}</annotation></semantics></math>.</p>
</section>
<section id="fitting-it" class="level2">
<h2 class="anchored" data-anchor-id="fitting-it">Fitting it</h2>
<p>The series below is a stylised reconstruction, not a download — the shape is calibrated to the 2015–2026 experience so the argument is reproducible without a data vendor, but do not quote the levels.</p>
<div id="cell-build-series" class="cell" data-execution_count="1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb2-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb2-3"></span>
<span id="cb2-4">LAMBDA, KAPPA, TAU <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.37</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.55</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">10.0</span></span>
<span id="cb2-5">rng <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.random.default_rng(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20260304</span>)</span>
<span id="cb2-6"></span>
<span id="cb2-7">dates <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.date_range(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2015-01-31"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2026-02-28"</span>, freq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ME"</span>)</span>
<span id="cb2-8">n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(dates)</span>
<span id="cb2-9">t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.arange(n)</span>
<span id="cb2-10"></span>
<span id="cb2-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Policy rate: near-zero, liftoff, the 2022 tightening, then a partial descent.</span></span>
<span id="cb2-12">policy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.piecewise(</span>
<span id="cb2-13">    t.astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>),</span>
<span id="cb2-14">    [t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>, (t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> (t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">86</span>), t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">86</span>],</span>
<span id="cb2-15">    [<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> s: <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.20</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.010</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> s,</span>
<span id="cb2-16">     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> s: <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.80</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.185</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>),</span>
<span id="cb2-17">     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> s: <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.35</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.055</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">86</span>)],</span>
<span id="cb2-18">).clip(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.05</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.6</span>)</span>
<span id="cb2-19"></span>
<span id="cb2-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Neutral rate drifts up over the sample; that drift is the whole argument.</span></span>
<span id="cb2-21">r_star <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.linspace(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.30</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.35</span>, n)</span>
<span id="cb2-22"></span>
<span id="cb2-23"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Expected average short rate over 10y under OU mean reversion to r*.</span></span>
<span id="cb2-24">decay <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>KAPPA <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> TAU)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (KAPPA <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> TAU)</span>
<span id="cb2-25">expected <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> r_star <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (policy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> r_star) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> decay</span>
<span id="cb2-26"></span>
<span id="cb2-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Observed 10y = expectations + a premium that regime-shifts in 2022, + noise.</span></span>
<span id="cb2-28">premium <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> np.where(t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">84</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.45</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.004</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> t, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.11</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.021</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (t <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">84</span>))</span>
<span id="cb2-29">observed <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> expected <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> premium <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> rng.normal(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.055</span>, n)</span>
<span id="cb2-30"></span>
<span id="cb2-31">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb2-32">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"date"</span>: dates,</span>
<span id="cb2-33">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"observed"</span>: observed,</span>
<span id="cb2-34">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"expected"</span>: expected,</span>
<span id="cb2-35">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"premium"</span>: observed <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> expected,</span>
<span id="cb2-36">})</span>
<span id="cb2-37"></span>
<span id="cb2-38">df.tail(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span></code></pre></div></div>
<div id="build-series" class="cell-output cell-output-display" data-execution_count="1">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">date</th>
<th data-quarto-table-cell-role="th">observed</th>
<th data-quarto-table-cell-role="th">expected</th>
<th data-quarto-table-cell-role="th">premium</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">130</th>
<td>2025-11-30</td>
<td>4.14</td>
<td>3.25</td>
<td>0.89</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">131</th>
<td>2025-12-31</td>
<td>4.11</td>
<td>3.25</td>
<td>0.86</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">132</th>
<td>2026-01-31</td>
<td>4.14</td>
<td>3.25</td>
<td>0.89</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">133</th>
<td>2026-02-28</td>
<td>4.19</td>
<td>3.24</td>
<td>0.94</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
<p>Two regimes fall straight out of the residual. Through 2021 the premium sits negative and drifts slowly — the decomposition is doing what it advertises, and the expectations leg explains the level. From mid-2022 the residual turns and climbs, and by the end of the sample it accounts for most of the move in the long end.</p>
<div id="cell-fig-decomposition" class="cell" data-execution_count="2">
<details class="code-fold">
<summary>Show plotting code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> altair <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> alt</span>
<span id="cb3-2"></span>
<span id="cb3-3">PAPER, INK, ACCENT, RULE, META <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#f0eee9"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#1a1a1a"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#2a78d6"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#e6e2db"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#8a857c"</span></span>
<span id="cb3-4"></span>
<span id="cb3-5">long_df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df.melt(</span>
<span id="cb3-6">    id_vars<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"date"</span>,</span>
<span id="cb3-7">    value_vars<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"observed"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"expected"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"premium"</span>],</span>
<span id="cb3-8">    var_name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"series"</span>,</span>
<span id="cb3-9">    value_name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pct"</span>,</span>
<span id="cb3-10">).replace({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"series"</span>: {</span>
<span id="cb3-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"observed"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10y yield"</span>,</span>
<span id="cb3-12">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"expected"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Expected avg. short rate"</span>,</span>
<span id="cb3-13">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"premium"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Term premium (residual)"</span>,</span>
<span id="cb3-14">}})</span>
<span id="cb3-15"></span>
<span id="cb3-16">base <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb3-17">    alt.Chart(long_df)</span>
<span id="cb3-18">    .mark_line(strokeWidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.6</span>)</span>
<span id="cb3-19">    .encode(</span>
<span id="cb3-20">        x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.X(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"date:T"</span>, title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>,</span>
<span id="cb3-21">                axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.Axis(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%Y"</span>, tickCount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, grid<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)),</span>
<span id="cb3-22">        y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.Y(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pct:Q"</span>, title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"percent"</span>,</span>
<span id="cb3-23">                axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.Axis(grid<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, gridColor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>RULE, tickCount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>)),</span>
<span id="cb3-24">        color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.Color(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"series:N"</span>, title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>,</span>
<span id="cb3-25">                        scale<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.Scale(</span>
<span id="cb3-26">                            domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10y yield"</span>,</span>
<span id="cb3-27">                                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Expected avg. short rate"</span>,</span>
<span id="cb3-28">                                    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Term premium (residual)"</span>],</span>
<span id="cb3-29">                            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[INK, ACCENT, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"#b8862e"</span>]),</span>
<span id="cb3-30">                        legend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.Legend(orient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"top"</span>, direction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"horizontal"</span>,</span>
<span id="cb3-31">                                          labelFontSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>, symbolStrokeWidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>,</span>
<span id="cb3-32">                                          labelLimit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">220</span>, offset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>)),</span>
<span id="cb3-33">        strokeDash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.StrokeDash(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"series:N"</span>, legend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>,</span>
<span id="cb3-34">                                  scale<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alt.Scale(</span>
<span id="cb3-35">                                      domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10y yield"</span>,</span>
<span id="cb3-36">                                              <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Expected avg. short rate"</span>,</span>
<span id="cb3-37">                                              <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Term premium (residual)"</span>],</span>
<span id="cb3-38">                                      <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], [<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>]])),</span>
<span id="cb3-39">    )</span>
<span id="cb3-40">)</span>
<span id="cb3-41"></span>
<span id="cb3-42"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> styled(c):</span>
<span id="cb3-43">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""Apply the paper palette. configure_* only works on a top-level chart."""</span></span>
<span id="cb3-44">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (</span>
<span id="cb3-45">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Inner padding lives in the spec, not in CSS — see custom.scss.</span></span>
<span id="cb3-46">        c.properties(padding<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"left"</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"top"</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"right"</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bottom"</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>})</span>
<span id="cb3-47">         .configure_view(strokeWidth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb3-48">         .configure_axis(labelFont<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ui-monospace, Menlo, monospace"</span>, labelFontSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>,</span>
<span id="cb3-49">                         labelColor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>META, titleFont<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ui-monospace, Menlo, monospace"</span>,</span>
<span id="cb3-50">                         titleFontSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>, titleColor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>META, domainColor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>RULE,</span>
<span id="cb3-51">                         tickColor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>RULE)</span>
<span id="cb3-52">         <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># No labelFont here on purpose: vl-convert cannot resolve "system-ui"</span></span>
<span id="cb3-53">         <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># when rasterising the thumbnail and drops the legend text entirely.</span></span>
<span id="cb3-54">         .configure_legend(labelColor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>INK, labelFontSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span>
<span id="cb3-55">    )</span>
<span id="cb3-56"></span>
<span id="cb3-57"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># The hero thumbnail needs a concrete width — vl-convert cannot resolve</span></span>
<span id="cb3-58"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># width="container", and silently exports a clipped chart if you hand it one.</span></span>
<span id="cb3-59">styled(base.properties(width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">720</span>, height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span>)).save(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"thumbnail.png"</span>, scale_factor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>)</span>
<span id="cb3-60"></span>
<span id="cb3-61"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># The in-page chart stays fluid so it reflows on mobile.</span></span>
<span id="cb3-62">styled(base.properties(width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"container"</span>, height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">300</span>))</span></code></pre></div></div>
</details>
<div id="fig-decomposition" class="cell-output cell-output-display quarto-float quarto-figure quarto-figure-center anchored" data-execution_count="2">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-decomposition-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">

<style>
  #altair-viz-e7d9c0dfe42c478f9d2c2550bc512a90.vega-embed {
    width: 100%;
    display: flex;
  }

  #altair-viz-e7d9c0dfe42c478f9d2c2550bc512a90.vega-embed details,
  #altair-viz-e7d9c0dfe42c478f9d2c2550bc512a90.vega-embed details summary {
    position: relative;
  }
</style>
<div id="altair-viz-e7d9c0dfe42c478f9d2c2550bc512a90"></div>
<script type="text/javascript">
  var VEGA_DEBUG = (typeof VEGA_DEBUG == "undefined") ? {} : VEGA_DEBUG;
  (function(spec, embedOpt){
    let outputDiv = document.currentScript.previousElementSibling;
    if (outputDiv.id !== "altair-viz-e7d9c0dfe42c478f9d2c2550bc512a90") {
      outputDiv = document.getElementById("altair-viz-e7d9c0dfe42c478f9d2c2550bc512a90");
    }

    const paths = {
      "vega": "https://cdn.jsdelivr.net/npm/vega@6?noext",
      "vega-lib": "https://cdn.jsdelivr.net/npm/vega-lib?noext",
      "vega-lite": "https://cdn.jsdelivr.net/npm/vega-lite@6.4.1?noext",
      "vega-embed": "https://cdn.jsdelivr.net/npm/vega-embed@7?noext",
    };

    function maybeLoadScript(lib, version) {
      var key = `${lib.replace("-", "")}_version`;
      return (VEGA_DEBUG[key] == version) ?
        Promise.resolve(paths[lib]) :
        new Promise(function(resolve, reject) {
          var s = document.createElement('script');
          document.getElementsByTagName("head")[0].appendChild(s);
          s.async = true;
          s.onload = () => {
            VEGA_DEBUG[key] = version;
            return resolve(paths[lib]);
          };
          s.onerror = () => reject(`Error loading script: ${paths[lib]}`);
          s.src = paths[lib];
        });
    }

    function showError(err) {
      outputDiv.innerHTML = `<div class="error" style="color:red;">${err}</div>`;
      throw err;
    }

    function displayChart(vegaEmbed) {
      vegaEmbed(outputDiv, spec, embedOpt)
        .catch(err => showError(`Javascript Error: ${err.message}<br>This usually means there's a typo in your chart specification. See the javascript console for the full traceback.`));
    }

    if(typeof define === "function" && define.amd) {
      requirejs.config({paths});
      let deps = ["vega-embed"];
      require(deps, displayChart, err => showError(`Error loading script: ${err.message}`));
    } else {
      maybeLoadScript("vega", "6")
        .then(() => maybeLoadScript("vega-lite", "6.4.1"))
        .then(() => maybeLoadScript("vega-embed", "7"))
        .catch(showError)
        .then(() => displayChart(vegaEmbed));
    }
  })({"config": {"view": {"continuousWidth": 300, "continuousHeight": 300, "strokeWidth": 0}, "axis": {"domainColor": "#e6e2db", "labelColor": "#8a857c", "labelFont": "ui-monospace, Menlo, monospace", "labelFontSize": 9, "tickColor": "#e6e2db", "titleColor": "#8a857c", "titleFont": "ui-monospace, Menlo, monospace", "titleFontSize": 9}, "legend": {"labelColor": "#1a1a1a", "labelFontSize": 10}}, "data": {"name": "data-6285f87c155d401731bfbf97880ca7a5"}, "mark": {"type": "line", "strokeWidth": 1.6}, "encoding": {"color": {"field": "series", "legend": {"direction": "horizontal", "labelFontSize": 10, "labelLimit": 220, "offset": 6, "orient": "top", "symbolStrokeWidth": 2}, "scale": {"domain": ["10y yield", "Expected avg. short rate", "Term premium (residual)"], "range": ["#1a1a1a", "#2a78d6", "#b8862e"]}, "title": null, "type": "nominal"}, "strokeDash": {"field": "series", "legend": null, "scale": {"domain": ["10y yield", "Expected avg. short rate", "Term premium (residual)"], "range": [[1, 0], [1, 0], [4, 2]]}, "type": "nominal"}, "x": {"axis": {"format": "%Y", "grid": false, "tickCount": 6}, "field": "date", "title": null, "type": "temporal"}, "y": {"axis": {"grid": true, "gridColor": "#e6e2db", "tickCount": 6}, "field": "pct", "title": "percent", "type": "quantitative"}}, "height": 300, "padding": {"left": 12, "top": 12, "right": 16, "bottom": 12}, "width": "container", "$schema": "https://vega.github.io/schema/vega-lite/v6.4.1.json", "datasets": {"data-6285f87c155d401731bfbf97880ca7a5": [{"date": "2015-01-31T00:00:00", "series": "10y yield", "pct": 1.3677277268848569}, {"date": "2015-02-28T00:00:00", "series": "10y yield", "pct": 1.5078703913072342}, {"date": "2015-03-31T00:00:00", "series": "10y yield", "pct": 1.3828662420009754}, {"date": "2015-04-30T00:00:00", "series": "10y yield", "pct": 1.5225674486639997}, {"date": "2015-05-31T00:00:00", "series": "10y yield", "pct": 1.4984464282048422}, {"date": "2015-06-30T00:00:00", "series": "10y yield", "pct": 1.519009189384902}, {"date": "2015-07-31T00:00:00", "series": "10y yield", "pct": 1.4774610041213398}, {"date": "2015-08-31T00:00:00", "series": "10y yield", "pct": 1.444219616864718}, {"date": "2015-09-30T00:00:00", "series": "10y yield", "pct": 1.5713241354313405}, {"date": "2015-10-31T00:00:00", "series": "10y yield", "pct": 1.6148399820552197}, {"date": "2015-11-30T00:00:00", "series": "10y yield", "pct": 1.5713505101814478}, {"date": "2015-12-31T00:00:00", "series": "10y yield", "pct": 1.5928323281603025}, {"date": "2016-01-31T00:00:00", "series": "10y yield", "pct": 1.6082321677349811}, {"date": "2016-02-29T00:00:00", "series": "10y yield", "pct": 1.6418956653128287}, {"date": "2016-03-31T00:00:00", "series": "10y yield", "pct": 1.7306510416778587}, {"date": "2016-04-30T00:00:00", "series": "10y yield", "pct": 1.697428901310219}, {"date": "2016-05-31T00:00:00", "series": "10y yield", "pct": 1.6407707757088095}, {"date": "2016-06-30T00:00:00", "series": "10y yield", "pct": 1.6306663639785386}, {"date": "2016-07-31T00:00:00", "series": "10y yield", "pct": 1.7350897886253274}, {"date": "2016-08-31T00:00:00", "series": "10y yield", "pct": 1.7456335898826043}, {"date": "2016-09-30T00:00:00", "series": "10y yield", "pct": 1.8080790670572786}, {"date": "2016-10-31T00:00:00", "series": "10y yield", "pct": 1.7256045081615081}, {"date": "2016-11-30T00:00:00", "series": "10y yield", "pct": 1.6688523197885026}, {"date": "2016-12-31T00:00:00", "series": "10y yield", "pct": 1.7160218296699006}, {"date": "2017-01-31T00:00:00", "series": "10y yield", "pct": 1.8055439282722996}, {"date": "2017-02-28T00:00:00", "series": "10y yield", "pct": 1.8042142920482176}, {"date": "2017-03-31T00:00:00", "series": "10y yield", "pct": 1.7807307951025046}, {"date": "2017-04-30T00:00:00", "series": "10y yield", "pct": 1.7428885895584725}, {"date": "2017-05-31T00:00:00", "series": "10y yield", "pct": 1.787631438355859}, {"date": "2017-06-30T00:00:00", "series": "10y yield", "pct": 1.8598460011197537}, {"date": "2017-07-31T00:00:00", "series": "10y yield", "pct": 1.8374654001383828}, {"date": "2017-08-31T00:00:00", "series": "10y yield", "pct": 1.854979717709518}, {"date": "2017-09-30T00:00:00", "series": "10y yield", "pct": 1.8292722858524952}, {"date": "2017-10-31T00:00:00", "series": "10y yield", "pct": 1.8316385364113155}, {"date": "2017-11-30T00:00:00", "series": "10y yield", "pct": 1.9349264626896538}, {"date": "2017-12-31T00:00:00", "series": "10y yield", "pct": 1.9433080046516458}, {"date": "2018-01-31T00:00:00", "series": "10y yield", "pct": 1.961889363967365}, {"date": "2018-02-28T00:00:00", "series": "10y yield", "pct": 1.8923753294746015}, {"date": "2018-03-31T00:00:00", "series": "10y yield", "pct": 1.8871293497306387}, {"date": "2018-04-30T00:00:00", "series": "10y yield", "pct": 1.8905625898316543}, {"date": "2018-05-31T00:00:00", "series": "10y yield", "pct": 1.9154716255577855}, {"date": "2018-06-30T00:00:00", "series": "10y yield", "pct": 1.9531226829952313}, {"date": "2018-07-31T00:00:00", "series": "10y yield", "pct": 1.9260057330726985}, {"date": "2018-08-31T00:00:00", "series": "10y yield", "pct": 1.9160936781264515}, {"date": "2018-09-30T00:00:00", "series": "10y yield", "pct": 1.9620421884172197}, {"date": "2018-10-31T00:00:00", "series": "10y yield", "pct": 2.0366464125894734}, {"date": "2018-11-30T00:00:00", "series": "10y yield", "pct": 2.06319242258828}, {"date": "2018-12-31T00:00:00", "series": "10y yield", "pct": 2.066676260650974}, {"date": "2019-01-31T00:00:00", "series": "10y yield", "pct": 2.1239039853771047}, {"date": "2019-02-28T00:00:00", "series": "10y yield", "pct": 2.1479335533689516}, {"date": "2019-03-31T00:00:00", "series": "10y yield", "pct": 2.095710757448602}, {"date": "2019-04-30T00:00:00", "series": "10y yield", "pct": 2.1130768755718474}, {"date": "2019-05-31T00:00:00", "series": "10y yield", "pct": 1.9729177543352558}, {"date": "2019-06-30T00:00:00", "series": "10y yield", "pct": 2.1988904725645857}, {"date": "2019-07-31T00:00:00", "series": "10y yield", "pct": 2.1644316457775377}, {"date": "2019-08-31T00:00:00", "series": "10y yield", "pct": 2.2177981867403744}, {"date": "2019-09-30T00:00:00", "series": "10y yield", "pct": 2.105697655604404}, {"date": "2019-10-31T00:00:00", "series": "10y yield", "pct": 2.2082903049897387}, {"date": "2019-11-30T00:00:00", "series": "10y yield", "pct": 2.0487858620637875}, {"date": "2019-12-31T00:00:00", "series": "10y yield", "pct": 2.1604214822721426}, {"date": "2020-01-31T00:00:00", "series": "10y yield", "pct": 2.279967186885738}, {"date": "2020-02-29T00:00:00", "series": "10y yield", "pct": 2.178771296683076}, {"date": "2020-03-31T00:00:00", "series": "10y yield", "pct": 2.246857230517104}, {"date": "2020-04-30T00:00:00", "series": "10y yield", "pct": 2.2253560952566236}, {"date": "2020-05-31T00:00:00", "series": "10y yield", "pct": 2.3963511402591138}, {"date": "2020-06-30T00:00:00", "series": "10y yield", "pct": 2.4560370274363548}, {"date": "2020-07-31T00:00:00", "series": "10y yield", "pct": 2.4968357977249833}, {"date": "2020-08-31T00:00:00", "series": "10y yield", "pct": 2.4869817525685916}, {"date": "2020-09-30T00:00:00", "series": "10y yield", "pct": 2.4960633733928956}, {"date": "2020-10-31T00:00:00", "series": "10y yield", "pct": 2.6958726847253773}, {"date": "2020-11-30T00:00:00", "series": "10y yield", "pct": 2.5675459029023124}, {"date": "2020-12-31T00:00:00", "series": "10y yield", "pct": 2.737792348182926}, {"date": "2021-01-31T00:00:00", "series": "10y yield", "pct": 2.748287292483142}, {"date": "2021-02-28T00:00:00", "series": "10y yield", "pct": 2.831715697728068}, {"date": "2021-03-31T00:00:00", "series": "10y yield", "pct": 2.819862845009688}, {"date": "2021-04-30T00:00:00", "series": "10y yield", "pct": 2.8617265625549524}, {"date": "2021-05-31T00:00:00", "series": "10y yield", "pct": 2.9439496067559117}, {"date": "2021-06-30T00:00:00", "series": "10y yield", "pct": 3.0121992873951715}, {"date": "2021-07-31T00:00:00", "series": "10y yield", "pct": 3.0845535881945803}, {"date": "2021-08-31T00:00:00", "series": "10y yield", "pct": 3.064634774051685}, {"date": "2021-09-30T00:00:00", "series": "10y yield", "pct": 3.056564436465009}, {"date": "2021-10-31T00:00:00", "series": "10y yield", "pct": 3.1002854400802438}, {"date": "2021-11-30T00:00:00", "series": "10y yield", "pct": 3.1033661577200338}, {"date": "2021-12-31T00:00:00", "series": "10y yield", "pct": 3.2151056793304695}, {"date": "2022-01-31T00:00:00", "series": "10y yield", "pct": 3.342515226312948}, {"date": "2022-02-28T00:00:00", "series": "10y yield", "pct": 3.342899789062497}, {"date": "2022-03-31T00:00:00", "series": "10y yield", "pct": 3.3540917062707147}, {"date": "2022-04-30T00:00:00", "series": "10y yield", "pct": 3.3290147250720494}, {"date": "2022-05-31T00:00:00", "series": "10y yield", "pct": 3.3810139670482573}, {"date": "2022-06-30T00:00:00", "series": "10y yield", "pct": 3.453252656294487}, {"date": "2022-07-31T00:00:00", "series": "10y yield", "pct": 3.3975972562409242}, {"date": "2022-08-31T00:00:00", "series": "10y yield", "pct": 3.34630317791442}, {"date": "2022-09-30T00:00:00", "series": "10y yield", "pct": 3.4551039682722986}, {"date": "2022-10-31T00:00:00", "series": "10y yield", "pct": 3.492494434082941}, {"date": "2022-11-30T00:00:00", "series": "10y yield", "pct": 3.5650794246489315}, {"date": "2022-12-31T00:00:00", "series": "10y yield", "pct": 3.525637636311284}, {"date": "2023-01-31T00:00:00", "series": "10y yield", "pct": 3.4824411394995267}, {"date": "2023-02-28T00:00:00", "series": "10y yield", "pct": 3.502842311560023}, {"date": "2023-03-31T00:00:00", "series": "10y yield", "pct": 3.5760806291630995}, {"date": "2023-04-30T00:00:00", "series": "10y yield", "pct": 3.520879606077707}, {"date": "2023-05-31T00:00:00", "series": "10y yield", "pct": 3.638584586973078}, {"date": "2023-06-30T00:00:00", "series": "10y yield", "pct": 3.5192444762984167}, {"date": "2023-07-31T00:00:00", "series": "10y yield", "pct": 3.6612939608932282}, {"date": "2023-08-31T00:00:00", "series": "10y yield", "pct": 3.6254640017582354}, {"date": "2023-09-30T00:00:00", "series": "10y yield", "pct": 3.6516303816828515}, {"date": "2023-10-31T00:00:00", "series": "10y yield", "pct": 3.6847982225253264}, {"date": "2023-11-30T00:00:00", "series": "10y yield", "pct": 3.762215603338007}, {"date": "2023-12-31T00:00:00", "series": "10y yield", "pct": 3.644839408448332}, {"date": "2024-01-31T00:00:00", "series": "10y yield", "pct": 3.7294145955214515}, {"date": "2024-02-29T00:00:00", "series": "10y yield", "pct": 3.7028519850330195}, {"date": "2024-03-31T00:00:00", "series": "10y yield", "pct": 3.835749908126656}, {"date": "2024-04-30T00:00:00", "series": "10y yield", "pct": 3.8152412565529277}, {"date": "2024-05-31T00:00:00", "series": "10y yield", "pct": 3.761633381930733}, {"date": "2024-06-30T00:00:00", "series": "10y yield", "pct": 3.8319885836187466}, {"date": "2024-07-31T00:00:00", "series": "10y yield", "pct": 3.8324973750711036}, {"date": "2024-08-31T00:00:00", "series": "10y yield", "pct": 3.857953773141668}, {"date": "2024-09-30T00:00:00", "series": "10y yield", "pct": 3.9434554696222524}, {"date": "2024-10-31T00:00:00", "series": "10y yield", "pct": 3.8821752500574935}, {"date": "2024-11-30T00:00:00", "series": "10y yield", "pct": 3.9262842767720594}, {"date": "2024-12-31T00:00:00", "series": "10y yield", "pct": 4.005913760036552}, {"date": "2025-01-31T00:00:00", "series": "10y yield", "pct": 3.8591515056749253}, {"date": "2025-02-28T00:00:00", "series": "10y yield", "pct": 3.9477324981051103}, {"date": "2025-03-31T00:00:00", "series": "10y yield", "pct": 3.9777347164654158}, {"date": "2025-04-30T00:00:00", "series": "10y yield", "pct": 3.9661306495090667}, {"date": "2025-05-31T00:00:00", "series": "10y yield", "pct": 4.011239098756469}, {"date": "2025-06-30T00:00:00", "series": "10y yield", "pct": 4.080428091154047}, {"date": "2025-07-31T00:00:00", "series": "10y yield", "pct": 4.028980769492188}, {"date": "2025-08-31T00:00:00", "series": "10y yield", "pct": 4.057453835834068}, {"date": "2025-09-30T00:00:00", "series": "10y yield", "pct": 4.069875296789964}, {"date": "2025-10-31T00:00:00", "series": "10y yield", "pct": 4.09212720098808}, {"date": "2025-11-30T00:00:00", "series": "10y yield", "pct": 4.142356060433402}, {"date": "2025-12-31T00:00:00", "series": "10y yield", "pct": 4.109972946693566}, {"date": "2026-01-31T00:00:00", "series": "10y yield", "pct": 4.139038240177908}, {"date": "2026-02-28T00:00:00", "series": "10y yield", "pct": 4.185883023075457}, {"date": "2015-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 1.9197422218219589}, {"date": "2015-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 1.9280181694692553}, {"date": "2015-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 1.9362941171165513}, {"date": "2015-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 1.9445700647638477}, {"date": "2015-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 1.9528460124111442}, {"date": "2015-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 1.9611219600584404}, {"date": "2015-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 1.9693979077057364}, {"date": "2015-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 1.9776738553530329}, {"date": "2015-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 1.9859498030003293}, {"date": "2015-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 1.9942257506476253}, {"date": "2015-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.002501698294922}, {"date": "2015-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.010777645942218}, {"date": "2016-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.019053593589514}, {"date": "2016-02-29T00:00:00", "series": "Expected avg. short rate", "pct": 2.0273295412368104}, {"date": "2016-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.035605488884107}, {"date": "2016-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.043881436531403}, {"date": "2016-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.0521573841786993}, {"date": "2016-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.0604333318259958}, {"date": "2016-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.068709279473292}, {"date": "2016-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.076985227120588}, {"date": "2016-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.0852611747678846}, {"date": "2016-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.093537122415181}, {"date": "2016-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.101813070062477}, {"date": "2016-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.1100890177097735}, {"date": "2017-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.1183649653570695}, {"date": "2017-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 2.126640913004366}, {"date": "2017-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.134916860651662}, {"date": "2017-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.1431928082989584}, {"date": "2017-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.151468755946255}, {"date": "2017-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.159744703593551}, {"date": "2017-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.1680206512408473}, {"date": "2017-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.1762965988881438}, {"date": "2017-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.1845725465354398}, {"date": "2017-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.192848494182736}, {"date": "2017-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.2011244418300326}, {"date": "2017-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.2094003894773286}, {"date": "2018-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.217676337124625}, {"date": "2018-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 2.2259522847719215}, {"date": "2018-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.234228232419218}, {"date": "2018-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.242504180066514}, {"date": "2018-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.25078012771381}, {"date": "2018-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.2590560753611064}, {"date": "2018-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.267332023008403}, {"date": "2018-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.275607970655699}, {"date": "2018-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.2838839183029953}, {"date": "2018-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.2921598659502918}, {"date": "2018-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.3004358135975878}, {"date": "2018-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.308711761244884}, {"date": "2019-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.3169877088921806}, {"date": "2019-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 2.3252636565394766}, {"date": "2019-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.333539604186773}, {"date": "2019-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.3418155518340695}, {"date": "2019-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.3500914994813655}, {"date": "2019-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.358367447128662}, {"date": "2019-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.3666433947759584}, {"date": "2019-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.3749193424232544}, {"date": "2019-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.3831952900705504}, {"date": "2019-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.391471237717847}, {"date": "2019-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.3997471853651433}, {"date": "2019-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.4080231330124393}, {"date": "2020-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.4162990806597358}, {"date": "2020-02-29T00:00:00", "series": "Expected avg. short rate", "pct": 2.4562631764885356}, {"date": "2020-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.496227272317335}, {"date": "2020-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.536191368146135}, {"date": "2020-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.576155463974935}, {"date": "2020-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.6161195598037343}, {"date": "2020-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.656083655632534}, {"date": "2020-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.6960477514613337}, {"date": "2020-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.7360118472901336}, {"date": "2020-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.775975943118933}, {"date": "2020-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 2.815940038947733}, {"date": "2020-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.855904134776533}, {"date": "2021-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.8958682306053323}, {"date": "2021-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 2.935832326434132}, {"date": "2021-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 2.9757964222629316}, {"date": "2021-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.015760518091731}, {"date": "2021-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.055724613920531}, {"date": "2021-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.095688709749331}, {"date": "2021-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.1356528055781303}, {"date": "2021-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.17561690140693}, {"date": "2021-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.2155809972357297}, {"date": "2021-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2555450930645295}, {"date": "2021-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.295509188893329}, {"date": "2021-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.335473284722129}, {"date": "2022-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.375437380550929}, {"date": "2022-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 3.4154014763797287}, {"date": "2022-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.408286037767437}, {"date": "2022-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.404792101804461}, {"date": "2022-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.4012981658414843}, {"date": "2022-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.397804229878508}, {"date": "2022-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.394310293915532}, {"date": "2022-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.390816357952555}, {"date": "2022-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.3873224219895786}, {"date": "2022-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3838284860266024}, {"date": "2022-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.380334550063626}, {"date": "2022-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.376840614100649}, {"date": "2023-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.373346678137673}, {"date": "2023-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 3.3698527421746967}, {"date": "2023-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.36635880621172}, {"date": "2023-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.362864870248744}, {"date": "2023-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3593709342857676}, {"date": "2023-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.355876998322791}, {"date": "2023-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3523830623598143}, {"date": "2023-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.348889126396838}, {"date": "2023-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.345395190433862}, {"date": "2023-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3419012544708857}, {"date": "2023-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.338407318507909}, {"date": "2023-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3349133825449324}, {"date": "2024-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.331419446581956}, {"date": "2024-02-29T00:00:00", "series": "Expected avg. short rate", "pct": 3.3279255106189796}, {"date": "2024-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3244315746560034}, {"date": "2024-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.320937638693027}, {"date": "2024-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3174437027300505}, {"date": "2024-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.313949766767074}, {"date": "2024-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.3104558308040977}, {"date": "2024-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.306961894841121}, {"date": "2024-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.303467958878145}, {"date": "2024-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2999740229151686}, {"date": "2024-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.296480086952192}, {"date": "2024-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2929861509892153}, {"date": "2025-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.289492215026239}, {"date": "2025-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 3.2859982790632625}, {"date": "2025-03-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2825043431002863}, {"date": "2025-04-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.2790104071373096}, {"date": "2025-05-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2755164711743334}, {"date": "2025-06-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.272022535211357}, {"date": "2025-07-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2685285992483806}, {"date": "2025-08-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2650346632854044}, {"date": "2025-09-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.261540727322428}, {"date": "2025-10-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.258046791359451}, {"date": "2025-11-30T00:00:00", "series": "Expected avg. short rate", "pct": 3.254552855396475}, {"date": "2025-12-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.2510589194334987}, {"date": "2026-01-31T00:00:00", "series": "Expected avg. short rate", "pct": 3.247564983470522}, {"date": "2026-02-28T00:00:00", "series": "Expected avg. short rate", "pct": 3.244071047507546}, {"date": "2015-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.552014494937102}, {"date": "2015-02-28T00:00:00", "series": "Term premium (residual)", "pct": -0.4201477781620211}, {"date": "2015-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.5534278751155759}, {"date": "2015-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.422002616099848}, {"date": "2015-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.454399584206302}, {"date": "2015-06-30T00:00:00", "series": "Term premium (residual)", "pct": -0.4421127706735384}, {"date": "2015-07-31T00:00:00", "series": "Term premium (residual)", "pct": -0.49193690358439657}, {"date": "2015-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.533454238488315}, {"date": "2015-09-30T00:00:00", "series": "Term premium (residual)", "pct": -0.4146256675689888}, {"date": "2015-10-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3793857685924056}, {"date": "2015-11-30T00:00:00", "series": "Term premium (residual)", "pct": -0.4311511881134742}, {"date": "2015-12-31T00:00:00", "series": "Term premium (residual)", "pct": -0.41794531778191546}, {"date": "2016-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.41082142585453285}, {"date": "2016-02-29T00:00:00", "series": "Term premium (residual)", "pct": -0.3854338759239817}, {"date": "2016-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3049544472062482}, {"date": "2016-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.3464525352211838}, {"date": "2016-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.41138660846988984}, {"date": "2016-06-30T00:00:00", "series": "Term premium (residual)", "pct": -0.42976696784745716}, {"date": "2016-07-31T00:00:00", "series": "Term premium (residual)", "pct": -0.33361949084796483}, {"date": "2016-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3313516372379839}, {"date": "2016-09-30T00:00:00", "series": "Term premium (residual)", "pct": -0.27718210771060603}, {"date": "2016-10-31T00:00:00", "series": "Term premium (residual)", "pct": -0.36793261425367296}, {"date": "2016-11-30T00:00:00", "series": "Term premium (residual)", "pct": -0.4329607502739745}, {"date": "2016-12-31T00:00:00", "series": "Term premium (residual)", "pct": -0.39406718803987295}, {"date": "2017-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.31282103708476994}, {"date": "2017-02-28T00:00:00", "series": "Term premium (residual)", "pct": -0.3224266209561484}, {"date": "2017-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3541860655491573}, {"date": "2017-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.40030421874048594}, {"date": "2017-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.36383731759039595}, {"date": "2017-06-30T00:00:00", "series": "Term premium (residual)", "pct": -0.29989870247379713}, {"date": "2017-07-31T00:00:00", "series": "Term premium (residual)", "pct": -0.33055525110246453}, {"date": "2017-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3213168811786258}, {"date": "2017-09-30T00:00:00", "series": "Term premium (residual)", "pct": -0.3553002606829445}, {"date": "2017-10-31T00:00:00", "series": "Term premium (residual)", "pct": -0.36120995777142073}, {"date": "2017-11-30T00:00:00", "series": "Term premium (residual)", "pct": -0.2661979791403788}, {"date": "2017-12-31T00:00:00", "series": "Term premium (residual)", "pct": -0.26609238482568287}, {"date": "2018-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.2557869731572602}, {"date": "2018-02-28T00:00:00", "series": "Term premium (residual)", "pct": -0.33357695529732}, {"date": "2018-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.34709888268857925}, {"date": "2018-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.3519415902348597}, {"date": "2018-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3353085021560245}, {"date": "2018-06-30T00:00:00", "series": "Term premium (residual)", "pct": -0.30593339236587513}, {"date": "2018-07-31T00:00:00", "series": "Term premium (residual)", "pct": -0.34132628993570435}, {"date": "2018-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3595142925292474}, {"date": "2018-09-30T00:00:00", "series": "Term premium (residual)", "pct": -0.32184172988577564}, {"date": "2018-10-31T00:00:00", "series": "Term premium (residual)", "pct": -0.2555134533608183}, {"date": "2018-11-30T00:00:00", "series": "Term premium (residual)", "pct": -0.2372433910093079}, {"date": "2018-12-31T00:00:00", "series": "Term premium (residual)", "pct": -0.24203550059391032}, {"date": "2019-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.19308372351507597}, {"date": "2019-02-28T00:00:00", "series": "Term premium (residual)", "pct": -0.177330103170525}, {"date": "2019-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.23782884673817106}, {"date": "2019-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.2287386762622221}, {"date": "2019-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.3771737451461097}, {"date": "2019-06-30T00:00:00", "series": "Term premium (residual)", "pct": -0.15947697456407628}, {"date": "2019-07-31T00:00:00", "series": "Term premium (residual)", "pct": -0.20221174899842076}, {"date": "2019-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.15712115568288}, {"date": "2019-09-30T00:00:00", "series": "Term premium (residual)", "pct": -0.2774976344661466}, {"date": "2019-10-31T00:00:00", "series": "Term premium (residual)", "pct": -0.1831809327281082}, {"date": "2019-11-30T00:00:00", "series": "Term premium (residual)", "pct": -0.35096132330135577}, {"date": "2019-12-31T00:00:00", "series": "Term premium (residual)", "pct": -0.24760165074029672}, {"date": "2020-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.13633189377399768}, {"date": "2020-02-29T00:00:00", "series": "Term premium (residual)", "pct": -0.27749187980545953}, {"date": "2020-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.24937004180023115}, {"date": "2020-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.3108352728895114}, {"date": "2020-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.1798043237158211}, {"date": "2020-06-30T00:00:00", "series": "Term premium (residual)", "pct": -0.16008253236737957}, {"date": "2020-07-31T00:00:00", "series": "Term premium (residual)", "pct": -0.15924785790755047}, {"date": "2020-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.20906599889274213}, {"date": "2020-09-30T00:00:00", "series": "Term premium (residual)", "pct": -0.23994847389723795}, {"date": "2020-10-31T00:00:00", "series": "Term premium (residual)", "pct": -0.0801032583935557}, {"date": "2020-11-30T00:00:00", "series": "Term premium (residual)", "pct": -0.2483941360454205}, {"date": "2020-12-31T00:00:00", "series": "Term premium (residual)", "pct": -0.118111786593607}, {"date": "2021-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.1475809381221902}, {"date": "2021-02-28T00:00:00", "series": "Term premium (residual)", "pct": -0.10411662870606397}, {"date": "2021-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.15593357725324353}, {"date": "2021-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.15403395553677868}, {"date": "2021-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.1117750071646193}, {"date": "2021-06-30T00:00:00", "series": "Term premium (residual)", "pct": -0.08348942235415935}, {"date": "2021-07-31T00:00:00", "series": "Term premium (residual)", "pct": -0.051099217383550055}, {"date": "2021-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.11098212735524537}, {"date": "2021-09-30T00:00:00", "series": "Term premium (residual)", "pct": -0.1590165607707208}, {"date": "2021-10-31T00:00:00", "series": "Term premium (residual)", "pct": -0.1552596529842858}, {"date": "2021-11-30T00:00:00", "series": "Term premium (residual)", "pct": -0.19214303117329523}, {"date": "2021-12-31T00:00:00", "series": "Term premium (residual)", "pct": -0.12036760539165936}, {"date": "2022-01-31T00:00:00", "series": "Term premium (residual)", "pct": -0.03292215423798073}, {"date": "2022-02-28T00:00:00", "series": "Term premium (residual)", "pct": -0.0725016873172315}, {"date": "2022-03-31T00:00:00", "series": "Term premium (residual)", "pct": -0.05419433149672237}, {"date": "2022-04-30T00:00:00", "series": "Term premium (residual)", "pct": -0.07577737673241147}, {"date": "2022-05-31T00:00:00", "series": "Term premium (residual)", "pct": -0.02028419879322696}, {"date": "2022-06-30T00:00:00", "series": "Term premium (residual)", "pct": 0.055448426415979135}, {"date": "2022-07-31T00:00:00", "series": "Term premium (residual)", "pct": 0.003286962325392384}, {"date": "2022-08-31T00:00:00", "series": "Term premium (residual)", "pct": -0.044513180038135314}, {"date": "2022-09-30T00:00:00", "series": "Term premium (residual)", "pct": 0.06778154628272004}, {"date": "2022-10-31T00:00:00", "series": "Term premium (residual)", "pct": 0.10866594805633856}, {"date": "2022-11-30T00:00:00", "series": "Term premium (residual)", "pct": 0.1847448745853053}, {"date": "2022-12-31T00:00:00", "series": "Term premium (residual)", "pct": 0.14879702221063473}, {"date": "2023-01-31T00:00:00", "series": "Term premium (residual)", "pct": 0.10909446136185386}, {"date": "2023-02-28T00:00:00", "series": "Term premium (residual)", "pct": 0.13298956938532625}, {"date": "2023-03-31T00:00:00", "series": "Term premium (residual)", "pct": 0.20972182295137953}, {"date": "2023-04-30T00:00:00", "series": "Term premium (residual)", "pct": 0.1580147358289632}, {"date": "2023-05-31T00:00:00", "series": "Term premium (residual)", "pct": 0.27921365268731035}, {"date": "2023-06-30T00:00:00", "series": "Term premium (residual)", "pct": 0.16336747797562579}, {"date": "2023-07-31T00:00:00", "series": "Term premium (residual)", "pct": 0.3089108985334139}, {"date": "2023-08-31T00:00:00", "series": "Term premium (residual)", "pct": 0.27657487536139724}, {"date": "2023-09-30T00:00:00", "series": "Term premium (residual)", "pct": 0.30623519124898957}, {"date": "2023-10-31T00:00:00", "series": "Term premium (residual)", "pct": 0.3428969680544407}, {"date": "2023-11-30T00:00:00", "series": "Term premium (residual)", "pct": 0.4238082848300979}, {"date": "2023-12-31T00:00:00", "series": "Term premium (residual)", "pct": 0.3099260259033998}, {"date": "2024-01-31T00:00:00", "series": "Term premium (residual)", "pct": 0.3979951489394953}, {"date": "2024-02-29T00:00:00", "series": "Term premium (residual)", "pct": 0.3749264744140399}, {"date": "2024-03-31T00:00:00", "series": "Term premium (residual)", "pct": 0.5113183334706526}, {"date": "2024-04-30T00:00:00", "series": "Term premium (residual)", "pct": 0.4943036178599005}, {"date": "2024-05-31T00:00:00", "series": "Term premium (residual)", "pct": 0.44418967920068253}, {"date": "2024-06-30T00:00:00", "series": "Term premium (residual)", "pct": 0.5180388168516727}, {"date": "2024-07-31T00:00:00", "series": "Term premium (residual)", "pct": 0.5220415442670059}, {"date": "2024-08-31T00:00:00", "series": "Term premium (residual)", "pct": 0.5509918783005472}, {"date": "2024-09-30T00:00:00", "series": "Term premium (residual)", "pct": 0.6399875107441075}, {"date": "2024-10-31T00:00:00", "series": "Term premium (residual)", "pct": 0.5822012271423249}, {"date": "2024-11-30T00:00:00", "series": "Term premium (residual)", "pct": 0.6298041898198674}, {"date": "2024-12-31T00:00:00", "series": "Term premium (residual)", "pct": 0.7129276090473371}, {"date": "2025-01-31T00:00:00", "series": "Term premium (residual)", "pct": 0.5696592906486861}, {"date": "2025-02-28T00:00:00", "series": "Term premium (residual)", "pct": 0.6617342190418478}, {"date": "2025-03-31T00:00:00", "series": "Term premium (residual)", "pct": 0.6952303733651295}, {"date": "2025-04-30T00:00:00", "series": "Term premium (residual)", "pct": 0.6871202423717571}, {"date": "2025-05-31T00:00:00", "series": "Term premium (residual)", "pct": 0.7357226275821351}, {"date": "2025-06-30T00:00:00", "series": "Term premium (residual)", "pct": 0.8084055559426901}, {"date": "2025-07-31T00:00:00", "series": "Term premium (residual)", "pct": 0.7604521702438074}, {"date": "2025-08-31T00:00:00", "series": "Term premium (residual)", "pct": 0.792419172548664}, {"date": "2025-09-30T00:00:00", "series": "Term premium (residual)", "pct": 0.8083345694675357}, {"date": "2025-10-31T00:00:00", "series": "Term premium (residual)", "pct": 0.834080409628629}, {"date": "2025-11-30T00:00:00", "series": "Term premium (residual)", "pct": 0.8878032050369269}, {"date": "2025-12-31T00:00:00", "series": "Term premium (residual)", "pct": 0.8589140272600675}, {"date": "2026-01-31T00:00:00", "series": "Term premium (residual)", "pct": 0.891473256707386}, {"date": "2026-02-28T00:00:00", "series": "Term premium (residual)", "pct": 0.9418119755679109}]}}, {"mode": "vega-lite"});
</script>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-decomposition-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: The ten-year decomposed. Through 2021 the expectations leg tracks the yield; after mid-2022 the residual carries it.
</figcaption>
</figure>
</div>
</div>
</section>
<section id="where-it-breaks" class="level2">
<h2 class="anchored" data-anchor-id="where-it-breaks">Where it breaks</h2>
<p>The residual is not compensation you can point at. Three things move it that have nothing to do with risk appetite:</p>
<ol type="1">
<li><strong><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mi>r</mi><mo>*</mo></msup><annotation encoding="application/x-tex">r^{\ast}</annotation></semantics></math> is a free parameter.</strong> Raise the assumed neutral rate by 50bp and the expectations leg lifts by roughly the same amount at the long end, and the premium falls one-for-one. The decomposition has no opinion about which is right.</li>
<li><strong><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>κ</mi><annotation encoding="application/x-tex">\kappa</annotation></semantics></math> sets how much of the current policy rate survives ten years.</strong> With <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>κ</mi><mo>=</mo><mn>0.55</mn></mrow><annotation encoding="application/x-tex">\kappa = 0.55</annotation></semantics></math> the decay factor is about 0.18 — the front end barely reaches the ten-year. Halve <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>κ</mi><annotation encoding="application/x-tex">\kappa</annotation></semantics></math> and the tightening cycle shows up in the expectations leg instead of the residual.</li>
<li><strong>Supply is not in the model at all.</strong> Duration coming to market is a quantity, and an affine model in yields has nowhere to put it, so it lands in <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>ϕ</mi><mi>t</mi></msub><annotation encoding="application/x-tex">\phi_t</annotation></semantics></math>.</li>
</ol>
<p>You can see the first two directly — the same data, three assumptions about the neutral rate:</p>
<div id="cell-sensitivity" class="cell" data-execution_count="3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> premium_under(r_star_shift: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>, kappa: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>:</span>
<span id="cb4-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""Mean 2023-2026 term premium under alternative (r*, kappa) assumptions."""</span></span>
<span id="cb4-3">    d <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> np.exp(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>kappa <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> TAU)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> (kappa <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> TAU)</span>
<span id="cb4-4">    exp_leg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (r_star <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> r_star_shift) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (policy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> (r_star <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> r_star_shift)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d</span>
<span id="cb4-5">    resid <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> observed <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> exp_leg</span>
<span id="cb4-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>(resid[dates <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2023-01-01"</span>].mean())</span>
<span id="cb4-7"></span>
<span id="cb4-8">pd.DataFrame(</span>
<span id="cb4-9">    [{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"r* shift"</span>: <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>s<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:+.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kappa"</span>: k, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mean premium 2023-26"</span>: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(premium_under(s, k), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)}</span>
<span id="cb4-10">     <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> s <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> (<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.50</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.50</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> k <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> (<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.30</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.55</span>)]</span>
<span id="cb4-11">)</span></code></pre></div></div>
<div id="sensitivity" class="cell-output cell-output-display" data-execution_count="3">
<div>


<table class="dataframe caption-top table table-sm table-striped small" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th"></th>
<th data-quarto-table-cell-role="th">r* shift</th>
<th data-quarto-table-cell-role="th">kappa</th>
<th data-quarto-table-cell-role="th">mean premium 2023-26</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<th data-quarto-table-cell-role="th">0</th>
<td>-0.50</td>
<td>0.30</td>
<td>0.80</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">1</th>
<td>-0.50</td>
<td>0.55</td>
<td>0.94</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">2</th>
<td>+0.00</td>
<td>0.30</td>
<td>0.46</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">3</th>
<td>+0.00</td>
<td>0.55</td>
<td>0.54</td>
</tr>
<tr class="odd">
<th data-quarto-table-cell-role="th">4</th>
<td>+0.50</td>
<td>0.30</td>
<td>0.11</td>
</tr>
<tr class="even">
<th data-quarto-table-cell-role="th">5</th>
<td>+0.50</td>
<td>0.55</td>
<td>0.13</td>
</tr>
</tbody>
</table>

</div>
</div>
</div>
<p>The spread across that table is wider than the move everyone is attributing to risk premia. Which is the point: the term premium has not stopped existing, it has stopped being identified. When the residual’s range under defensible parameter choices exceeds the signal you are reading out of it, the honest statement is that the long end is being set by something the model does not contain — most plausibly duration supply and a genuinely unsettled neutral rate.</p>
</section>
<section id="what-i-would-do-instead" class="level2">
<h2 class="anchored" data-anchor-id="what-i-would-do-instead">What I would do instead</h2>
<p>Stop reporting a point estimate. Report the residual as a band across a grid of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><msup><mi>r</mi><mo>*</mo></msup><mo>,</mo><mi>κ</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(r^{\ast}, \kappa)</annotation></semantics></math> you are willing to defend, and say plainly that the width of the band is the size of your ignorance. That is less quotable than “the term premium is back,” and considerably more defensible.</p>
<p>Next in this thread: fitting the same curve with a supply term, and seeing whether the residual narrows enough to be worth the extra parameter.</p>
</section>
<section id="keep-exploring" class="level2">
<h2 class="anchored" data-anchor-id="keep-exploring">Keep exploring</h2>
<p>For another modelling project, see <a href="../../projects/vol-surface.html">vol-surface</a>, which focuses on fitting implied volatility while checking for arbitrage. Or <a href="../../articles.html">browse all articles</a>.</p>


</section>

 ]]></description>
  <category>rates</category>
  <category>macro</category>
  <guid>https://tomroth.dev/posts/term-premium/</guid>
  <pubDate>Tue, 03 Mar 2026 23:00:00 GMT</pubDate>
  <media:content url="https://tomroth.dev/posts/term-premium/thumbnail.png" medium="image" type="image/png" height="66" width="144"/>
</item>
<item>
  <title>Vol surface interpolation in 60 lines</title>
  <dc:creator>Tom Roth</dc:creator>
  <link>https://tomroth.dev/posts/vol-surface/</link>
  <description><![CDATA[ 




<p>Most of the difficulty in fitting an implied volatility surface is not the optimiser — it is keeping the result free of calendar and butterfly arbitrage once you interpolate between quoted expiries.</p>
<p><em>Full post in progress. The scaffold here exists so the home listing, archive, and tag filtering have real entries to render.</em></p>



 ]]></description>
  <category>python</category>
  <category>options</category>
  <guid>https://tomroth.dev/posts/vol-surface/</guid>
  <pubDate>Tue, 10 Feb 2026 23:00:00 GMT</pubDate>
</item>
<item>
  <title>Notes on Itô, slowly</title>
  <dc:creator>Tom Roth</dc:creator>
  <link>https://tomroth.dev/posts/ito-notes/</link>
  <description><![CDATA[ 




<p>The lemma is easy to apply and hard to believe. These are the notes I wrote while trying to move from the second to the first.</p>
<p><em>Full post in progress. The scaffold here exists so the home listing, archive, and tag filtering have real entries to render.</em></p>



 ]]></description>
  <category>math</category>
  <category>stochastic</category>
  <guid>https://tomroth.dev/posts/ito-notes/</guid>
  <pubDate>Wed, 21 Jan 2026 23:00:00 GMT</pubDate>
</item>
<item>
  <title>Backtesting my own bad ideas</title>
  <dc:creator>Tom Roth</dc:creator>
  <link>https://tomroth.dev/posts/backtesting-bad-ideas/</link>
  <description><![CDATA[ 




<p>A backtest that has not tried to kill your idea is a marketing document. This is an attempt to be adversarial toward my own hypotheses.</p>
<p><em>Full post in progress. The scaffold here exists so the home listing, archive, and tag filtering have real entries to render.</em></p>



 ]]></description>
  <category>stats</category>
  <category>python</category>
  <guid>https://tomroth.dev/posts/backtesting-bad-ideas/</guid>
  <pubDate>Mon, 08 Dec 2025 23:00:00 GMT</pubDate>
</item>
</channel>
</rss>
