<p>There might be a closed-form method that is more efficient, but in practice, bond market calculations have a lot of irregularities when compared to the pricing formula given above.</p>

<p>As an addendum, if you have access to two functions, you can use Newton-Raphson.</p>

<ol>
<li>A function to calculate price from yield.</li>
<li>A function to calculate modified duration from the yield. This could be done by using the previous function, and approximating the modified duration by looking at the price change that results from a small yield shock.</li>
</ol>

<p>The modified duration (which I will shorten to “duration” here) is the sensitivity of price return as a percentage from a yield change (need to multiply by -1). E.g., if the duration is 2, a .01% rise in yields (approximately) gives a price percentage change of -0.02%.</p>

<p>You then follow this scheme.</p>

<ol>
<li>Start off with the yield estimate equalling the coupon. (If you are working from time series data, you could use the previous yield as a starting point.)</li>
<li>Calculate the price. If within the target margin of error of the market price, stop, you’re done.</li>
<li>Otherwise, calculate the duration for the bond at the estimated yield, and the deviation of the estimated price from the market price.</li>
<li>The new estimate is now the old yield plus the change required to get the new price to match the market price, based on the modified duration relation. E.g., yield change = -1*(price error in percentage terms)/(modified duration). </li>
<li>Using the new estimate, go back to step 2.</li>
</ol>

<p>This procedure eliminates the need to generate an upper and lower bound for the yield, and should converge faster. If you are working from a time series, the previous yield will tend to be close the current yield, and the duration price change estimate will be a good approximation of the actual price change, and so convergence may only take a few steps.</p>

CC BY-SA 4.0
2020-05-10T12:47:11.140Z
2020-05-10T12:47:11.140Z
Brian Romanchuk
<p>Following the suggestion by <a href="https://economics.stackexchange.com/users/12891/brian-romanchuk">Brian Romanchuk</a> of the 'quick and dirty' <a href="https://en.wikipedia.org/wiki/Bisection_method" rel="nofollow noreferrer">bisection method</a> in the comments, I wrote this python program to estimate the yield to maturity :</p>

<pre><code>def find_i(P, C, FV, n, epsilon):

    if P &gt; FV : i_min, i_max = 0 , C / FV 
    elif P &lt; FV : i_min, i_max = C / FV , 10
    else : return C / FV

    while True :

        i_mid = ( i_max + i_min ) / 2 # mid point of the current intervall 
        point = C*(1-(1+i_mid)**(-n))/i_mid + FV/(1+i_mid)**n - P # it should converge to 0

        if abs(point) &lt; epsilon  : return i_mid # if point is close enough to 0 then finish

        if point &gt; 0 : i_min = i_mid # [i_mid,i_max] : new intervall
        elif point &lt; 0 : i_max = i_mid # [i_min,i_mid] : new intervall

P, C, FV, n = 1100, 100, 1000, 10
epsilon = 10**-5
i = find_i(P, C, FV, n, epsilon)
</code></pre>

<p>The choice of <span class="math-container">$i_{min}$</span> and <span class="math-container">$i_{max}$</span> is important to estimate <span class="math-container">$i$</span> in edge cases.
Dealing with negative interest is harder.</p>

<p>I'm going to update the method to improve the computation , for now I list the relavant facts used :</p>

<p>1) When <span class="math-container">$P = FV $</span> then <span class="math-container">$i = C / FV$</span></p>

<p>2) <span class="math-container">$P$</span> and <span class="math-container">$i$</span> are negative correlated when <span class="math-container">$i&gt;0$</span></p>

CC BY-SA 4.0
2020-05-10T12:16:03.163Z
If you go with bisection, probably need to add code to search for wider limits if needed. Another alternative is the Newton-Raphson method, which also eliminates the need for hard limits. If you have a formula for the duration, you can use the duration to estimate what yield change causes the price to match the market price. It will converge faster.
Brian Romanchuk
CC BY-SA 4.0
2020-05-10T12:25:19.507Z
Thanks very much for this helpful comment ! I will for sure try to add some of this tools !
Tortar
CC BY-SA 4.0
2020-05-10T11:07:52.880Z
2020-05-11T18:09:23.657Z
2020-05-11T18:09:23.657Z
Tortar
<p>Given the formula  <span class="math-container">$P = \sum_{t=1}^n \frac{CF_t}{(1+i)^t} $</span> 
 we can apply it to the case of a bond with constant coupons so that : </p>

<p><span class="math-container">$\displaystyle P =\sum_{t=1}^n \frac{C}{(1+i)^t} + \frac{FV}{(1+i)^n}  \implies P = C(\frac{1-(1+i)^{-n}}{i})+\frac{FV}{(1+i)^n}$</span>  </p>

<p>with  <span class="math-container">$P$</span> = price , <span class="math-container">$C$</span> = coupon at the time <span class="math-container">$t$</span> , <span class="math-container">$FV$</span> = face value , <span class="math-container">$i$</span> = yield to maturity</p>

<p>My problem : How is it estimated <span class="math-container">$i$</span> when <span class="math-container">$P\neq FV$</span> and <span class="math-container">$P, C,FV$</span> are known ? </p>

<p>I think that it's not possible to obtain an exact result , because it doesn't seem possible to separate the <span class="math-container">$i$</span> from the rest . I tried to use Taylor formulas somehow to get an approximation but I haven't come to anything. </p>

<p>EDIT :</p>

<p>Is bisection method the only possible way to proceed ? Is something about polynomial approximation possible?</p>

CC BY-SA 4.0
2020-05-09T22:36:30.473Z
I’m used to more complex formulae (irregular day counts, etc.), and the quick and dirty solution is bisection - get an upper and lower limit, take the midpoint, and keep sub-dividing. There might be something more rigorous for the simplified formula you use there, so I won’t post this as the answer.
Brian Romanchuk
CC BY-SA 4.0
2020-05-09T22:41:59.213Z
ah yes , this could be a good way to proceed even if I guess it's an expensive method for what regards the number of computations
Tortar
CC BY-SA 4.0
2020-05-10T00:08:43.267Z
I would have worried about computational complexity in 1990. In 2020? Not as much. It converges at a known rate,  Since you are using a simplified formula, it’s presumably not a real time pricing application.
Brian Romanchuk
<mathematical-economics><computation>
Compute yield to maturity for a bond with coupons when price is different from face value
Tortar
# Compute yield to maturity for a bond with coupons when price is different from face value

(Asked by: username_0 on 2020-05-09)

Given the formula $P = \sum\_{t=1}^n \frac{CF\_t}{(1+i)^t} $
we can apply it to the case of a bond with constant coupons so that :

$\displaystyle P =\sum\_{t=1}^n \frac{C}{(1+i)^t} + \frac{FV}{(1+i)^n} \implies P = C(\frac{1-(1+i)^{-n}}{i})+\frac{FV}{(1+i)^n}$

with $P$ = price , $C$ = coupon at the time $t$ , $FV$ = face value , $i$ = yield to maturity

My problem : How is it estimated $i$ when $P\neq FV$ and $P, C,FV$ are known ?

I think that it's not possible to obtain an exact result , because it doesn't seem possible to separate the $i$ from the rest . I tried to use Taylor formulas somehow to get an approximation but I haven't come to anything.

EDIT :

Is bisection method the only possible way to proceed ? Is something about polynomial approximation possible?

**Tags:** mathematical-economics, computation
> **Comments:**
> **username_1**: I’m used to more complex formulae (irregular day counts, etc.), and the quick and dirty solution is bisection - get an upper and lower limit, take the midpoint, and keep sub-dividing. There might be something more rigorous for the simplified formula you use there, so I won’t post this as the answer.  
> **username_0**: ah yes , this could be a good way to proceed even if I guess it's an expensive method for what regards the number of computations  
> **username_1**: I would have worried about computational complexity in 1990. In 2020? Not as much. It converges at a known rate,  Since you are using a simplified formula, it’s presumably not a real time pricing application.  

---

## 2 answers

### Answer by username_1 on 2020-05-10. Score: 1 | Accepted answer

There might be a closed-form method that is more efficient, but in practice, bond market calculations have a lot of irregularities when compared to the pricing formula given above.

As an addendum, if you have access to two functions, you can use Newton-Raphson.

1. A function to calculate price from yield.
2. A function to calculate modified duration from the yield. This could be done by using the previous function, and approximating the modified duration by looking at the price change that results from a small yield shock.

The modified duration (which I will shorten to “duration” here) is the sensitivity of price return as a percentage from a yield change (need to multiply by -1). E.g., if the duration is 2, a .01% rise in yields (approximately) gives a price percentage change of -0.02%.

You then follow this scheme.

1. Start off with the yield estimate equalling the coupon. (If you are working from time series data, you could use the previous yield as a starting point.)
2. Calculate the price. If within the target margin of error of the market price, stop, you’re done.
3. Otherwise, calculate the duration for the bond at the estimated yield, and the deviation of the estimated price from the market price.
4. The new estimate is now the old yield plus the change required to get the new price to match the market price, based on the modified duration relation. E.g., yield change = -1\*(price error in percentage terms)/(modified duration).
5. Using the new estimate, go back to step 2.

This procedure eliminates the need to generate an upper and lower bound for the yield, and should converge faster. If you are working from a time series, the previous yield will tend to be close the current yield, and the duration price change estimate will be a good approximation of the actual price change, and so convergence may only take a few steps.


---

### Answer by username_0 on 2020-05-10. Score: 1

Following the suggestion by Brian Romanchuk of the 'quick and dirty' bisection method in the comments, I wrote this python program to estimate the yield to maturity :
def find_i(P, C, FV, n, epsilon):

    if P > FV : i_min, i_max = 0 , C / FV 
    elif P < FV : i_min, i_max = C / FV , 10
    else : return C / FV

    while True :

        i_mid = ( i_max + i_min ) / 2 # mid point of the current intervall 
        point = C*(1-(1+i_mid)**(-n))/i_mid + FV/(1+i_mid)**n - P # it should converge to 0

        if abs(point) < epsilon  : return i_mid # if point is close enough to 0 then finish

        if point > 0 : i_min = i_mid # [i_mid,i_max] : new intervall
        elif point < 0 : i_max = i_mid # [i_min,i_mid] : new intervall

P, C, FV, n = 1100, 100, 1000, 10
epsilon = 10**-5
i = find_i(P, C, FV, n, epsilon)

The choice of $i_{min}$ and $i_{max}$ is important to estimate $i$ in edge cases.
Dealing with negative interest is harder.
I'm going to update the method to improve the computation , for now I list the relavant facts used :
1) When $P = FV $ then $i = C / FV$
2) $P$ and $i$ are negative correlated when $i>0$

> **Comments:**
> **username_1**: If you go with bisection, probably need to add code to search for wider limits if needed. Another alternative is the Newton-Raphson method, which also eliminates the need for hard limits. If you have a formula for the duration, you can use the duration to estimate what yield change causes the price to match the market price. It will converge faster.  
> **username_0**: Thanks very much for this helpful comment ! I will for sure try to add some of this tools !  

---

