# NAG FL Interfaces30acf (opt_​imp_​vol)

## ▸▿ Contents

Settings help

FL Name Style:

FL Specification Language:

## 1Purpose

s30acf computes the implied volatility of a European option contract based on the Black–Scholes–Merton formula.

## 2Specification

Fortran Interface
 Subroutine s30acf ( n, p, k, s0, t, r, mode,
 Integer, Intent (In) :: n, mode Integer, Intent (Inout) :: ifail Integer, Intent (Out) :: ivalid(n) Real (Kind=nag_wp), Intent (In) :: p(n), k(n), s0(n), t(n), r(n) Real (Kind=nag_wp), Intent (Out) :: sigma(n) Character (1), Intent (In) :: calput
#include <nag.h>
 void s30acf_ (const char *calput, const Integer *n, const double p[], const double k[], const double s0[], const double t[], const double r[], double sigma[], const Integer *mode, Integer ivalid[], Integer *ifail, const Charlen length_calput)
The routine may be called by the names s30acf or nagf_specfun_opt_imp_vol.

## 3Description

The Black–Scholes formula for the price of a European option is
 $Pcall = S0 Φ ( ln( S0 K ) + [r+ σ2 2 ] T σT ) - K e -rT Φ ( ln( S0 K ) + [r- σ2 2 ] T σ T ) ,$
for a call option, and
 $Pput = K e-rT Φ ( - ln( S0 K ) - [r- σ2 2 ] T σ T ) - S0 Φ ( - ln( S0 K ) - [r+ σ2 2 ] T σ T ) ,$
for a put option, where $\Phi$ is the cumulative Normal distribution function, $T$ is the time to maturity, ${S}_{0}$ is the spot price of the underlying asset, $K$ is the strike price, $r$ is the interest rate and $\sigma$ is the volatility.
Given arrays of values ${P}_{i}$, ${K}_{i}$, ${S}_{0i}$, ${T}_{i}$ and ${r}_{i}$, for $i=1,2,\dots n$, s30acf computes the implied volatilities ${\sigma }_{i}$.
s30acf offers the choice of two algorithms. The algorithm of Glau et al. (2018) uses Chebyshev interpolation to compute the implied volatilities, and performs best for long arrays of input data. The algorithm of Jäckel (2015) uses a third order Householder iteration and performs better for short arrays of input data.
Glau K, Herold P, Madan D B and Pötz C (2018) The Chebyshev method for the implied volatility Accepted for publication in the Journal of Computational Finance
Jäckel P (2015) Let's be Rational Wilmott Magazine 2015(75) 40–53

## 5Arguments

1: $\mathbf{calput}$Character(1) Input
On entry: determines whether the option is a call or a put.
${\mathbf{calput}}=\text{'C'}$
A call; the holder has a right to buy.
${\mathbf{calput}}=\text{'P'}$
A put; the holder has a right to sell.
Constraint: ${\mathbf{calput}}=\text{'C'}$ or $\text{'P'}$.
2: $\mathbf{n}$Integer Input
On entry: $n$, the number of implied volatilities to be computed.
Constraint: ${\mathbf{n}}\ge 0$.
3: $\mathbf{p}\left({\mathbf{n}}\right)$Real (Kind=nag_wp) array Input
On entry: ${\mathbf{p}}\left(i\right)$ must contain ${P}_{i}$, the $i$th option price, for $i=1,2,\dots ,n$.
Constraint: ${\mathbf{p}}\left(\mathit{i}\right)\ge 0.0$, for $\mathit{i}=1,2,\dots ,n$.
4: $\mathbf{k}\left({\mathbf{n}}\right)$Real (Kind=nag_wp) array Input
On entry: ${\mathbf{k}}\left(i\right)$ must contain ${K}_{i}$, the $i$th strike price, for $i=1,2,\dots ,n$.
Constraint: ${\mathbf{k}}\left(\mathit{i}\right)>0.0$, for $\mathit{i}=1,2,\dots ,n$.
5: $\mathbf{s0}\left({\mathbf{n}}\right)$Real (Kind=nag_wp) array Input
On entry: ${\mathbf{s0}}\left(i\right)$ must contain ${S}_{0i}$, the $i$th spot price, for $i=1,2,\dots ,n$.
Constraint: ${\mathbf{s0}}\left(\mathit{i}\right)>0.0$, for $\mathit{i}=1,2,\dots ,n$.
6: $\mathbf{t}\left({\mathbf{n}}\right)$Real (Kind=nag_wp) array Input
On entry: ${\mathbf{t}}\left(i\right)$ must contain ${T}_{i}$, the $i$th time, in years, to maturity, for $i=1,2,\dots ,n$.
Constraint: ${\mathbf{t}}\left(\mathit{i}\right)>0.0$, for $\mathit{i}=1,2,\dots ,n$.
7: $\mathbf{r}\left({\mathbf{n}}\right)$Real (Kind=nag_wp) array Input
On entry: ${\mathbf{r}}\left(i\right)$ must contain ${r}_{i}$, the $i$th interest rate, for $i=1,2,\dots ,n$. Note that a rate of 5% should be entered as 0.05.
8: $\mathbf{sigma}\left({\mathbf{n}}\right)$Real (Kind=nag_wp) array Output
On exit: ${\mathbf{sigma}}\left(i\right)$ contains ${\sigma }_{i}$, the $i$th implied volatility, for $i=1,2,\dots ,n$.
9: $\mathbf{mode}$Integer Input
On entry: specifies which algorithm will be used to compute the implied volatilities. See Sections 7 and 8 for further guidance on the choice of mode.
${\mathbf{mode}}=0$
The Glau et al. (2018) algorithm will be used. The nodes used in the Chebyshev interpolation will be chosen to achieve relative accuracy to approximately seven decimal places;
${\mathbf{mode}}=1$
The Glau et al. (2018) algorithm will be used. The nodes used in the Chebyshev interpolation will be chosen to achieve relative accuracy to approximately $15$ decimal places, but limited by the machine precision;
${\mathbf{mode}}=2$
The Jäckel (2015) algorithm will be used, aiming for accuracy to approximately $15$$16$ decimal places, but limited by machine precision.
Constraint: ${\mathbf{mode}}=0$, $1$ or $2$.
10: $\mathbf{ivalid}\left({\mathbf{n}}\right)$Integer array Output
On exit: ${\mathbf{ivalid}}\left(i\right)$ indicates any errors with the input arguments that prevented ${\sigma }_{i}$ from being computed. If ${\mathbf{ivalid}}\left(i\right)\ne 0$, ${\mathbf{sigma}}\left(i\right)$ contains $0.0$.
${\mathbf{ivalid}}\left(i\right)=0$
No error.
${\mathbf{ivalid}}\left(i\right)=1$
${P}_{i}<0.0$.
${\mathbf{ivalid}}\left(i\right)=2$
${K}_{i}\le 0.0$.
${\mathbf{ivalid}}\left(i\right)=3$
${S}_{0i}\le 0.0$.
${\mathbf{ivalid}}\left(i\right)=4$
${T}_{i}\le 0.0$.
${\mathbf{ivalid}}\left(i\right)=5$
The combination of ${P}_{i}$, ${K}_{i}$, ${S}_{0i}$, ${T}_{i}$ and ${r}_{i}$ is out of the domain in which ${\sigma }_{i}$ can be computed. See Section 9 for further details.
11: $\mathbf{ifail}$Integer Input/Output
On entry: ifail must be set to $0$, $-1$ or $1$ to set behaviour on detection of an error; these values have no effect when no error is detected.
A value of $0$ causes the printing of an error message and program execution will be halted; otherwise program execution continues. A value of $-1$ means that an error message is printed while a value of $1$ means that it is not.
If halting is not appropriate, the value $-1$ or $1$ is recommended. If message printing is undesirable, then the value $1$ is recommended. Otherwise, the value $0$ is recommended. When the value $-\mathbf{1}$ or $\mathbf{1}$ is used it is essential to test the value of ifail on exit.
On exit: ${\mathbf{ifail}}={\mathbf{0}}$ unless the routine detects an error or a warning has been flagged (see Section 6).

## 6Error Indicators and Warnings

If on entry ${\mathbf{ifail}}=0$ or $-1$, explanatory error messages are output on the current error message unit (as defined by x04aaf).
Errors or warnings detected by the routine:
${\mathbf{ifail}}=1$
On entry at least one input argument was invalid.
${\mathbf{ifail}}=2$
On entry, ${\mathbf{n}}=⟨\mathit{\text{value}}⟩$.
Constraint: ${\mathbf{n}}\ge 0$.
${\mathbf{ifail}}=3$
On entry, ${\mathbf{mode}}=⟨\mathit{\text{value}}⟩$.
Constraint: ${\mathbf{mode}}=0$, $1$ or $2$.
${\mathbf{ifail}}=4$
On entry, ${\mathbf{calput}}=⟨\mathit{\text{value}}⟩$ was an illegal value.
${\mathbf{ifail}}=-99$
See Section 7 in the Introduction to the NAG Library FL Interface for further information.
${\mathbf{ifail}}=-399$
Your licence key may have expired or may not have been installed correctly.
See Section 8 in the Introduction to the NAG Library FL Interface for further information.
${\mathbf{ifail}}=-999$
Dynamic memory allocation failed.
See Section 9 in the Introduction to the NAG Library FL Interface for further information.

## 7Accuracy

If ${\mathbf{mode}}=0$ or $1$ then s30acf uses Chebyshev interpolation. For ${\mathbf{mode}}=0$ it aims for relative accuracy to roughly single precision (approximately seven decimal places). For ${\mathbf{mode}}=1$ it aims for relative accuracy to roughly double precision (approximately sixteen decimal places).
If ${\mathbf{mode}}=2$, a Householder iteration is used to achieve relative accuracy to roughly double precision (approximately sixteen decimal places). In practice there is very little difference in accuracy between ${\mathbf{mode}}=1$ and $2$, though for more extreme input values, ${\mathbf{mode}}=2$ is likely to be more accurate.

## 8Parallelism and Performance

s30acf is threaded by NAG for parallel execution in multithreaded implementations of the NAG Library.
Please consult the X06 Chapter Introduction for information on how to control and interrogate the OpenMP environment used within this routine. Please also consult the Users' Note for your implementation for any additional implementation-specific information.
When ${\mathbf{mode}}=0$ or $1$, s30acf uses an algorithm optimized for performance on large vectors of input data ($n\gtrsim 1000$) by exploiting vector instructions when available.
When ${\mathbf{mode}}=2$, s30acf uses an algorithm optimized for performance on smaller vectors of input data.
Numerical experiments suggest that for $n\lesssim 1000$, the best performance is always achieved by choosing ${\mathbf{mode}}=2$, whereas for $n\gtrsim 1000$, ${\mathbf{mode}}=0$ or $1$ should be used, according to the desired accuracy.

The domain of inputs, ${P}_{i}$, ${K}_{i}$, ${S}_{0i}$, ${T}_{i}$ and ${r}_{i}$, for which s30acf is able to accurately compute ${\sigma }_{i}$ is very large and should cover all practical applications of this routine. Thus, encountering arguments for which ${\mathbf{ivalid}}\left(i\right)=5$ is returned is highly unlikely. Note that it is not possible to give a closed-form expression for the allowed range of arguments because this range is based on a transformation to the normalized call price.
Note that some formulations of the Black–Scholes equation also include the annual yield rate, $q$. If you wish to incorporate $q$ here, then you must first compute the quantities ${\stackrel{~}{S}}_{0}={S}_{0}{e}^{-qT}$, $\stackrel{~}{K}=K{e}^{-qT}$ and $\stackrel{~}{r}=r-q$. s30acf should then be called with ${\stackrel{~}{S}}_{0}$, $\stackrel{~}{K}$ and $\stackrel{~}{r}$ in place of ${S}_{0}$, $K$ and $r$ respectively.
s30acf can also be used with Black's model for European futures options. In this case, the forward price, $F$, and the discount factor, $D$, are used, which are related to ${S}_{0}$ via $F={S}_{0}/D$. In addition, the option price is scaled by a factor ${e}^{-rT}$.
Approximately $7×n$ of real allocatable memory and $3×n$ of integer allocatable memory is required by the routine.

## 10Example

This example reads in values of ${P}_{i}$, ${K}_{i}$, ${S}_{0i}$, ${T}_{i}$ and $r$ from a file, evaluates the implied volatilities, ${\sigma }_{i}$, and prints the results.

### 10.1Program Text

Program Text (s30acfe.f90)

### 10.2Program Data

Program Data (s30acfe.d)

### 10.3Program Results

Program Results (s30acfe.r)