Putting it all together – implied volatility modeling

In the options pricing methods we learned so far, a number of parameters are assumed to be constant: interest rates, strike prices, dividends, and volatility. Here, the parameter of interest is volatility. In quantitative research, the volatility ratio is used to forecast price trends.

To derive implied volatilities, we need to refer to Chapter 3, Nonlinearity in Finance where we discussed root-finding methods of nonlinear functions. We will use the bisection method of numerical procedures in our next example to create an implied volatility curve.

Implied volatilities of AAPL American put option

Let's consider the option data of the stock Apple (AAPL) gathered at the end of day on October 3, 2014, given in the following table. The option expires on December 20, 2014. The prices listed are the mid-points of the bid and ask prices:

Strike price

Call price

Put price

75

30

0.16

80

24.55

0.32

85

20.1

0.6

90

15.37

1.22

92.5

10.7

1.77

95

8.9

2.54

97.5

6.95

3.55

100

5.4

4.8

105

4.1

7.75

110

2.18

11.8

115

1.05

15.96

120

0.5

20.75

125

0.26

25.81

The last traded price of AAPL was 99.62 with an interest rate of 2.48 percent and a dividend yield of 1.82 percent. The American options expire in 78 days.

Using this information, let's create a new class named ImpliedVolatilityModel that accepts the stock option's parameters in the __init__ constructor method. Import the BinomialLROption class that we created for the Leisen-Reimer binomial tree covered in the earlier section of this chapter. Also, import the bisection.py file that we created using the bisection function covered in Chapter 3, Nonlinearity in Finance.

The _option_valuation_ method accepts the strike price K and the volatility value sigma to compute the value of the option. In this example, we are using the BinomialLROption pricing method.

The get_implied_volatilities public method accepts a list of strike and option prices to compute the implied volatilities by the bisection method for every price available. Therefore, the length of the two lists must be the same.

The Python code for the ImpliedVolatilityModel is given as follows:

"""
Get implied volatilities from a Leisen-Reimer binomial
tree using the bisection method as the numerical procedure.
"""
from bisection import bisection
from BinomialLROption import BinomialLROption

class ImpliedVolatilityModel(object):

    def __init__(self, S0, r, T, div, N,
                 is_call=False):
        self.S0 = S0
        self.r = r
        self.T = T
        self.div = div
        self.N = N
        self.is_call = is_call

    def _option_valuation_(self, K, sigma):
        # Use the binomial Leisen-Reimer tree
        lr_option = BinomialLROption(
            self.S0, K, self.r,  self.T, self.N,
            {"sigma": sigma,
             "is_call": self.is_call,
             "div": self.div})
        return lr_option.price()

    def get_implied_volatilities(self, Ks, opt_prices):
        impvols = []
        for i in range(len(Ks)):
            # Bind f(sigma) for use by the bisection method
            f = lambda sigma: 
                self._option_valuation_(
                    Ks[i], sigma) - opt_prices[i]
            impv = bisection(f, 0.01, 0.99, 0.0001, 100)[0]
            impvols.append(impv)
        return impvols
if __name__ == "__main__":

Using this model, let's find out the implied volatilities of the American put options using this particular set of data:

>>> # The data
>>> strikes = [ 75, 80, 85, 90, 92.5, 95, 97.5,
...             100, 105, 110, 115, 120, 125]
>>> put_prices = [0.16, 0.32, 0.6, 1.22, 1.77, 2.54, 3.55,
...               4.8, 7.75, 11.8, 15.96, 20.75, 25.81]
>>>
>>> model = ImpliedVolatilityModel(99.62, 0.0248, 78/365.,
...                           0.0182, 77, is_call=False)
>>> impvols_put = model.get_implied_volatilities(strikes, 
                                             put_prices) 

The implied volatility values are now stored in the impvols_put variable as a list object. Let's plot these values against the strike prices so that we can get an implied volatility curve:

>>> import matplotlib.pyplot as plt
>>> plt.plot(strikes, impvols_put)
>>> plt.xlabel('Strike Prices')
>>> plt.ylabel('Implied Volatilities')
>>> plt.title('AAPL Put Implied Volatilities expiring in 78 days')
>>> plt.show()

This would give us the volatility smile, as shown in the following figure. Here, we have modeled a Leisen-Reimer tree with 77 steps, each step representing one day:

Implied volatilities of AAPL American put option

Of course, pricing an option daily may not be ideal since markets change by fractions of a millisecond. We used the bisection method to solve the implied volatility as implied by the binomial tree, as opposed to the realized volatility values directly observed from market prices.

Should we fit this curve against a polynomial curve to identify potential arbitrage opportunities? Or extrapolate the curve to derive further insights on potential opportunities from implied volatilities of far out-of-the-money and in-the-money options? Well, these questions are for options traders like you to find out!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.220.16