Skip to content
All library documents

Barrier Option Pricing with Discrete Monitoring in a Binomial Model

Article Quant Q&A · Author: user57440

Summary

The document defines a European barrier call whose payoff depends on the asset finishing above the strike and staying above a lower barrier at specified observation times. It asks how to estimate its discounted risk-neutral value by Monte Carlo simulation and shows an attempted binomial-tree implementation. The example supplies up and down factors, a rate, maturity, strike, initial price, barrier, and monitoring dates.

The code and warning messages illustrate numerical difficulties when the tree is made extremely fine while retaining fixed per-step up and down factors. Those factors should be scaled consistently with the time increment; otherwise the implied price distribution changes as the step count grows, and powers can overflow. The snippet also uses a barrier comparison that conflicts with the stated lower-barrier survival condition, refers to an undefined variable, and calls a tree recursion rather than a Monte Carlo estimator. The document provides no corrected implementation or simulation results, so it identifies a pricing problem but does not establish an answer.

Key ideas

  • A discretely monitored barrier call pays only when its terminal price condition and barrier survival conditions are both met.
  • A binomial tree’s up and down factors must be consistent with the length of each time step.
  • Using fixed factors while greatly increasing the number of steps can cause overflow and distort the modeled dynamics.
  • The barrier comparison in an implementation must match whether crossing the barrier knocks the option in or out.
  • A binomial-tree recursion and a Monte Carlo estimator are distinct pricing approaches.

Tags

Full text
# How can I simulate the barrier option call model in Python?


# How can I simulate the barrier option call model in Python?












We have a barrier call option of European type with strike price $K>0$ and a barrier value

$0 < b< S_0$,

where $S_0$ is the starting price.According to the contract, the times $0<t_1<...<t_k<T$ the price must be checked $S(t_k)>b$ for every $k$.

The payoff function : $$C_{T} = \max(S(T)-K) \mathbf{1}_{S(t_{1})> b \cap \dots \cap S(t_k)>b }$$

Assuming the $S(t)$ is described with the binomial option model with $u=1.1$ and $d = 0.9,r=0.05,T=10$, and $t_1=2,t_2=4$ and $t_3=7$ the times that the asset must be checked.Also consider the $S_0=100,K=125$ and the barrier $b=60$.

Run a Monte Carlo simulation with `n=[100,1000,10000,50000]` to estimate the $$\left(\frac{1}{1+r}\right)^{T} E_{\mathbb{Q}}[C_{T}]$$

My attempt is the following :

```
# Initialise parameters
S0 = 100      # initial stock price
K = 125       # strike price
T = 10        # time to maturity in years
b = 60        # up-and-out barrier price/value
r = 0.05      # annual risk-free rate
N = 4         # number of time steps
u = 1.1       # up-factor in binomial models
d = 0.9       # ensure recombining tree
opttype = 'C' # Option Type 'C' or 'P'

def barrier_binomial(K,T,S0,b,r,N,u,d,opttype='C'):
    #precompute values
    dt = T/N
    q = (1+r - d)/(u-d)
    disc = np.exp(-r*dt)
    
    # initialise asset prices at maturity
    S = S0 * d**(np.arange(N,-1,-1)) * u**(np.arange(0,N+1,1))
        
    # option payoff
    if opttype == 'C':
        C = np.maximum( S - K, 0 )
    else:
        C = np.maximum( K - S, 0 )
            
    # check terminal condition payoff
    C[S >= b] = 0
            
    # backward recursion through the tree
    for i in np.arange(N-1,-1,-1):
        S = S0 * d**(np.arange(i,-1,-1)) * u**(np.arange(0,i+1,1))
        C[:i+1] = disc * ( q * C[1:i+2] + (1-q) * C[0:i+1] )
        C = C[:-1]
        C[S >= H] = 0
    return C[0]

for N in [100, 1000, 10000, 50000]:
    barrier_binomial(K,T,S0,b,r,N,u,d,opttype='C')
```

What is my mistake here ? I can't find out what.Any help ?

```
<ipython-input-24-eea44e75eec5>:8: RuntimeWarning: overflow encountered in power
  S = S0 * d**(np.arange(N,-1,-1)) * u**(np.arange(0,N+1,1))
<ipython-input-24-eea44e75eec5>:21: RuntimeWarning: overflow encountered in power
  S = S0 * d**(np.arange(i,-1,-1)) * u**(np.arange(0,i+1,1))
<ipython-input-24-eea44e75eec5>:21: RuntimeWarning: overflow encountered in multiply
  S = S0 * d**(np.arange(i,-1,-1)) * u**(np.arange(0,i+1,1))
<ipython-input-24-eea44e75eec5>:8: RuntimeWarning: invalid value encountered in multiply
  S = S0 * d**(np.arange(N,-1,-1)) * u**(np.arange(0,N+1,1))
<ipython-input-24-eea44e75eec5>:17: RuntimeWarning: invalid value encountered in greater_equal
  C[S >= b] = 0
<ipython-input-24-eea44e75eec5>:21: RuntimeWarning: invalid value encountered in multiply
  S = S0 * d**(np.arange(i,-1,-1)) * u**(np.arange(0,i+1,1))
<ipython-input-24-eea44e75eec5>:24: RuntimeWarning: invalid value encountered in greater_equal
  C[S >= b] = 0
```

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.