I am trying to price a type of leveraged down-and-out (LDAO) barrier call option, using geometric Brownian motion.

My python script is below. I am not sure how to correctly model the increasing barrier B and leverage factor that multiplies the payoff when the stock price goes up.

The characteristics of this option are as follows.

  1. The "leveraged" part op the LDAO looks like this. When you buy the call, you only pay part of the spot price S0 of the underlying asset. The seller provides financing F0 to buy the rest. In other words, the buying price P of the option is: P = S -/- F.
  2. As a buyer, you pay interest i on the financing level F.
  3. The "down-and-out" part is structured as follows. When the price S of the underlying drops below the barrier B, the option is cancelled and the underlying asset is sold at the active market price. When the spot price S1 is lower than the financing F, your end value is zero. If the spot price is higher than the financing, your payout is S1 - F1 (F1 includes the interest). Your payout cannot be negative.
  4. The barrier B is increased daily by the amount of the interest on the financing level F. So B1 = B0 + F*(1 + i)^t
  5. The barrier B is always below the price of the underlying asset, but above the financing level: S0 > B > F

I have tried to implement this in the Python 3 script below. Any suggestions on how to get this right?

import numpy as np
from math import log, e

P = 30 # This is what you pay (S -/- F)
S = 360 # spot price of the stock
K = 340 Exercise price is equal to the stop-loss barrier (as far as I understand it)
B = 340 # the stop-loss barrier at which the option is cancelled
F = 330 # The financing level
T = 1 # Time to maturity. But in priciple, the option runs indefintely as long as S > B
i = 0.02 # Annualised interest rate on the financing F
r = 0.00135 # Risk-free rate of return
impliedVolatility = 0.3
num_reps = 100 

def barrier_option(option_type, s0, strike, B, F, maturity, i, r, sigma, num_reps):
    payoff_sum = 0
    for j in range(num_reps):
        st = S
        st = st*e**((r-0.5*sigma**2)*maturity + sigma*np.sqrt(maturity)*np.random.normal(0, 1))
        B_shift = B + F*(1+i)*np.sqrt(maturity) # Here the interest I on F gets adjusted by increasing B
        non_touch = (np.min(st) > B_shift)*1
        if option_type == 'c':
            payoff = max(0,st-strike)
        elif option_type == 'p':
            payoff = max(0,strike-st)
        payoff_sum += non_touch * payoff
    premium = (payoff_sum/float(num_reps))*e**(-r*maturity)
    return premium

Bar = barrier_option('c', S, K, B, F, (T*252)/365, i, r, impliedVolatility, num_reps)```
  • $\begingroup$ Check your B_shift value on each run... It's huge and so the non_touch is always 0 $\endgroup$ – David Duarte Jun 29 '20 at 22:03
  • $\begingroup$ Thanks a lot. Correct that and updated the question. I am unsure if the script models the option correctly. $\endgroup$ – twhale Jun 30 '20 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.