Convertible Bond
From ThetaWiki
Contents |
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, and what is our main focus here, the issuer usually has to give notice some period in advance (e.g. 1 month) of calling the issue.
Implementation in a ThetaScript
Model Convertible import S "Stock" 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" import kappa "Conversion Ratio" import spread "Credit spread" export P "Price of convertible" export V_obs % monthly conversion n = 12 * T P = E(V) Coupon_time = 0 fork loop inf V_obs = E(V) Theta @dt end end fork % Compute trigger (10 days above trigger ~ trigger >=10) Trigger_counter = 0 loop inf if kappa*S > B_t Trigger_counter = Trigger_counter + 1 else Trigger_counter = 0 end Theta 5/250 end end fork % implement conversion constraint loop n if E(V!)<kappa * S V = kappa * S end Theta 1/12 end end 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
Here, we use Theta.m which creates a numeraire EUR with a stochastic default rate corresponding to the stock price S. The stock price's excess drift 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

