Saturday, January 13, 2018

Strange Delta for FX Down And Out Call, Strike below Barrier


Based on this text about FX options on pages 139, 141 and 145 I'm trying to compute the delta of a down and out call with the strike below the barrier. Here is a quick and dirty Python code (I assume 0 interest rates and ignore the rebate for simplicity):


from scipy.stats import norm
from math import log, sqrt
def delta(ttm,S,K,H,sig):

x1 = ((sig*sqrt(ttm))**-1) * (log(S/H)+(0.5*sig**2)*ttm)
y1 = ((sig*sqrt(ttm))**-1) * (log(H/S)+(0.5*sig**2)*ttm)
mu = -0.5*sig**2
lam = 1+(mu*sig**-2)

E = S*((H/S)**(2*lam))*norm.cdf(y1)-K*((H/S)**(2*lam-2))*norm.cdf(y1-sig*sqrt(ttm))

dDdS = norm.cdf(x1)-K*(norm.pdf(x1)/(sig*sqrt(ttm)))*(1-(K/H))

dEdS = (2/S)*(1-lam)*E-((H/S)**(2*lam))*norm.cdf(y1) \

- ((H/S)**(2*lam))*(norm.pdf(y1)/(sig*sqrt(ttm)))*((K/H)-1)
return dDdS -dEdS

#args: ttm,spot,strike,barrier,vol
delta(0.2,1400,1300,1350,0.2)
>> -193.12173389762643 #this looks bad
delta(0.2,1.400,1.300,1.350,0.2)
>> 0.6447696223910977



http://www.quantonline.co.za/documents/FxDerivativesAdvFinT1.pdf



My question is not about the code. I'm pretty sure it is correct but really wonder why the results are so strange? Can this delta really become negative (I think no), or is the formula wrong? Maybe someone else already read the mentioned text and can comment?



Answer



Pricing


In order to answer you question regarding the computation of the delta, I need to take a brief detour into pricing first. When the underlying asset follows a geometric Brownian motion, then barrier options can be easily priced using the method of images; see e.g. Buchen (2001). The notation I use is very similar to the one in my paper Zhang and Thul (2017) and I refer to its appendix A and B for details (sorry for the plug).


Using this approach, we can show that the price of a down-and-out call option with a barrier above the strike is given by


\begin{equation} \tilde{V}(S, \tau) = \mathcal{A}_B^+(S, \tau) - K \mathcal{B}_B^+(S, \tau) - \stackrel{B}{\mathcal{I}} \left\{ \mathcal{A}_B^+(S, \tau) - K \mathcal{B}_B^+(S, \tau) \right\}, \end{equation}


where


\begin{eqnarray} \mathcal{A}_\xi^s (S, \tau) & = & S e^{-\delta \tau} \mathcal{N} \left( s d_1 \right),\\ \mathcal{B}_\xi^s (S, \tau) & = & e^{-r \tau} \mathcal{N} \left( s d_0 \right),\\ d_\eta & = & \frac{1}{\sigma \sqrt{\tau}} \left( \ln \left( \frac{S}{\xi} \right) + \left( r - \delta + \left( \eta - \frac{1}{2} \right) \sigma^2 \right) \tau \right),\\ \stackrel{B}{\mathcal{I}} \left\{ \tilde{V}(S, \tau) \right\} & = & \left( \frac{S}{B} \right)^{2 \alpha} \tilde{V} \left( \frac{B^2}{S}, \tau \right),\\ \alpha & = & \frac{1}{2} - \frac{r - \delta}{\sigma^2}. \end{eqnarray}



Here, $\mathcal{A}_\xi^s(S, \tau)$ if the valuation function of an asset binary option that pays off one unit of the underlying asset if $s S_T > s \xi$ where $s \in \{ -1, +1 \}$ indicates a put or call. Similarly, $\mathcal{B}_\xi^s(S, \tau)$ is the valuation function of a bond binary option that pays off one currency unit. $\stackrel{B}{\mathcal{I}}$ is called the image operator.


To get the derivatives, we use that


\begin{eqnarray} \frac{\partial}{\partial S} \mathcal{A}_\xi^s(S, \tau) & = & e^{-\delta \tau} \mathcal{N} \left( s d_1 \right) + s S e^{-\delta \tau} \mathcal{N}' \left( s d_1 \right) \frac{\partial d_1}{\partial S},\\ \frac{\partial}{\partial S} \mathcal{B}_\xi^s(S, \tau) & = & s e^{-r \tau} \mathcal{N}' \left( s d_0 \right) \frac{\partial d_0}{\partial S},\\ \frac{\partial}{\partial S} d_\eta & = & \frac{1}{S \sigma \sqrt{\tau}},\\ \frac{\partial}{\partial S} \stackrel{B}{\mathcal{I}} \left\{ \tilde{V}(S, \tau) \right\} & = & \left( \frac{S}{B} \right)^{2 \alpha} \left( \frac{2 \alpha}{S} \tilde{V} \left( \frac{B^2}{S}, \tau \right) - \frac{B^2}{S^2} \frac{\partial \tilde{V}}{\partial S} \left( \frac{B^2}{S}, \tau \right) \right). \end{eqnarray}


I did not go through the tedious task of checking if this actually agrees with the formula that you referenced.


Code


import numpy
import scipy.stats as stats

def assetBinary1D(maturity, xi, phi, spot, rate, dividend, volatility):
totalVolatility = volatility * numpy.sqrt(maturity)

dPlus = (numpy.log(spot / xi) + (rate - dividend + 0.5 * volatility**2) * maturity) / totalVolatility
dPlusCDF = stats.norm.cdf(phi * dPlus)
discountFactorDividend = numpy.exp(-dividend * maturity)
value = spot * discountFactorDividend * dPlusCDF
derivative = discountFactorDividend * (dPlusCDF + phi * spot * stats.norm.pdf(phi * dPlus) / (spot * totalVolatility))
return (value, derivative)

def bondBinary1D(maturity, xi, phi, spot, rate, dividend, volatility):
totalVolatility = volatility * numpy.sqrt(maturity)
dMinus = (numpy.log(spot / xi) + (rate - dividend - 0.5 * volatility**2) * maturity) / totalVolatility

discountFactorRate = numpy.exp(-rate * maturity)
value = discountFactorRate * stats.norm.cdf(phi * dMinus)
derivative = phi * discountFactorRate * stats.norm.pdf(phi * dMinus) / (spot * totalVolatility)
return (value, derivative);

def imageOperator(valueFunction, barrier, spot, rate, dividend, volatility):
alpha = 0.5 - (rate - dividend) / volatility**2
imageFactor = (spot / barrier)**(2.0 * alpha)
value, derivative = valueFunction(barrier**2 / spot)
value2 = imageFactor * value

derivative2 = imageFactor * (2.0 * alpha / spot * value - (barrier / spot)**2 * derivative)
return (value2, derivative2)

# attention: only for barriers above the strike!
def downAndOutCall(maturity, strike, barrier, spot, rate, dividend, volatility):
def valueFunction(spot):
value, derivative = assetBinary1D(maturity, barrier, 1.0, spot, rate, dividend, volatility)
value2, derivative2 = bondBinary1D(maturity, barrier, 1.0, spot, rate, dividend, volatility)
return (value - strike * value2, derivative - strike * derivative2)
value, derivative = valueFunction(spot)

value2, derivative2 = imageOperator(valueFunction, barrier, spot, rate, dividend, volatility)
return (value - value2, derivative - derivative2)

This yields


downAndOutCall(0.2, 1300.0, 1350.0, 1400.0, 0.0, 0.0, 0.2)
>> (65.16660154600855, 1.2863311571074099)

Delta


Down-and-out call delta.


The delta is, just like the slope of the payoff function, non-negative everywhere.



Edit


Full source code can be found on GitHub.


References


Buchen, Peter W. (2001) "Image Options and the Road to Barriers," Risk Magazine, Vol. 14, No. 9, pp. 127-130


Zhang, Ally Quan and Matthias Thul (2017) "How Much is the Gap? Efficient Jump-Risk Adjusted Valuation of Leverage Certificates," Quantitative Finance, forthcoming, available on SSRN


No comments:

Post a Comment

technique - How credible is wikipedia?

I understand that this question relates more to wikipedia than it does writing but... If I was going to use wikipedia for a source for a res...