

# Barrier Options


```python
import pyvacon.analytics as analytics
import datetime as dt
import pyvacon.tools.converter as converter
import pyvacon.tools.enums as enums
import pyvacon.marketdata.testdata as mkt_testdata
import pyvacon.instruments.testdata as ins_testdata
import math
from scipy.stats import norm
import pyvacon.marketdata.plot as mkt_plot #import module for plotting functionality
#the next lin is a jupyter internal command to show the matplotlib graphs within the notebook
%matplotlib inline
```


```python
def exp(x):
    return math.exp(x)
def cdf(x):
    return norm.cdf(x)
def log(x):
    return math.log(x)
def sqrt(x):
    return math.sqrt(x)
```

## Definition of Barrier Options

Barrier options are options where the payoff depends on whether the underlying's spot price reaches a certain level during a certain period of time. Barrier options can be classified in know-out options and knock-in options. A knock-in option comes into existence only when the underlying's spot price reaches the defined barrier; a knock-out option ceases to exist if the underlying's spot prices reaches the defined barrier. The different barrier options including their payoff profile are presented in this notebook. For a detailed description please refer to Hull, *Options, futures, and other derivatives, 8th Edition,* 2012, pp. 579-581.

The following code defines the valuation formula for barrier options assuming a non-dividend paying stock.


```python
def BarrierOptionPricer(_Type, S0, K, H, r, q, sigma, T, t=0):
    _lambda = (r-q+sigma**2/2)/sigma**2
    y = (log(H**2/(S0*K)))/(sigma*sqrt(T-t))+_lambda*sigma*sqrt(T-t)
    x1 = (log(S0/H))/(sigma*sqrt(T-t))+_lambda*sigma*sqrt(T-t)
    y1 = (log(H/S0))/(sigma*sqrt(T-t))+_lambda*sigma*sqrt(T-t)
    d1= (log(S0/K)+(r+sigma**2/2)*(T-t))/(sigma*sqrt(T-t))
    d2 = d1-sigma*sqrt(T-t)
    p = -1*(S0*cdf(-1*d1)-K*exp(-r*(T-t))*cdf(-1*d2))
    c = 1*(S0*cdf(1*d1)-K*exp(-r*(T-t))*cdf(1*d2))
    cdi = S0*exp(-q*(T-t))*(H/S0)**(2*_lambda)*cdf(y)-K*exp(-r*(T-t))*(H/S0)**(2*_lambda-2)*cdf(y-sigma*sqrt(T-t))
    cdo = S0*cdf(x1)*exp(-q*(T-t))-K*exp(-r*(T-t))*cdf(x1-sigma*sqrt(T-t))-S0*exp(-q*(T-t))*(H/S0)**(2*_lambda)*cdf(y1)+K*exp(-r*(T-t))*(H/S0)**(2*_lambda-2)*cdf(y1-sigma*sqrt(T-t))
    cui = S0*cdf(x1)*exp(-q*(T-t))-K*exp(-r*(T-t))*cdf(x1-sigma*sqrt(T-t))-S0*exp(-q*(T-t))*(H/S0)**(2*_lambda)*(cdf(-y)-cdf(-y1))+K*exp(-r*(T-t))*(H/S0)**(2*_lambda-2)*(cdf(-y+sigma*sqrt(T-t))-cdf(-y1+sigma*sqrt(T-t)))
    pui = -S0*exp(-q*(T-t))*(H/S0)**(2*_lambda)*cdf(-y)+K*exp(-r*(T-t))*(H/S0)**(2*_lambda-2)*cdf(-y+sigma*sqrt(T-t))
    puo = -S0*cdf(-x1)*exp(-q*(T-t))+K*exp(-r*(T-t))*cdf(-x1+sigma*sqrt(T-t))+S0*exp(-q*(T-t))*(H/S0)**(2*_lambda)*cdf(-y1)-K*exp(-r*(T-t))*(H/S0)**(2*_lambda-2)*cdf(-y1+sigma*math.sqrt(T-t))
    pdi = -S0*cdf(-x1)*exp(-q*(T-t))+K*exp(-r*(T-t))*cdf(-x1+sigma*sqrt(T-t))+S0*exp(-q*(T-t))*(H/S0)**(2*_lambda)*(cdf(y)-cdf(y1))-K*exp(-r*(T-t))*(H/S0)**(2*_lambda-2)*(cdf(y-sigma*sqrt(T-t))-cdf(y1-sigma*sqrt(T-t)))
    if _Type =='cdi' and H<K and S0>H:
        return cdi
    if _Type =='cdi' and H>=K and S0>H:
        return c-cdo
    if _Type =='cdi' and S0<=H:
        return c
    if _Type =='cdo' and H<K and S0>H:
        return c-cdi
    if _Type =='cdo' and H<K and S0<=H:
        return 0
    if _Type =='cdo' and H>=K and S0>H:
        return cdo
    if _Type =='cdo' and H>=K and S0<=H:
        return 0
    if _Type =='cui' and H>K:
        return cui
    if _Type =='cui' and H<=K:
        return c
    if _Type =='cuo' and H>K and S0<H:
        return c-cui
    if _Type =='cuo' and H>K and S0>=H:
        return 0
    if _Type =='cuo' and H<=K:
        return 0.0
    if _Type =='pui' and H>=K and S0<H:
        return pui
    if _Type =='pui' and H<K and S0<H:
        return p-puo
    if _Type =='pui' and S0>=H:
        return p
    if _Type =='puo':
        if S0>=H:
            return 0
        else:
            if _Type =='puo' and H>=K:
                return p-pui
            if _Type =='puo' and H<K:
                return puo
    if _Type =='pdi' and H>=K:
        return p
    if _Type =='pdi' and H<K:
        return pdi
    if _Type =='pdo' and H>=K:
        return 0
    if _Type =='pdo' and H<K and S0>H:
        return p-pdi
    if _Type =='pdo' and H<K and S0<=H:
        return 0
    if _Type =='c':
        return c
    if _Type =='p':
        return p
```


```python
spots = analytics.vectorDouble()

S0 = 30
n=0.1
while n <=100:
    spots.append(n)
    n=n+0.1

K = 50
H1 = 40
H2 = 60
r = 0.05
q = 0
sigma = 0.3
T = 1
t = 0
```

### Barrier call options

#### Down-and-in call

A down-and-in call is a call option which comes into existence if the stock price hits a barrier which is below the initial asset price.

If the barrier $H$ is less than or equal to the strike price $K$, the formula to price a down-and-in call is defined as

$$c_{di}=S_0e^{-qT}(H/S_0)^{2\lambda}N(y)-Ke^{-rT}(H/S_0)^{2\lambda-2}N(y-\sigma\sqrt{T}),$$

where 

\begin{align}
\lambda &= \frac{r-q+\sigma^2/2}{\sigma^2} \\
y &= \frac{\ln[H^2/(S_0K)]}{\sigma\sqrt{T}}+\lambda\sigma\sqrt{T}. \\
\end{align}

$S_0$ is the underlying's spot price, $K$ is the strike price, $H$ is the barrier level, $\sigma$ is the underlying's volatility, $r$ is the risk-free interest rate, $q$ is the borrowing rate, and $T$ is the time to maturity. $N(x)$ is the cumulative probability distribution function for a standardized normal distribution.

If the barrier is greater than or equal to the strike price, the formula for the down-and-in call is

$$c_{di}=c-c_{do}.$$


```python
# Assumption that H has not been reached yet. If H is reached, product becomes normal plain vanilla call.

cdi_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    cdi_price1.append(BarrierOptionPricer('cdi', spots[s], K, H1, r, q, sigma, T, t))
vanilla_call1 = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_call1.append(BarrierOptionPricer('c', spots[s], K, H1, r, q, sigma, T, t))
    
cdi_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    cdi_price2.append(BarrierOptionPricer('cdi', spots[s], K, H2, r, q, sigma, T, t))
    
fig, (cdi1, cdi2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
cdi1.plot(spots, cdi_price1, 'k', label='Down-and-in call')
cdi1.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cdi1.set_title('Down-and-in call H<K')
cdi1.set_xlabel('Spot')
cdi1.set_ylabel('Price')
cdi1.axvline(x=K, label='Strike', ls= '--', c='g')
cdi1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = cdi1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, cdi2 = mkt_plot.plt.subplots()
cdi2.plot(spots, cdi_price2, 'k', label='Down-and-in call')
cdi2.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cdi2.set_title('Down-and-in call H>K')
cdi2.set_xlabel('Spot')
cdi2.set_ylabel('Price')
cdi2.axvline(x=K, label='Strike', ls= '--', c='g')
cdi2.axvline(x=H2, label='Barrier', ls=':', c='r')
legend = cdi2.legend(loc='best', shadow=True, fontsize='medium')
```

#### Down-and-out call

A down-and-out call in a call option that ceases to exists when the stock price hits a barrier which is below the initial asset price.

If $H \leq K$, the formula for the down-and-out call is 

$$c_{do}=c-c_{di},$$

if $H \geq K$, the formula is 

$$c_{do}=S_0N(x_1)e^{-qT}-Ke^{-rT}N(x_1-\sigma\sqrt{T})-S_0e^{-qT}(H/S_0)^{2\lambda}N(y_1)+Ke^{-rT}(H/S_0)^{2\lambda-2}N(y_1-\sigma\sqrt{T})$$

where 

\begin{align}
x_1 &=\frac{\ln(S_0/H}{\sigma\sqrt{T}}+\lambda\sigma\sqrt{T} \\
y_1 &=\frac{\ln(H/S_0}{\sigma\sqrt{T}}+\lambda\sigma\sqrt{T}. \\
\end{align}


```python
vanilla_call1 = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_call1.append(BarrierOptionPricer('c', spots[s], K, H1, r, q, sigma, T, t))

cdo_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    cdo_price1.append(BarrierOptionPricer('cdo', spots[s], K, H1, r, q, sigma, T, t))
    
cdo_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    cdo_price2.append(BarrierOptionPricer('cdo', spots[s], K, H2, r, q, sigma, T, t))
    
fig, (cdo1, cdo2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
cdo1.plot(spots, cdo_price1, 'k', label='Down-and-out call')
cdo1.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cdo1.set_title('Down-and-out call H<K')
cdo1.set_xlabel('Spot')
cdo1.set_ylabel('Price')
cdo1.axvline(x=K, label='Strike', ls= '--', c='g')
cdo1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = cdo1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, cdo2 = mkt_plot.plt.subplots()
cdo2.plot(spots, cdo_price2, 'k', label='Down-and-out call')
cdo2.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cdo2.set_title('Down-and-out call H>K')
cdo2.set_xlabel('Spot')
cdo2.set_ylabel('Price')
cdo2.axvline(x=K, label='Strike', ls= '--', c='g')
cdo2.axvline(x=H2, label='Barrier', ls=':', c='r')
legend = cdo2.legend(loc='best', shadow=True, fontsize='medium')
```

#### Up-and-in call

An up-and-in call is a call option which comes into existence if the spots hits a barrier which is above the initial asset price.

In the case of $H \leq K$ the value of the up-and-in call $c_{ui}$ is $c$.

When $H > K$ the formula for the up-and-in call is defined as

$$c_{ui}=S_0N(x_1)e^{-qT}-Ke^{-rT}N(x_1-\sigma\sqrt{T})-S_0e^{-qT}(H/S_0)^{2\lambda}[N(-y)-N(-y_1)]+Ke^{-rT}(H/S_0)^{2\lambda-2}[N(-y+\sigma\sqrt{T})-N(-y_1+\sigma\sqrt{T})].$$


```python
# Assumption that H has not been reached yet. If the barrier is hit, the it is a plain vanilla call.

vanilla_call1 = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_call1.append(BarrierOptionPricer('c', spots[s], K, H1, r, q, sigma, T, t))

cui_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    cui_price1.append(BarrierOptionPricer('cui', spots[s], K, H1, r, q, sigma, T, t))
    
cui_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    cui_price2.append(BarrierOptionPricer('cui', spots[s], K, 80, r, q, sigma, T, t))

fig, (cui1, cui2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
cui1.plot(spots, cui_price1, 'k', label='Up-and-in call')
cui1.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cui1.set_title('Up-and-in call H<K')
cui1.set_xlabel('Spot')
cui1.set_ylabel('Price')
cui1.axvline(x=K, label='Strike', ls= '--', c='g')
cui1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = cui1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, cui2 = mkt_plot.plt.subplots()
cui2.plot(spots, cui_price2, 'k', label='Up-and-in call')
cui2.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cui2.set_title('Up-and-in call H>K')
cui2.set_xlabel('Spot')
cui2.set_ylabel('Price')
cui2.axvline(x=K, label='Strike', ls= '--', c='g')
cui2.axvline(x=80, label='Barrier', ls=':', c='r')
legend = cui2.legend(loc='best', shadow=True, fontsize='medium')    
```

#### Up-and-out call

An up-and-out call is a call option which ceases to exist when the stock price hits a barrier which is above the initial asset price.

When $H \leq K$, the value of the up-and-out call is zero.

When $H > K$, formula for the up-and-out call is defined as 

$$c_{uo}=c-c_{ui}.$$


```python
vanilla_call1 = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_call1.append(BarrierOptionPricer('c', spots[s], K, H1, r, q, sigma, T, t))

cuo_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    cuo_price1.append(BarrierOptionPricer('cuo', spots[s], K, H1, r, q, sigma, T, t))
    
cuo_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    cuo_price2.append(BarrierOptionPricer('cuo', spots[s], K, H2, r, q, sigma, T, t))
    
fig, (cuo1, cuo2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
cuo1.plot(spots, cuo_price1, 'k', label='Up-and-out call')
#cuo1.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cuo1.set_title('Up-and-out call H<K')
cuo1.set_xlabel('Spot')
cuo1.set_ylabel('Price')
cuo1.axvline(x=K, label='Strike', ls= '--', c='g')
cuo1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = cuo1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, cuo2 = mkt_plot.plt.subplots()
cuo2.plot(spots, cuo_price2, 'k', label='Up-and-out call')
#cuo2.plot(spots, vanilla_call1, 'y:', label='Plain vanilla call')
cuo2.set_title('Up-and-out call H>K')
cuo2.set_xlabel('Spot')
cuo2.set_ylabel('Price')
cuo2.axvline(x=K, label='Strike', ls= '--', c='g')
cuo2.axvline(x=H2, label='Barrier', ls=':', c='r')
legend = cuo2.legend(loc='best', shadow=True, fontsize='medium')
```

### Barrier put options

#### Down-and-in put

A down-and-in put is a put option which comes into existence if the spot price hits a barrier which is below the initial asset price.

When the barrier is greater than or equal to the strike price, the value of the down-and-in put is equal to a plain vanilla put $p$. If the barrier is less than the strike price, the formula for the down-and-in put is defined as 

$$p_{di}=-S_0N(-x_1)e^{-qT}+Ke^{-rT}N(-x_1+\sigma\sqrt{T})+S_0e^{-qT}(H/S_0)^{2\lambda}[N(y)-N(y_1)]-Ke^{-rT}(H/S_0)^{2\lambda-2}[N(y-\sigma\sqrt{T}-N(y_1-\sigma\sqrt{T}].$$


```python
# H<K: As soon as the barrier is hit, the down-and-in put becomes a plain vanilla put.

vanilla_put = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_put.append(BarrierOptionPricer('p', spots[s], K, H1, r, q, sigma, T, t))

pdi_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    pdi_price1.append(BarrierOptionPricer('pdi', spots[s], K, 30, r, q, sigma, T, t))
    
pdi_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    pdi_price2.append(BarrierOptionPricer('pdi', spots[s], K, H2, r, q, sigma, T, t))
    
fig, (pdi1, pdi2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
pdi1.plot(spots, pdi_price1, 'k', label='Down-and-in put')
pdi1.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
pdi1.set_title('Down-and-in put H<K')
pdi1.set_xlabel('Spot')
pdi1.set_ylabel('Price')
pdi1.axvline(x=K, label='Strike', ls= '--', c='g')
pdi1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = pdi1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, pdi2 = mkt_plot.plt.subplots()
pdi2.plot(spots, pdi_price2, 'k', label='Down-and-in put')
pdi2.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
pdi2.set_title('Down-and-in put H>K')
pdi2.set_xlabel('Spot')
pdi2.set_ylabel('Price')
pdi2.axvline(x=K, label='Strike', ls= '--', c='g')
pdi2.axvline(x=H2, label='Barrier', ls=':', c='r')
legend = pdi2.legend(loc='best', shadow=True, fontsize='medium')  
```

#### Down-and-out put

A down-and-out put is a put option which ceases to exists when the spot price hits a barrier which is below the initial asset price.

When the barrier is greater than or equal to the strike price, the value of the down-and-out put is zero. If the barrier is less than the strike price, the formula for the down-and-out put is defined as

$$p_{do} = p - p_{di}.$$


```python
vanilla_put = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_put.append(BarrierOptionPricer('p', spots[s], K, H1, r, q, sigma, T, t))

pdo_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    pdo_price1.append(BarrierOptionPricer('pdo', spots[s], K, H1, r, q, sigma, T, t))
    
pdo_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    pdo_price2.append(BarrierOptionPricer('pdo', spots[s], K, H2, r, q, sigma, T, t))

fig, (pdo1, pdo2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
pdo1.plot(spots, pdo_price1, 'k', label='Down-and-out put')
#pdo1.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
pdo1.set_title('Down-and-out put H<K')
pdo1.set_xlabel('Spot')
pdo1.set_ylabel('Price')
pdo1.axvline(x=K, label='Strike', ls= '--', c='g')
pdo1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = pdo1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, pdo2 = mkt_plot.plt.subplots()
pdo2.plot(spots, pdo_price2, 'k', label='Down-and-out put')
#pdo2.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
pdo2.set_title('Down-and-out put H>K')
pdo2.set_xlabel('Spot')
pdo2.set_ylabel('Price')
pdo2.axvline(x=K, label='Strike', ls= '--', c='g')
pdo2.axvline(x=H2, label='Barrier', ls=':', c='r')
legend = pdo2.legend(loc='best', shadow=True, fontsize='medium')        
```

#### Up-and-in put

An up-and-in put is a put option that comes into existence if the spot price hits a barrier which is above the initial asset price.

When $H \geq K$, the formula for the up-and-in put is defined as

$$ p_{ui}=S_0e^{-qT}(H/S_0)^{2\lambda}N(-y)+Ke^{-rT}(H/S_0)^{2\lambda-2}N(-y+\sigma\sqrt{T})$$

when $H<K$ the formula is 

$$ p_{ui}=p-p_{uo}.$$


```python
vanilla_put = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_put.append(BarrierOptionPricer('p', spots[s], K, H1, r, q, sigma, T, t))

pui_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    pui_price1.append(BarrierOptionPricer('pui', spots[s], K, H1, r, q, sigma, T, t))
    
pui_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    pui_price2.append(BarrierOptionPricer('pui', spots[s], K, H2, r, q, sigma, T, t))
    
fig, (pui1, pui2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
pui1.plot(spots, pui_price1, 'k', label='Up-and-in put')
pui1.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
pui1.set_title('Up-and-in put H<K')
pui1.set_xlabel('Spot')
pui1.set_ylabel('Price')
pui1.axvline(x=K, label='Strike', ls= '--', c='g')
pui1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = pui1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, pui2 = mkt_plot.plt.subplots()
pui2.plot(spots, pui_price2, 'k', label='Up-and-in put')
pui2.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
pui2.set_title('Up-and-in H>K')
pui2.set_xlabel('Spot')
pui2.set_ylabel('Price')
pui2.axvline(x=K, label='Strike', ls= '--', c='g')
pui2.axvline(x=H2, label='Barrier', ls=':', c='r')
legend = pui2.legend(loc='best', shadow=True, fontsize='medium') 
```

#### Up-and-out put

An up-and-out put is a put option which ceases to exists when the spot price hits a barrier which is above the initial asset price.

When r $H \geq K$, the formula for the up-and-out put is defined as

$$ p_{uo}=p-p_{ui},$$

when $H<K$ the formula is 

$$p_{uo}=-S_0N(-x_1)e^{-qT}+Ke^{-rT}N(-x_1+\sigma\sqrt{T})+S_0e^{-qT}(H/S_0)N(-y_1)-Ke^{-rT}(H/S_0)^{2\lambda-2}N(-y_1+\sigma\sqrt{T}).$$


```python
vanilla_put = analytics.vectorDouble()
for s in range(len(spots)):
    vanilla_put.append(BarrierOptionPricer('p', spots[s], K, H1, r, q, sigma, T, t))

puo_price1 = analytics.vectorDouble()
for s in range(len(spots)):
    puo_price1.append(BarrierOptionPricer('puo', spots[s], K, H1, r, q, sigma, T, t))
    
puo_price2 = analytics.vectorDouble()
for s in range(len(spots)):
    puo_price2.append(BarrierOptionPricer('puo', spots[s], K, H2, r, q, sigma, T, t))

fig, (puo1, puo2) = mkt_plot.plt.subplots(1,2, figsize=(12,4),dpi=100,num=1)
puo1.plot(spots, puo_price1, 'k', label='Up-and-out put')
puo1.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
puo1.set_title('Up-and-out put H<K')
puo1.set_xlabel('Spot')
puo1.set_ylabel('Price')
puo1.axvline(x=K, label='Strike', ls= '--', c='g')
puo1.axvline(x=H1, label='Barrier', ls=':', c='r')
legend = puo1.legend(loc='best', shadow=True, fontsize='medium')
    
#fig, puo2 = mkt_plot.plt.subplots()
puo2.plot(spots, puo_price2, 'k', label='Up-and-out put')
puo2.plot(spots, vanilla_put, 'y:', label='Plain vanilla put')
puo2.set_title('Up-and-out H>K')
puo2.set_xlabel('Spot')
puo2.set_ylabel('Price')
puo2.axvline(x=K, label='Strike', ls= '--', c='g')
puo2.axvline(x=H2, label='Barrier', ls=':', c='r')
legend = puo2.legend(loc='best', shadow=True, fontsize='medium')    
```

---

5233a8e98bfff0c287afa0db2b85c6c5c7d9a956
ipynb
Jupyter Notebook
instruments/barrier_options.ipynb
frontmark/jupyter-notebooks
556a01bc4d3f2dc9b44af9c167aaabf35d23f5ba
MIT
2020-01-16T17:05:07.000Z
2022-02-17T00:59:00.000Z
instruments/barrier_options.ipynb
frontmark/jupyter-notebooks
556a01bc4d3f2dc9b44af9c167aaabf35d23f5ba
MIT
2020-05-01T10:19:24.000Z
2020-10-07T10:40:03.000Z
instruments/barrier_options.ipynb
frontmark/jupyter-notebooks
556a01bc4d3f2dc9b44af9c167aaabf35d23f5ba
MIT
2020-01-31T18:52:56.000Z
2022-03-27T12:06:01.000Z
Qwen/Qwen-72B
1. YES
2. YES