Welcome to THETAWIKI. If you like to create or edit a page please make sure to login or register an account. All registered users please make sure to provide a valid email address.

Convertible Bond

From ThetaWiki
Jump to: navigation, search

Overview

Convertible bonds incorporate a variety of features. The instrument might be convertible into shares of the issuing company or in some cases into shares of a different company. Convertibles can usually be converted by the holder at any time. Often these bonds can be sold back (or "put") to the issuer at specific dates for a guaranteed price. In addition, the issuer may have the right to redeem or call back the convertible at a specified call price. If the issuer does so, the investor can choose between receiving the call price or converting into shares.

The ability of the issuer to call back the issue is frequently restricted by "soft" and "hard" call constraints. A hard call constraint prohibits calling the issue during the initial life of the contract. A soft call constraint requires that the issuer's stock price remains above a discretely-observed trigger level before the issue can be called, i.e., the convertible cannot be called until the underlying has been m out of n days above the trigger level. In addition, to call the issue, the issuer usually has to give notice some time in advance (e.g. 1 month). Here we mainly focus on pricing the convertible bond with this feature.

Implementation in a ThetaML

The underlying 'S' and the discount numeraire 'EUR' are processes simulated externally. For example, the process 'S' can be a stock price process that follows a Geometric Brownian Motion or a Heston Volatility process. The discount numeraire 'EUR' can be a constant discount curve as implemented in Discounting, or a stochastic process that has a dynamics as defined in the CIR model.

model Convertible
  import S       "Stock prices"
  import F       "Face value"
  import C       "Coupon value"
  import EUR     "Numeraire with default"
  import T       "Maturity time"
  import B_c     "Call price"
  import B_t     "Call trigger price"
  import sigma   "Vola"
  import r       "Interest rate"
  import kappa   "Conversion Ratio"
  import spread  "Credit spread"
  export P       "Price of convertible"
  export V_obs
 
  % monthly conversion
  n = 12 * T
  %at current time, set the option value to have the same expected discounted
  %value as the variable 'V'; the ThetaML future operator '!' accompanying the
  %variable 'V' acts like a function on 'V', such that the values of 'V'at
  %current time remain to be determined at a later instance when 'V' is assigned
  %some values
  P = E(V!)
  Coupon_time = 0
  %a fork ... end statement that virtually parallels the processes defined within the
  %statement and processes inside another fork ... end statement or outside in the model body
  fork
    %an infinite loop, the loop length automatically extends to the desired length of the pricing application
    loop inf
      V_obs = E(V!)
      %the ThetaML command 'Theta' passes time by '@dt' time intervals
      %the ThetaML parameter '@dt' extracts the smallest time interval passing to the next model time point
      Theta @dt
    end
  end
  %a fork ... end statement that virtually parallels the processes defined within the
  %statement and processes inside another fork ... end statement or outside in the model body
  fork
    % Compute trigger (10 days above trigger ~ trigger >=10)
    Trigger_counter = 0
    %an infinite loop, the loop length automatically extends to the desired length of the pricing application
    loop inf
      if kappa*S > B_t
	Trigger_counter = Trigger_counter + 1
      else
	Trigger_counter = 0
      end
      %the ThetaML command 'Theta' passes time by '5/250' years
      Theta 5/250
    end
  end
  %a fork ... end statement that virtually parallels the processes defined within the
  %statement and processes inside another fork ... end statement or outside in the model body
  fork
    % implement conversion constraint
    loop n
      if E(V!)<kappa * S
	V = kappa * S
      end
      Theta 1/12
    end
  end
  %a fork ... end statement that virtually parallels the processes defined within the
  %statement and processes inside another fork ... end statement or outside in the model body
  fork
    % implement soft call constraint
    loop n
 
      % Call convertible if trigger constraint satisfied and calling is
      % optimal for the issuer
      if (E(V!)> E(V_called!)) & Trigger_counter >= 2
	V = V_called!
      end
 
      % Compute price after call notice
      fork
	Theta 20/250
	% compute accrued interest
	Accrued =  Coupon! * (Coupon_time!-@time)/(Coupon_time! - Coupon_time)
	V_called = max(kappa*S, (B_c + Accrued) * EUR )
      end
 
      Theta 1/12
    end
  end
 
  % implement payment of coupons
  loop T
    Theta 1
    V = V! + C * EUR
    % remember coupon value and time for computation of
    % accrued interest
    Coupon = C
    Coupon_time = @time
  end
  % pay face value at maturity time
  V = F*EUR + C * EUR
end

Stochastic model with default

The following Theta.m creates a numeraire EUR with stochastic default rates. The stochastic default rates are derived from the stock price S process. The drift of stock price increments consists of a risk-free component and a stochastic component that corresponds to the risk-neutral default probability.

function state = Theta(dt, state)
 
if nargin == 0    
    state.S.comment='Stock price process';
    state.S.value=10.03;    
    state.EUR.comment = 'Numeraire';
    state.EUR.value=1;    
    state.sigma.comment = 'Volatility';
    state.sigma.value = 0.4;    
    state.r.comment = 'Risk-free rate';
    state.r.value = 0.05;    
    state.spread.value = 0.02;
    state.spread.comment = 'Credit Spread';
else
    % no excess return for risk-free stock price process    
    p_0 = state.spread(1); 
    mu = state.r(1) + p_0 * (state.S/10.23).^(-1.2); 
 
    sigma = state.sigma(1); % constant volatility
    state.S   = state.S .* exp( (mu-0.5*sigma^2)*dt + sqrt(dt)*sigma*randn(size(state.S)));
    state.EUR = exp(-dt .* (state.r+mu) ) .* state.EUR;    
end

Thetagram

Convertible.png