Broadie and Kaya Capital Structure Model
import numpy as np
import matplotlib.pyplot as plt
from math import log, sqrt, exp
from scipy import stats
from scipy import optimize as sco
%matplotlib inline
We begin by modeling the dynamics of the unlevered firm under the risk neutral measure. Specifically, we have:
V
T
=
V
0
e
(
r
f
−
q
)
T
−
σ
2
2
T
+
σ
T
Z
T
V_T = V_0e^{(r_f-q)T -\frac{\sigma^2}{2}T + \sigma \sqrt{T}Z_T}
VT=V0e(rf−q)T−2σ2T+σTZT
Here, the unlevered firm generates cash at the proportional rate,
q
q
q. The expected value of the assets of the firm is
E
0
[
V
T
]
=
V
0
e
(
r
f
−
q
)
T
E_0[V_T] = V_0e^{(r_f-q)T}
E0[VT]=V0e(rf−q)T. Since the total expected return should grow at the riskless rate, the accrued value of the cash generated over time T is
V
0
e
q
T
−
V
0
V_0e^{qT}-V_0
V0eqT−V0.
We approximate the dynamics with a binomial model with a time partition of width
Δ
t
\Delta t
Δt. The cash produced by the firm when its value is
V
t
V_t
Vt is given by
V
t
δ
t
V_t \delta_t
Vtδt where
δ
=
e
q
Δ
t
−
1
\delta = e^{q\Delta t} - 1
δ=eqΔt−1
At each node of the lattice we have the asset value and cash. We have the usual binomial model parameterization, namely:
\begin{eqnarray*}
u &=& e^{\sigma\sqrt{\Delta t}}\
d&=& 1/u\
p &=& \frac{e^{(r_f-q)\Delta t}-d}{(u-d)}\
\delta &=& (e^{q\Delta t} - 1)
\end{eqnarray*}
Then, on the lattice we have:
V
t
=
[
p
(
V
t
+
Δ
t
+
(
1
+
δ
)
+
(
1
−
p
)
(
V
t
+
Δ
t
−
(
1
+
δ
)
]
e
−
r
Δ
t
V_t = \left[p(V^+_{t+\Delta t}(1+\delta) + (1-p)(V^-_{t+\Delta t}(1+\delta)\right]e^{-r\Delta t}
Vt=[p(Vt+Δt+(1+δ)+(1−p)(Vt+Δt−(1+δ)]e−rΔt
where
V
t
+
Δ
+
V^+_{t+\Delta}
Vt+Δ+ is the successor up node, and
V
t
+
Δ
−
V^-_{t+\Delta}
Vt+Δ− is the successor down node.
n = 3;T=3;sigma =0.40;r=0.06;q = 0.04; V0 = 100;F = 90; FF = 90; cr = 0.05;tau = 0.25;b = 0.50
dt = T/n; u = exp(sigma*sqrt(dt)); d = 1/u; disc = exp(-r*dt); p = (exp((r-q)*dt) - d)/(u - d); pbar = 1-p;
delta = exp(q*dt)-1
c = cr*FF*dt
n = 3
#V[j,t].....j downjumps in t periods j = 0....,t
V = np.zeros((4,4))
cash = np.zeros((4,4))
V[0,0] = V0
for t in range(1,4):
V[0,t] = u*V[0,t-1]
cash[0,t] = V[0,t]*delta
V[t,t] = d*V[t-1,t-1]
cash[t,t] = delta*V[t,t]
for t in range(2, n+1):
for j in range(1,t):
V[j, t] = V[j-1,t]*d**2
cash[j,t] = V[j,t]*delta
print('Value of Assets, V \n')
print(V)
print('')
print('Cash Generation, cash \n')
print(cash)
Value of Assets, V
[[100. 149.18246976 222.55409285 332.01169227]
[ 0. 67.0320046 100. 149.18246976]
[ 0. 0. 44.93289641 67.0320046 ]
[ 0. 0. 0. 30.11942119]]
Cash Generation, cash
[[ 0. 6.08825209 9.08260483 13.5496542 ]
[ 0. 2.735628 4.08107742 6.08825209]
[ 0. 0. 1.83374629 2.735628 ]
[ 0. 0. 0. 1.2291969 ]]
- Assume a firm has issued a bond that promises to pay coupons at a total rate of C C C per year.
- The face value of the debt is F F F. The effective tax rate is τ \tau τ.
- The government subsidy is τ C \tau C τC per year, so the effective cost of the coupons is ( 1 − τ ) C (1- \tau)C (1−τ)C per year.
- Given the time increments of the lattice, we can compute the exact time periods where a coupon payment is scheduled and where a principal payment is scheduled. Let c t c_t ct be the net payment due at time period t t t.
- In the case where a firm had only one coupon bond outstanding, with face value F and coupon payment c, then c t c_t ct would equal 0 if time increment did not correspond to a coupon date, It would equal c c c if the date wasa coupon date and it would equal c + F c+F c+F if it t t t was the maturity date.
- The debt obligation at any time period is paid from the firms cash flow, δ t \delta_t δt at date t.
- If the debt payment is smaller than the cash flow, then there is no problem. The residual is paid off as a dividend to the shareholders.
- However, if the debt obligation is greater than the cash flow, then, if it is in the interest of the shareholders, they will either issue equity to cover the shortfall, or if it is not in the shareholders interest they will default.
For the moment, assume we are at a node in the lattice. The present value of the equity, ignoring the current coupon and current cash flow is given by:
E
~
=
e
−
r
f
Δ
t
(
p
E
+
+
(
1
−
p
)
E
−
)
\tilde{E} = e^{-r_f\Delta t}(pE^+ + (1-p)E^-)
E~=e−rfΔt(pE++(1−p)E−)
Similarly, the present value of the debt and the present value of the unlevered firm are:
\begin{eqnarray*}
\tilde{D} &=&e^{-r_f\Delta t}(pD^+ + (1-p)D^-)\
\tilde{V} &=& e^{-r_f\Delta t}(pV^+ + (1-p)V^-)
\end{eqnarray*}
In computing these values we are ignoring any events that occur at the current node. Clearly, these values need to be modified based on events such as coupon payments, liquidation and distress costs.
-
Now suppose at this node we are trying to compute the value of the equity, E t E_t Et, and that we know E t + Δ t + E^+_{t+\Delta t} Et+Δt+ and E t + Δ t − E^-_{t+\Delta t} Et+Δt−.
-
Further assume the cash generated by the firm is δ V t \delta V_t δVt and the coupon payment is c t c_t ct. Let s t s_t st be the shortfall, representing the difference between the coupon payment and the cash available, s t = c t − δ V t s_t = c_t-\delta V_t st=ct−δVt.
-
If the shortfall, s t < 0 s_t <0 st<0, there is no problem in that the cash generated by the firm exceeds the coupon payment. However, if the shortfall is positive, s t > 0 s_t>0 st>0, then the issue is less clear. Since there is a shortfall, the firm has to raise equity, or the firm defaults. Broadie and Kaya show that at this node, the value of the equity can always be written as:
KaTeX parse error: Undefined control sequence: \mbox at position 36: …{array}{cc} 0& \̲m̲b̲o̲x̲{if } \tilde{E_… -
The equation says that as long as the present value of equity is higher than the shortfall, then the equityholders will find it optimal to raise cash by issuing equity, and that the value of the eqiuity will be given as above.
5.We now have all the ingredients to determine the equity, debt and financial distress costs at each node in the lattice.
At time T = n Δ t T= n\Delta t T=nΔt we know the asset value V T V_T VT and cash δ V T \delta V_T δVT at each node.
If
V
T
(
1
+
δ
)
>
(
1
−
τ
)
c
T
+
F
V_T(1 + \delta) > (1-\tau)c_T + F
VT(1+δ)>(1−τ)cT+F then the firm is in good shape:
\begin{eqnarray}
E_T &=& V_T(1+\delta) - (1-\tau)c_T -F \
D_T &=& c_T + F\
V_T^L &=& V_T(1+\delta) + \tau c_T
\end{eqnarray}
On the other hand, if
V
T
(
1
+
δ
)
<
(
1
−
τ
)
c
T
+
F
V_T(1 + \delta) < (1-\tau)c_T + F
VT(1+δ)<(1−τ)cT+F then the firm is not in good shapeand
\begin{eqnarray}
E_T &=& 0 \
D_T &=& (1-b)V_T(1+\delta)\
V_T^L &=& D_T
\end{eqnarray}
Given these boundary conditions, we now work backwards in the lattice using risk neutral valuation. For example:
\begin{eqnarray*}
\tilde{E}{t} &=& e^{-r_f\Delta t}(pE^+{t+\Delta t} + (1-p)E^-{t+\Delta t})\
\tilde{D}t &=&e^{-r_f\Delta t}(pD^+{t+\Delta t} + (1-p)D^-{t+\Delta t})\
\tilde{V}^L_t &=& e^{-r_f\Delta t}(pV^{L+}{t+\Delta t} + (1-p)V^{L-}{t+\Delta t})
\end{eqnarray*}
Then if
E
~
t
+
V
t
δ
≥
(
1
−
τ
)
c
t
\tilde{E}_t + V_t\delta \geq (1-\tau)c_t
E~t+Vtδ≥(1−τ)ct, we are in good shape, and:
\begin{eqnarray*}
{E}_{t} &=& \tilde{E} + V_t\delta - (1-\tau)c_t\
{D}_t &=& \tilde{D}_t = c_t\
{V}^L_t &=& \tilde{V}_t^L + V_t\delta + \tau c_t
\end{eqnarray*}
On the other hand if
E
~
t
+
V
t
δ
<
(
1
−
τ
)
c
t
\tilde{E}_t + V_t\delta < (1-\tau)c_t
E~t+Vtδ<(1−τ)ct, we are not in good shape and:
\begin{eqnarray*}
{E}_{t} &=& 0\
{D}_t &=& (1-b)V_t( 1+\delta)\
{V}^L_t &=& D_t
\end{eqnarray*}
Below is a three period problem which illustrates the basic idea
# This is a three period sample program
eq = np.zeros((4,4))
bond = np.zeros((4,4))
VL = np.zeros((4,4))
law = np.zeros((4,4))
tax = np.zeros((4,4))
for j in range(0, 4):
if V[j,3] +cash[j,3] > (1-tau)*c + F:
eq[j,3] = V[j,3] + cash[j,3] - ((1-tau)*c + F)
bond[j,3] = c + F
VL[j,3] = V[j,3] + cash[j,3] + tau*c
law[j,3] = 0
tax[j,3] = tau*c
else:
eq[j,3] = 0
bond[j,3] = (1-b)*(V[j,3]+cash[j,3])
VL[j,3] = bond[j,3]
law[j,3] = b*(V[j,3] + cash[j,3])
tax[j,3] = 0.0
for t in range(2, -1, -1):
for j in range(0, t+1):
eqtilde = disc*(p*eq[j, t+1] + pbar*eq[j+1, t+1])
btilde = disc*(p*bond[j, t+1] + pbar*bond[j+1,t+1])
VLtilde = disc*(p*VL[j, t+1] + pbar*VL[j+1, t+1])
lawtilde = disc*(p*law[j, t+1]+ pbar*law[j+1, t+1])
taxtilde = disc*(p*tax[j,t+1]+pbar*tax[j+1,t+1])
if (eqtilde +cash[j,t] > ( 1-tau)*c):
eq[j,t] = eqtilde + cash[j,t]- (1-tau)*c
bond[j,t] = btilde + c
VL[j,t] = VLtilde + cash[j,t] + tau*c
law[j,t] = lawtilde
tax[j,t] = taxtilde + tau*c
else:
eq[j,t] = 0
bond[j,t] = (1-b)*(V[j,t]+cash[j,t])
VL[j,t] = bond[j,t]
law[j,t] = b*(V[j,t]+cash[j,t])
tax[j,t] = 0.0
print('Equity \n')
print(np.round(eq,2))
print('')
print('Bond \n')
print(np.round(bond, 2))
print('')
print('Value of Levered Firm \n')
print(np.round(VL,2))
print('')
print('Value of Tax Shield \n')
print(np.round(tax,2))
print('')
print('Value of Bankruptcy Claim \n')
print(np.round(law,2))
Equity
[[ 31.02 72.8 140.32 252.19]
[ 0. 9.6 25.53 61.9 ]
[ 0. 0. 0. 0. ]
[ 0. 0. 0. 0. ]]
Bond
[[57.19 75.13 93.5 94.5 ]
[ 0. 41.72 61.26 94.5 ]
[ 0. 0. 23.38 34.88]
[ 0. 0. 0. 15.67]]
Value of Levered Firm
[[ 88.2 147.93 233.82 346.69]
[ 0. 51.32 86.8 156.4 ]
[ 0. 0. 23.38 34.88]
[ 0. 0. 0. 15.67]]
Value of Tax Shield
[[3.22 2.85 2.18 1.12]
[0. 1.76 1.58 1.12]
[0. 0. 0. 0. ]
[0. 0. 0. 0. ]]
Value of Bankruptcy Claim
[[15.02 10.2 0. 0. ]
[ 0. 20.21 18.86 0. ]
[ 0. 0. 23.38 34.88]
[ 0. 0. 0. 15.67]]
x = ['Value of Levered Firm','Equity','Bond','Tax Shield','Bankruptcy Claim']
y1 = [VL[0,0], eq[0,0],bond[0,0],tax[0,0],law[0,0]]
plt.barh(x,y1, label = 'Decomposition of Claims', color = 'b')
plt.xlabel('Claim on Cash Flows')
plt.ylabel('');
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MOlmABm2-1576122049639)(output_11_0.png)]
- We have the relationship that:
V L = E q u i t y + D e b t V^L = Equity + Debt VL=Equity+Debt - We also have:
\begin{equation}
V^L = V^U + V^{Tax Shield} - V^{Bankruptcy Claim}
\end{equation} - We check this…
print('Value of Equity and Debt = ', round(eq[0,0]+ bond[0,0],3))
print('Value of Unlevered firm + value of tax shield - value of bankruptcy claim =', round(V0+tax[0,0] - law[0,0],3))
error = VL[0,0] - (V0 + tax[0,0] - law[0,0])
Value of Equity and Debt = 88.204
Value of Unlevered firm + value of tax shield - value of bankruptcy claim = 88.204
Project:
- Rewrite the above program but for a general n; Run your program with
V0 = 100.0; T = 10.0; F= 0.0; q = 0.0; r= 0.06; sigma = 0.40; FF = 100; coupon = 5% nperiods = 100… THis implies that the bond issued is an annuity paying coupons continuously at a coupon of 5% of FF, ie 5 dollars a year, or 5*dt a period. Assume b = 0.50 and tau = 0.25
-
Then assume a bankruptcy cost of zero, b = 0, and a tax rate of zero. Do a sensitivity analysis with coupons on the x axis and equity and bond prices on the y axis as well as the value of the levered firm.Based on the figure you generate you should have confirmed the M&M theory.
-
Now repeat the analysis for a tax rate of 25% and a bankruptcy cost of 90%. Plot coupons from 0 to 16 and find the optimal capital structure.
-
Now put FF = 100 and F = 0 and increase nperiods. PLot a graph of the price of equity against nperiods. (T is fixed at 10)
-
V0 = 100.0;F= 0;cr = 0.05 ;q= 0.0;FF = 100;sigma = 0.30; tau = 0.25; b = 0.50. Increase time, T from amost 0 years to 200 years and for each maturity identify the equity and plot the graph. ( you should perhaps take time increments of 25 years.
-
Program up the Leland Model and compute the equity value and bond value and compare your answers with a long dated annuity computed on the lattice.
-
Now use the Leland model to show the sensitivity of bond prices to coupons for different asset volatilities. Interpret the results.
def Asset_Cash(T,n, sigma, r, q, V0):
dt = T/n
u = exp(sigma*sqrt(dt))
d = 1/u
disc = exp(-r*dt)
p = (exp((r-q)*dt) - d)/(u - d)
pbar = 1-p
delta = exp(q*dt)-1
c = cr*FF*dt
#V[j,t].....j downjumps in t periods j = 0....,t
V = np.zeros((n+1,n+1))
cash = np.zeros((n+1,n+1))
V[0,0] = V0
for t in range(1,n+1):
V[0,t] = u*V[0,t-1]
cash[0,t] = V[0,t]*delta
V[t,t] = d*V[t-1,t-1]
cash[t,t] = delta*V[t,t]
for t in range(2, n+1):
for j in range(1,t):
V[j, t] = V[j-1,t]*d**2
cash[j,t] = V[j,t]*delta
return V, cash
n = 3;T=3;sigma =0.40;r=0.06;q = 0.04; V0 = 100;F = 90; FF = 90; cr = 0.05;tau = 0.25;b = 0.50
V, cash = Asset_Cash(T,n, sigma, r, q, V0)
a = range(2, -1, -1)
for i in range(2, -1, -1):
print(i)
2
1
0
def get_full(T,n, sigma, r, q,F,FF, cr, tau, b):
dt = T/n
u = exp(sigma*sqrt(dt))
d = 1/u
disc = exp(-r*dt)
p = (exp((r-q)*dt) - d)/(u - d)
pbar = 1-p
delta = exp(q*dt)-1
c = cr*FF*dt
eq = np.zeros((n+1,n+1))
bond = np.zeros((n+1,n+1))
VL = np.zeros((n+1,n+1))
law = np.zeros((n+1,n+1))
tax = np.zeros((n+1,n+1))
V = np.zeros((n+1,n+1))
cash = np.zeros((n+1,n+1))
V[0,0] = V0
for t in range(1,n+1):
V[0,t] = u*V[0,t-1]
cash[0,t] = V[0,t]*delta
V[t,t] = d*V[t-1,t-1]
cash[t,t] = delta*V[t,t]
for t in range(2, n+1):
for j in range(1,t):
V[j, t] = V[j-1,t]*d**2
cash[j,t] = V[j,t]*delta
for j in range(0, n+1):
if V[j,n] + cash[j,n] > (1-tau)*c + F:
eq[j,n] = V[j,n] + cash[j,n] - ((1-tau)*c + F)
bond[j,n] = c + F
VL[j,n] = V[j,n] + cash[j,n] + tau*c
law[j,n] = 0
tax[j,n] = tau*c
else:
eq[j,n] = 0
bond[j,n] = (1-b)*(V[j,n]+cash[j,n])
VL[j,n] = bond[j,n]
law[j,n] = b*(V[j,n] + cash[j,n])
tax[j,n] = 0.0
for t in range(n-1, -1, -1):
for j in range(0, t+1):
eqtilde = disc*(p*eq[j, t+1] + pbar*eq[j+1, t+1])
btilde = disc*(p*bond[j, t+1] + pbar*bond[j+1,t+1])
VLtilde = disc*(p*VL[j, t+1] + pbar*VL[j+1, t+1])
lawtilde = disc*(p*law[j, t+1]+ pbar*law[j+1, t+1])
taxtilde = disc*(p*tax[j,t+1]+pbar*tax[j+1,t+1])
if (eqtilde +cash[j,t] > ( 1-tau)*c):
eq[j,t] = eqtilde + cash[j,t]- (1-tau)*c
bond[j,t] = btilde + c
VL[j,t] = VLtilde + cash[j,t] + tau*c
law[j,t] = lawtilde
tax[j,t] = taxtilde + tau*c
else:
eq[j,t] = 0
bond[j,t] = (1-b)*(V[j,t]+cash[j,t])
VL[j,t] = bond[j,t]
law[j,t] = b*(V[j,t]+cash[j,t])
tax[j,t] = 0.0
return eq, bond, VL, law, tax, V, cash
n = 4;T=3;sigma =0.40;r=0.06;q = 0.04; V0 = 100;F = 90; FF = 90; cr = 0.05;tau = 0.25;b = 0.50
eq1, bond1, VL1, law1, tax1, V1, cash1 = get_full(T,n, sigma, r, q,F,FF, cr, tau, b)
eq1
array([[ 29.84461603, 64.03179837, 116.50524182, 200.32280134,
319.38120217],
[ 0. , 10.58086353, 25.45950631, 54.7135715 ,
113.49230543],
[ 0. , 0. , 0.65842357, 4.00138867,
10.5142034 ],
[ 0. , 0. , 0. , 0. ,
0. ],
[ 0. , 0. , 0. , 0. ,
0. ]])
#1.
V0 = 100.0; T = 10.0; F= 0.0; q = 0.0; r= 0.06; sigma = 0.40; FF = 100; cr = 0.05; n = 100; b = 0.50; tau = 0.25
eq2, bond2, VL2, law2, tax2, V2, cash2 = get_full(T,n, sigma, r, q,F,FF, cr, tau, b)
error = eq2[0,0] + bond2[0,0]
print(error)
108.97960551279174
print(V0+tax2[0,0] - law2[0,0])
108.97960551279141
#2
V0 = 100.0; T = 10.0; F= 0.0; q = 0.0; r= 0.06; sigma = 0.40; FF = 100; cr = 0.03; n = 100; b = 0.00; tau = 0.00
eq3, bond3, VL3, law3, tax3, V3, cash3 = get_full(T,n, sigma, r, q,F,FF, cr, tau, b)
eq3[0,0]+bond3[0,0]
100.00000000000034
print(V0+tax3[0,0] - law3[0,0])
100.0
def sensitivity_cr(T,n, sigma, r, q,F,FF, tau, b, cr_end):
equity_v = np.zeros(cr_end+1)
bond_v = np.zeros(cr_end+1)
VL_v = np.zeros(cr_end+1)
eq = np.zeros((n+1,n+1))
bond = np.zeros((n+1,n+1))
VL = np.zeros((n+1,n+1))
law = np.zeros((n+1,n+1))
tax = np.zeros((n+1,n+1))
V = np.zeros((n+1,n+1))
cash = np.zeros((n+1,n+1))
V[0,0] = V0
cr_range = np.arange(0,cr_end+1)/100
dt = T/n
u = exp(sigma*sqrt(dt))
d = 1/u
disc = exp(-r*dt)
p = (exp((r-q)*dt) - d)/(u - d)
pbar = 1-p
delta = exp(q*dt)-1
for t in range(1,n+1):
V[0,t] = u*V[0,t-1]
cash[0,t] = V[0,t]*delta
V[t,t] = d*V[t-1,t-1]
cash[t,t] = delta*V[t,t]
for t in range(2, n+1):
for j in range(1,t):
V[j, t] = V[j-1,t]*d**2
cash[j,t] = V[j,t]*delta
for i, cr in enumerate(cr_range):
c = cr*FF*dt
for j in range(0, n+1):
if V[j,n] + cash[j,n] > (1-tau)*c + F:
eq[j,n] = V[j,n] + cash[j,n] - ((1-tau)*c + F)
bond[j,n] = c + F
VL[j,n] = V[j,n] + cash[j,n] + tau*c
law[j,n] = 0
tax[j,n] = tau*c
else:
eq[j,n] = 0
bond[j,n] = (1-b)*(V[j,n]+cash[j,n])
VL[j,n] = bond[j,n]
law[j,n] = b*(V[j,n] + cash[j,n])
tax[j,n] = 0.0
for t in range(n-1, -1, -1):
for j in range(0, t+1):
eqtilde = disc*(p*eq[j, t+1] + pbar*eq[j+1, t+1])
btilde = disc*(p*bond[j, t+1] + pbar*bond[j+1,t+1])
VLtilde = disc*(p*VL[j, t+1] + pbar*VL[j+1, t+1])
lawtilde = disc*(p*law[j, t+1]+ pbar*law[j+1, t+1])
taxtilde = disc*(p*tax[j,t+1]+pbar*tax[j+1,t+1])
if (eqtilde +cash[j,t] > ( 1-tau)*c):
eq[j,t] = eqtilde + cash[j,t]- (1-tau)*c
bond[j,t] = btilde + c
VL[j,t] = VLtilde + cash[j,t] + tau*c
law[j,t] = lawtilde
tax[j,t] = taxtilde + tau*c
else:
eq[j,t] = 0
bond[j,t] = (1-b)*(V[j,t]+cash[j,t])
VL[j,t] = bond[j,t]
law[j,t] = b*(V[j,t]+cash[j,t])
tax[j,t] = 0.0
equity_v[i] = eq[0,0]
bond_v[i] = bond[0,0]
VL_v[i] = VL[0,0]
return equity_v, bond_v, VL_v, cr_range
V0 = 100.0; T = 10.0; F= 0.0; q = 0.0; r= 0.06; sigma = 0.40; FF = 100; n = 100; b = 0.00; tau = 0.00; cr_end =101
equity_v1, bond_v1, VL_v1, cr_range1 = sensitivity_cr(T,n, sigma, r, q,F,FF, tau, b, cr_end)
plt.plot(cr_range1, equity_v1)
plt.plot(cr_range1, bond_v1)
plt.plot(cr_range1, VL_v1)
[<matplotlib.lines.Line2D at 0x9d3c50>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-efwPBGVd-1576122049640)(output_34_1.png)]
plt.plot(cr_range1, bond_v1)
[<matplotlib.lines.Line2D at 0xa3bff0>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cyNrCDzi-1576122049641)(output_35_1.png)]
plt.plot(cr_range1, VL_v1)
[<matplotlib.lines.Line2D at 0xa95070>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jBizHC96-1576122049641)(output_36_1.png)]
V0 = 100.0; T = 10.0; F= 0.0; q = 0.0; r= 0.06; sigma = 0.40; FF = 100; n = 100; b = 0.90; tau = 0.25; cr_end =16
equity_v2, bond_v2, VL_v2, cr_range2 = sensitivity_cr(T,n, sigma, r, q,F,FF, tau, b, cr_end)
equity_v2
array([100. , 94.30218104, 88.60793109, 82.92918989,
77.28468781, 71.69630223, 66.18757246, 60.78106458,
55.49960636, 50.36389702, 45.39425502, 40.60974999,
36.03006737, 31.66232184, 27.52431726, 23.65091782,
20.00105584])
plt.plot(cr_range2, equity_v2)
[<matplotlib.lines.Line2D at 0xad34b0>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cHXKA00i-1576122049641)(output_39_1.png)]
plt.plot(cr_range2, bond_v2)
[<matplotlib.lines.Line2D at 0xb123d0>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h0TKGFzf-1576122049642)(output_40_1.png)]
plt.plot(cr_range2, VL_v2)
[<matplotlib.lines.Line2D at 0xb524d0>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mw8ozD7s-1576122049642)(output_41_1.png)]
def sensitivity_n_equity1(T,n_range, sigma, r, q,F,FF, tau, b, cr):
n=100
nn=np.arange(1,n_range+1)
equity_v = np.zeros(n_range)
bond_v = np.zeros(n_range)
VL_v = np.zeros(n_range)
dt = 1
c = cr*FF*dt
u = exp(sigma*sqrt(dt))
d = 1/u
disc = exp(-r*dt)
p = (exp((r-q)*dt) - d)/(u - d)
pbar = 1-p
delta = exp(q*dt)-1
for i, n in enumerate(nn):
eq = np.zeros((n+1,n+1))
bond = np.zeros((n+1,n+1))
VL = np.zeros((n+1,n+1))
law = np.zeros((n+1,n+1))
tax = np.zeros((n+1,n+1))
V = np.zeros((n+1,n+1))
cash = np.zeros((n+1,n+1))
V[0,0] = V0
for t in range(1,n+1):
V[0,t] = u*V[0,t-1]
cash[0,t] = V[0,t]*delta
V[t,t] = d*V[t-1,t-1]
cash[t,t] = delta*V[t,t]
for t in range(2, n+1):
for j in range(1,t):
V[j, t] = V[j-1,t]*d**2
cash[j,t] = V[j,t]*delta
for j in range(0, n+1):
if V[j,n] + cash[j,n] > (1-tau)*c + F:
eq[j,n] = V[j,n] + cash[j,n] - ((1-tau)*c + F)
bond[j,n] = c + F
VL[j,n] = V[j,n] + cash[j,n] + tau*c
law[j,n] = 0
tax[j,n] = tau*c
else:
eq[j,n] = 0
bond[j,n] = (1-b)*(V[j,n]+cash[j,n])
VL[j,n] = bond[j,n]
law[j,n] = b*(V[j,n] + cash[j,n])
tax[j,n] = 0.0
for t in range(n-1, -1, -1):
for j in range(0, t+1):
eqtilde = disc*(p*eq[j, t+1] + pbar*eq[j+1, t+1])
btilde = disc*(p*bond[j, t+1] + pbar*bond[j+1,t+1])
VLtilde = disc*(p*VL[j, t+1] + pbar*VL[j+1, t+1])
lawtilde = disc*(p*law[j, t+1]+ pbar*law[j+1, t+1])
taxtilde = disc*(p*tax[j,t+1]+pbar*tax[j+1,t+1])
if (eqtilde +cash[j,t] > ( 1-tau)*c):
eq[j,t] = eqtilde + cash[j,t]- (1-tau)*c
bond[j,t] = btilde + c
VL[j,t] = VLtilde + cash[j,t] + tau*c
law[j,t] = lawtilde
tax[j,t] = taxtilde + tau*c
else:
eq[j,t] = 0
bond[j,t] = (1-b)*(V[j,t]+cash[j,t])
VL[j,t] = bond[j,t]
law[j,t] = b*(V[j,t]+cash[j,t])
tax[j,t] = 0.0
equity_v[i] = eq[0,0]
bond_v[i] = bond[0,0]
VL_v[i] = VL[0,0]
return equity_v, bond_v, VL_v, nn
V0 = 100.0; T = 10.0; F= 0.0; q = 0.0; r= 0.06; sigma = 0.40; FF = 100; b = 0.90; tau = 0.25; cr = 0.05; n_range = 200; n =100;
equity_v3, bond_v3, VL_v3, n_range3 = sensitivity_n_equity1(T,n_range, sigma, r, q,F,FF, tau, b, cr)
plt.plot(n_range3, equity_v3)
[<matplotlib.lines.Line2D at 0xe5eb290>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BNyN2SK2-1576122049643)(output_43_1.png)]
def sensitivity_n_equity(T,n_range, sigma, r, q,F,FF, tau, b, cr):
nn=np.arange(1,n_range+1)
equity_v = np.zeros(n_range)
bond_v = np.zeros(n_range)
VL_v = np.zeros(n_range)
for i, n in enumerate(nn):
eq = np.zeros((n+1,n+1))
bond = np.zeros((n+1,n+1))
VL = np.zeros((n+1,n+1))
law = np.zeros((n+1,n+1))
tax = np.zeros((n+1,n+1))
V = np.zeros((n+1,n+1))
cash = np.zeros((n+1,n+1))
dt = T/n
c = cr*FF*dt
V[0,0] = V0
u = exp(sigma*sqrt(dt))
d = 1/u
disc = exp(-r*dt)
p = (exp((r-q)*dt) - d)/(u - d)
pbar = 1-p
delta = exp(q*dt)-1
for t in range(1,n+1):
V[0,t] = u*V[0,t-1]
cash[0,t] = V[0,t]*delta
V[t,t] = d*V[t-1,t-1]
cash[t,t] = delta*V[t,t]
for t in range(2, n+1):
for j in range(1,t):
V[j, t] = V[j-1,t]*d**2
cash[j,t] = V[j,t]*delta
for j in range(0, n+1):
if V[j,n] + cash[j,n] > (1-tau)*c + F:
eq[j,n] = V[j,n] + cash[j,n] - ((1-tau)*c + F)
bond[j,n] = c + F
VL[j,n] = V[j,n] + cash[j,n] + tau*c
law[j,n] = 0
tax[j,n] = tau*c
else:
eq[j,n] = 0
bond[j,n] = (1-b)*(V[j,n]+cash[j,n])
VL[j,n] = bond[j,n]
law[j,n] = b*(V[j,n] + cash[j,n])
tax[j,n] = 0.0
for t in range(n-1, -1, -1):
for j in range(0, t+1):
eqtilde = disc*(p*eq[j, t+1] + pbar*eq[j+1, t+1])
btilde = disc*(p*bond[j, t+1] + pbar*bond[j+1,t+1])
VLtilde = disc*(p*VL[j, t+1] + pbar*VL[j+1, t+1])
lawtilde = disc*(p*law[j, t+1]+ pbar*law[j+1, t+1])
taxtilde = disc*(p*tax[j,t+1]+pbar*tax[j+1,t+1])
if (eqtilde +cash[j,t] > ( 1-tau)*c):
eq[j,t] = eqtilde + cash[j,t]- (1-tau)*c
bond[j,t] = btilde + c
VL[j,t] = VLtilde + cash[j,t] + tau*c
law[j,t] = lawtilde
tax[j,t] = taxtilde + tau*c
else:
eq[j,t] = 0
bond[j,t] = (1-b)*(V[j,t]+cash[j,t])
VL[j,t] = bond[j,t]
law[j,t] = b*(V[j,t]+cash[j,t])
tax[j,t] = 0.0
equity_v[i] = eq[0,0]
bond_v[i] = bond[0,0]
VL_v[i] = VL[0,0]
return equity_v, bond_v, VL_v, nn
V0 = 100.0; T = 10.0; F= 0.0; q = 0.0; r= 0.06; sigma = 0.40; FF = 100; b = 0.90; tau = 0.25; cr = 0.05; n_range = 200;
equity_v3, bond_v3, VL_v3, n_range3 = sensitivity_n_equity(T,n_range, sigma, r, q,F,FF, tau, b, cr)
plt.plot(n_range3, equity_v3)
[<matplotlib.lines.Line2D at 0xe54d250>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qptEksBd-1576122049644)(output_46_1.png)]
a = range(25,201,25)
25
50
75
100
125
150
175
200
def get_T_equity(T_end,n, sigma, r, q,F,FF, tau, b, cr):
T_n = int(T_end/25+1)
equity_v = np.zeros(T_n)
bond_v = np.zeros(T_n)
VL_v = np.zeros(T_n)
eq = np.zeros((n+1,n+1))
bond = np.zeros((n+1,n+1))
VL = np.zeros((n+1,n+1))
law = np.zeros((n+1,n+1))
tax = np.zeros((n+1,n+1))
V = np.zeros((n+1,n+1))
cash = np.zeros((n+1,n+1))
V[0,0] = V0
T_range = np.zeros(9)
T_range[0] = 0.001
T_values = range(25,T_end,25)
for i, value in enumerate(T_values):
T_range[i+1] = value
for i, T in enumerate(T_range):
dt = T/n
u = exp(sigma*sqrt(dt))
d = 1/u
disc = exp(-r*dt)
p = (exp((r-q)*dt) - d)/(u - d)
pbar = 1-p
delta = exp(q*dt)-1
c = cr*FF*dt
for t in range(1,n+1):
V[0,t] = u*V[0,t-1]
cash[0,t] = V[0,t]*delta
V[t,t] = d*V[t-1,t-1]
cash[t,t] = delta*V[t,t]
for t in range(2, n+1):
for j in range(1,t):
V[j, t] = V[j-1,t]*d**2
cash[j,t] = V[j,t]*delta
for j in range(0, n+1):
if V[j,n] + cash[j,n] > (1-tau)*c + F:
eq[j,n] = V[j,n] + cash[j,n] - ((1-tau)*c + F)
bond[j,n] = c + F
VL[j,n] = V[j,n] + cash[j,n] + tau*c
law[j,n] = 0
tax[j,n] = tau*c
else:
eq[j,n] = 0
bond[j,n] = (1-b)*(V[j,n]+cash[j,n])
VL[j,n] = bond[j,n]
law[j,n] = b*(V[j,n] + cash[j,n])
tax[j,n] = 0.0
for t in range(n-1, -1, -1):
for j in range(0, t+1):
eqtilde = disc*(p*eq[j, t+1] + pbar*eq[j+1, t+1])
btilde = disc*(p*bond[j, t+1] + pbar*bond[j+1,t+1])
VLtilde = disc*(p*VL[j, t+1] + pbar*VL[j+1, t+1])
lawtilde = disc*(p*law[j, t+1]+ pbar*law[j+1, t+1])
taxtilde = disc*(p*tax[j,t+1]+pbar*tax[j+1,t+1])
if (eqtilde +cash[j,t] > ( 1-tau)*c):
eq[j,t] = eqtilde + cash[j,t]- (1-tau)*c
bond[j,t] = btilde + c
VL[j,t] = VLtilde + cash[j,t] + tau*c
law[j,t] = lawtilde
tax[j,t] = taxtilde + tau*c
else:
eq[j,t] = 0
bond[j,t] = (1-b)*(V[j,t]+cash[j,t])
VL[j,t] = bond[j,t]
law[j,t] = b*(V[j,t]+cash[j,t])
tax[j,t] = 0.0
equity_v[i] = eq[0,0]
bond_v[i] = bond[0,0]
VL_v[i] = VL[0,0]
return equity_v, bond_v, VL_v, T_range
V0 = 100.0; T_end = 201; F= 0.0; q = 0.0; r= 0.06; sigma = 0.30; FF = 100; b = 0.50; tau = 0.25; cr = 0.05; n = 100
equity_v4, bond_v4, VL_v4, T_range4 = get_T_equity(T_end,n, sigma, r, q,F,FF, tau, b, cr)
plt.plot(T_range4, equity_v4)
[<matplotlib.lines.Line2D at 0x1344d3d0>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R16Zp1fF-1576122049645)(output_51_1.png)]