From 953d76e5279b405662c5713d0ec07f54dbce01cc Mon Sep 17 00:00:00 2001 From: Adrian Gao Date: Thu, 6 Jul 2023 11:59:12 +1000 Subject: [PATCH] Rearrange tests and Matlab files --- .../matlab/FRDSGenTestDataLoanPayoff.m | 2 +- .../matlab/ModMertonComputation.m | 11 +- .../matlab/ModMertonCreateLookup.m | 11 +- .../matlab/ModMertonSimulation.m | 2 +- .../matlab/FindFaceValueIndiv.m | 9 - .../modified_merton/matlab/LoanPayoff.m | 21 - .../modified_merton/matlab/MertonSolution.m | 31 -- .../matlab/ModMertonComputation.m | 255 ---------- .../matlab/ModMertonCreateLookup.m | 48 -- .../matlab/ModMertonEmpirical_unobsbookF.m | 172 ------- .../matlab/ModMertonSimulation.m | 471 ------------------ .../matlab/ModSingleCohortComputation.m | 137 ----- .../matlab/ModSingleCohortSolution.m | 26 - .../matlab/ModSingleMertonCreateLookup.m | 47 -- .../modified_merton/matlab/Readme.txt | 18 - .../modified_merton/matlab/fftsmooth.m | 23 - .../matlab/matrix2latex_Stefan.m | 267 ---------- .../modified_merton/matlab/mdef_output.mat | Bin 996 -> 0 bytes .../modified_merton/matlab/saveTightFigure.m | 25 - .../modified_merton/matlab/test_inputdata.csv | 5 - .../modified_merton/test_fftsmooth.py | 9 +- .../test_find_face_value_indiv.py | 9 +- .../modified_merton/test_loan_payoff.py | 11 +- .../test_matlab_python_conversion.py | 7 +- .../modified_merton/test_merton_solution.py | 13 +- .../test_mod_merton_computation.py | 9 +- .../test_mod_merton_create_lookup.py | 7 +- 27 files changed, 69 insertions(+), 1577 deletions(-) rename tests/measures/modified_merton/matlab/GenTestDataLoanPayoff.m => src/frds/measures/modified_merton/matlab/FRDSGenTestDataLoanPayoff.m (98%) delete mode 100644 tests/measures/modified_merton/matlab/FindFaceValueIndiv.m delete mode 100644 tests/measures/modified_merton/matlab/LoanPayoff.m delete mode 100644 tests/measures/modified_merton/matlab/MertonSolution.m delete mode 100644 tests/measures/modified_merton/matlab/ModMertonComputation.m delete mode 100644 tests/measures/modified_merton/matlab/ModMertonCreateLookup.m delete mode 100644 tests/measures/modified_merton/matlab/ModMertonEmpirical_unobsbookF.m delete mode 100644 tests/measures/modified_merton/matlab/ModMertonSimulation.m delete mode 100644 tests/measures/modified_merton/matlab/ModSingleCohortComputation.m delete mode 100644 tests/measures/modified_merton/matlab/ModSingleCohortSolution.m delete mode 100644 tests/measures/modified_merton/matlab/ModSingleMertonCreateLookup.m delete mode 100644 tests/measures/modified_merton/matlab/Readme.txt delete mode 100644 tests/measures/modified_merton/matlab/fftsmooth.m delete mode 100644 tests/measures/modified_merton/matlab/matrix2latex_Stefan.m delete mode 100644 tests/measures/modified_merton/matlab/mdef_output.mat delete mode 100644 tests/measures/modified_merton/matlab/saveTightFigure.m delete mode 100644 tests/measures/modified_merton/matlab/test_inputdata.csv diff --git a/tests/measures/modified_merton/matlab/GenTestDataLoanPayoff.m b/src/frds/measures/modified_merton/matlab/FRDSGenTestDataLoanPayoff.m similarity index 98% rename from tests/measures/modified_merton/matlab/GenTestDataLoanPayoff.m rename to src/frds/measures/modified_merton/matlab/FRDSGenTestDataLoanPayoff.m index 4031f2b1..b9e50af4 100644 --- a/tests/measures/modified_merton/matlab/GenTestDataLoanPayoff.m +++ b/src/frds/measures/modified_merton/matlab/FRDSGenTestDataLoanPayoff.m @@ -1,4 +1,4 @@ -function [F, f1j, ival, rho, sig, T] = GenTestDataLoanPayoff() +function [F, f1j, ival, rho, sig, T] = FRDSGenTestDataLoanPayoff() fs = [-0.8:0.05:0.8]'/(0.2*sqrt(0.5)*sqrt(10)); %range for dW_0 shocks N = 10; %number of loan cohorts diff --git a/src/frds/measures/modified_merton/matlab/ModMertonComputation.m b/src/frds/measures/modified_merton/matlab/ModMertonComputation.m index 38058ffa..feb056c5 100644 --- a/src/frds/measures/modified_merton/matlab/ModMertonComputation.m +++ b/src/frds/measures/modified_merton/matlab/ModMertonComputation.m @@ -26,7 +26,13 @@ %if not provided as input, then generate here if nargin < 5 rng(1,'twister') - w = normrnd(0,1,[Nsim2, 3*N]); + % w = normrnd(0,1,[Nsim2, 3*N]); + % Mingze's note + % This is to produce the same random normal values as numpy + % For unknown reasons, same seed doesn't guarantee same random NORMAL values + % in Matlab and Numpy given the same MT19937 rng. + % This line below is a workaround. + w = norminv(rand(Nsim2, 3*N),0,1); end ival = log(bookF)-log(ltv); %initial log asset value of borrower at origination @@ -173,7 +179,8 @@ for j = 1:N FHr = reshape(FHr1(:,j,:)+FHr2(:,j,:),Nsim2*Nsim1,1); Lr = reshape(Lr1(:,j,:)+Lr2(:,j,:),Nsim2*Nsim1,1); - [sortF, ind] = sort(FHr); + % Mingze's note: line below is changed to make sure we rely on a fixed precision + [sortF, ind] = sort(round(FHr, 9)); sortL = Lr(ind); win = (Nsim2*Nsim1)/20; %/10 seems to give about sufficient smoothness LHs = fftsmooth(sortL,win); diff --git a/src/frds/measures/modified_merton/matlab/ModMertonCreateLookup.m b/src/frds/measures/modified_merton/matlab/ModMertonCreateLookup.m index 74b04bd0..f110005f 100644 --- a/src/frds/measures/modified_merton/matlab/ModMertonCreateLookup.m +++ b/src/frds/measures/modified_merton/matlab/ModMertonCreateLookup.m @@ -4,8 +4,9 @@ rng(1,'twister') -w = normrnd(0,1,[Nsim2, 3*N]); - +% w = normrnd(0,1,[Nsim2, 3*N]); +w = norminv(rand(Nsim2, 3*N),0,1); + J = size(xsig,2); K = size(xr,3); Q = size(xF,4); @@ -25,9 +26,9 @@ for k = 1:K for q = 1:Q - j - k - q + % j + % k + % q param = [xr(1,j,k,q); T; xF(1,j,k,q); H; bookD*exp(xr(1,j,k,q)*H); rho; ltv; xsig(1,j,k,q); d; y]; %get face value of debt from current book value of debt diff --git a/src/frds/measures/modified_merton/matlab/ModMertonSimulation.m b/src/frds/measures/modified_merton/matlab/ModMertonSimulation.m index f966ed51..c7e52569 100644 --- a/src/frds/measures/modified_merton/matlab/ModMertonSimulation.m +++ b/src/frds/measures/modified_merton/matlab/ModMertonSimulation.m @@ -6,7 +6,7 @@ clc; %output directory -direc = ['/Users/snagel/Dropbox/hdrive/Research/projects/BankCreditRisk/output/']; +direc = ['./']; comp = 1; %1 to re-calculate, 0 to use already saved file; diff --git a/tests/measures/modified_merton/matlab/FindFaceValueIndiv.m b/tests/measures/modified_merton/matlab/FindFaceValueIndiv.m deleted file mode 100644 index 50bfde8e..00000000 --- a/tests/measures/modified_merton/matlab/FindFaceValueIndiv.m +++ /dev/null @@ -1,9 +0,0 @@ -function [err, newmu, L] = FindFaceValueIndiv(mu, F, ival, sig, T, r, d) - - [C, P] = blsprice(exp(ival), F, r, T, sig, d); - - L = F*exp(-r*T)-P; %to do with call we would also need to subtract PV(depreciation) - newmu = (1/T)*log(F/L); - - err = mu-newmu; - \ No newline at end of file diff --git a/tests/measures/modified_merton/matlab/LoanPayoff.m b/tests/measures/modified_merton/matlab/LoanPayoff.m deleted file mode 100644 index 10795178..00000000 --- a/tests/measures/modified_merton/matlab/LoanPayoff.m +++ /dev/null @@ -1,21 +0,0 @@ - - -function [L] = LoanPayoff(F, f, ival, rho, sig, T) - - %F = loan face value (either a scalar or a matrix the same size as f) - %f = log asset value factor realizations - %ival = initial log asset value - %rho = correlation of asset values - %sig = volatility of log asset values - %T = loan maturity - %r = log risk free rate - - EA = exp(f+ival+0.5*(1-rho)*T*sig^2); %expected asset value conditional on common factor - s = sig*sqrt(T)*sqrt(1-rho); - a = (log(F)-f-ival)/s; - L = EA.*(1-normcdf(s-a)) + normcdf(-a).*F; %loan portfolio payoff at maturity - - - - - \ No newline at end of file diff --git a/tests/measures/modified_merton/matlab/MertonSolution.m b/tests/measures/modified_merton/matlab/MertonSolution.m deleted file mode 100644 index b0d83493..00000000 --- a/tests/measures/modified_merton/matlab/MertonSolution.m +++ /dev/null @@ -1,31 +0,0 @@ - - -function [err] = MertonSolution(b, E, D, r, d, T, sigE) - -A = b(1); -sig = b(2); -esig = 0; -if sig < 0 - sig = 0; - esig = 9999999; -end -eA = 0; -if A < 0 - A = 0; - eA = 9999999; -end - -[C, P] = blsprice(A , D, r, T, sig, d); - -%add PV(dividends) to get cum dividend value -PVd = A*(1-exp(-d*T)); -C = C + PVd; - -d1 = (log(A)-log(D)+(r-d+sig^2/2)*T)/(sig*sqrt(T)); -v = ( exp(-d*T)*normcdf(d1) + (1-exp(-d*T)) )*(A/E)*sig; - -%v = ((A)/(C))*sig; %A includes PV(div), but B-S derivative prices don't -%Merton asset volatility too high - -err = [E - C; sigE-v] + esig*b(2)^2 + eA*b(1)^2; - diff --git a/tests/measures/modified_merton/matlab/ModMertonComputation.m b/tests/measures/modified_merton/matlab/ModMertonComputation.m deleted file mode 100644 index feb056c5..00000000 --- a/tests/measures/modified_merton/matlab/ModMertonComputation.m +++ /dev/null @@ -1,255 +0,0 @@ - -function [Lt, Bt, Et, LH, BH, EH, sigEt, mFt, def, mdef, face, FH, Gt, mu, F, sigLt] = ModMertonComputation(fs, param, N, Nsim2, w) - - - r = param(1); %log risk free rate - T = param(2); %original maturity of bank loans - bookF = param(3); %cash amount of loan issued = book value for a coupon-bearing loan issued at par - H = param(4); %bank debt maturity - D = param(5); %face value of bank debt - rho = param(6); %borrower asset value correlation - ltv = param(7); %initial LTV - sig = param(8); %borrower asset value volatility - d = param(9); %depreciation rate of borrower assets - y = param(10); %bank payout rate - - %optional: calculate value of govt guarantee, with prob g, govt absorbs - %Loss given default (bank and equity values not adjusted for presence of - %govt guarantee) - if size(param,1) > 10 - g = param(11); - else - g = 0; - end - - %optional: provide simulated factor shocks (for faster repeated computations) - %if not provided as input, then generate here - if nargin < 5 - rng(1,'twister') - % w = normrnd(0,1,[Nsim2, 3*N]); - % Mingze's note - % This is to produce the same random normal values as numpy - % For unknown reasons, same seed doesn't guarantee same random NORMAL values - % in Matlab and Numpy given the same MT19937 rng. - % This line below is a workaround. - w = norminv(rand(Nsim2, 3*N),0,1); - end - - ival = log(bookF)-log(ltv); %initial log asset value of borrower at origination - sigf = sqrt(rho)*sig; - HN = H*(N/T); %maturity in N time; - szfs = size(fs,1); - fs = [fs; fs; fs]; %use second and third block for numerical derivative - Nsim1 = size(fs,1); - - %remaining maturity of first loans at t - rmat(1,:,1) = [0:1:N-1]; - rmat = repmat(rmat, [Nsim2,1, Nsim1]); - ind1 = (rmat >= HN); - ind2 = (rmat < HN); - - %fractional accumulated loan life time at t+H - aHmat(1,:,1) = [HN:-1:0 N-1:-1:HN+1]/N; - aHmat = repmat(aHmat, [Nsim2,1, Nsim1]); - - %fractional accumulated loan life time at t - atmat(1,:,1) = (N-[0:1:N-1])/N; - atmat = repmat(atmat, [Nsim2,1, Nsim1]); - - %Euler discretization for log value has a jensen's term - %which depends on total, not just factor volatility, - %since f here is average log asset value of borrowers, the idiosyncratic - %shock averaged out, but to have expected return (gross of depreciation) - %for each individual borrower equal to exp(r), the drift needs to adjust - %for total volatility. - %Further below: - %To get average level of asset value, we take E[exp(f + 0.5*idiovar)] - %because only volatility from factors generates variation in our - %simulations (which then raises E[exp(.)] by averaging convex function, - %this 0.5*idiovar part combined with the total volatility drift - %adjustment here then only leaves the factor volatility drift adjustment - f = [zeros(Nsim2,1) cumsum( (r-d-0.5*sig^2)*(T/N) + sigf*sqrt(T/N)*w , 2)]; - - %fw is what we need to remove from f (until t) to let LEVEL of aggregate - %borrower asset value grow at expected path exp(r-d) - %(after we also add 0.5*idiovar further below) - fw = [zeros(Nsim2,1) cumsum( -0.5*rho*sig^2*(T/N) + sigf*sqrt(T/N)*w , 2)]; - - %factor realizations at relevant points for staggered loan cohorts (#sim x cohort) - % t = Time we do valuation - %first loan of first cohort starts at 0 and matures at t = N, i.e. accumulated factor shocks - %are those in 1, 2, ..., N. First loan of N-th cohort starts at N-1 and - %matures at 2*N-1 - %second loan of first cohort starts at N and accumulated factor shocks are those - %in N+1, ..., 2*N. Second loan of N-th cohort starts at 2*N-1 and matures - %at 3*N-1 - %Note that first element of f is zero, so f(1) is time 0 and f(N+1) is time t - xf1 = f(:,N+1) - f(:,1); %from start of first loan to maturity of first loan, first cohort only - f0w = repmat(fw(:,N+1),1,N) - fw(:,1:N); %factor shocks from start of first loan shocks until t - f1 = f(:,N+1:2*N) - f0w - f(:,1:N); %from start of first loan to maturity of first loan w/ shocks until t removed - f2 = f(:,2*N+1:3*N) - f(:,N+1:2*N); %from start of second loan to maturity of second loan - - %add fs shocks after loan origination - %dimension of f1tj, f2tj becomes (#sim x cohort x #fs-values) - %do not apply maturity weighting to df increments for numerical - %derivatives used for volatility calculation - fsa(1,1,:) = fs*sigf*sqrt(T); - dstep = 10; %1/dstep of SD step to evaluate numerical derivative - df = sigf/dstep; - fsa = repmat(fsa, [Nsim2 N 1]).*atmat ... - + df*cat(3,zeros(Nsim2,N,szfs),ones(Nsim2,N,szfs),-ones(Nsim2,N,szfs)); - f1j = repmat(f1,[1,1,Nsim1]) + fsa; - f2j = repmat(f2,[1,1,Nsim1]); %fs shock not here because they occurred before origination of second loan - - %solve for promised yield on loan (a fixed point): - %do not remove factor shocks until t in this calculation - options = optimset('TolFun',1.0e-12,'MaxIter',100000, 'TolX',1.0e-12, ... - 'MaxFunEvals',100000, 'Display', 'off'); - initmu = r+0.01; - [muout,fval,exitflag,output] = fsolve(@(mu) FindFaceValueIndiv(mu, bookF*exp(mu*T), ival, sig, T, r, d), initmu, options); - if exitflag < 1 - disp('Face value not found') - end - mu = muout; %output is promised total yield - F = bookF*exp(mu*T); %loan face value; - - %payoffs at loan maturities - %T is the correct "maturity" below because idiosyncratic risk accumulated - %since issuance of loan - %loan portfolio payoff at first maturity date (#sim x cohort x fs shocks) - %newmu coming out here is not exactly the same as mu because f1j doesn't - %have shocks until time t - L1 = LoanPayoff(F, f1j, ival, rho, sig, T); - face1 = ones(size(f1j))*F; - - %for second generation of loans use ival2 which accounts for collateral - %adjustment at loan roll over: same LTV as first generation loans, hence - %same risk, same promised yield - %here newmu comes out identical to mu initially calculated above - ival2 = log(L1/ltv); - F2 = L1*exp(mu*T); - L2 = LoanPayoff(F2, f2j, ival2, rho, sig, T); - face2 = F2; - - face2(ind1) = 0; - face1(ind2) = 0; - - %factor realizations at t and t+H - %first by loan cohort, then average across cohorts - %relevant number is the asset value of loan portfolio in whole portfolio, - %hence the Jensen's inequality term for the idio variance part - - ft = repmat( repmat(f(:,N+1),1,N) - f0w - f(:,1:N), [1,1,Nsim1]) + fsa + ival; %from start of first loan to time t CHECK: no need for ival here because it's constant, makes no diff in conditioning below - %including shock fs since origination of loan - fH1 = repmat(f(:,N+1+HN),1,N) - f0w - f(:,1:N); %from start of first loan to to time t+H - fH2 = repmat(f(:,N+1+HN),1,N) - f(:,N+1:2*N); %from start of second loan to time t+H - fH1j = repmat(fH1,[1,1,Nsim1]) + fsa + ival; - fH2j = repmat(fH2,[1,1,Nsim1]) + ival2; %fs shock here goes into ival2 - - FH1j = exp(fH1j).* exp(0.5*(1-rho)*(T*aHmat)*sig^2); %idio part is uncertain over whole maturity (past and future) when conditioning on common factor - FH2j = exp(fH2j).* exp(0.5*(1-rho)*(T*aHmat)*sig^2); %but only accumulated dispersion until valuation point matters for Jensen's adj. - - Ft = squeeze(mean(exp(ft).* exp(0.5*(1-rho)*(T*atmat)*sig^2),2)); %average across cohorts - - %get conditional payoff distribution based on t+H information - %i.e., conditional on factor path since inital orgination - %including any collateral amounts added or subtracted in the course of - %roll over into the second generation of loans - %use a (fast) smoother to compute this conditional expectation through - %local averaging - %Conditional exp of loan payoff for rolled over loans is a function of - %both - % (a) log factor shocks since roll over plus log collateral replenishment - % (b) the face value of the rolled over loan (which depends on factor - % realizations up to rollover date) - %However, (b) scales both loan value and face value, so by descaling we - %can reduce conditional expectation to one that depends only on (a) - sc = L1/bookF; - sc(ind1) = 1; - FHr1 = FH1j; - FHr1(ind2) = 0; - FHr2 = FH2j./sc; - FHr2(ind1) = 0; - Lr1 = L1; - Lr1(ind2) = 0; - Lr2 = L2./sc; - Lr2(ind1) = 0; - - LHj = zeros(Nsim2,N,Nsim1); - for j = 1:N - FHr = reshape(FHr1(:,j,:)+FHr2(:,j,:),Nsim2*Nsim1,1); - Lr = reshape(Lr1(:,j,:)+Lr2(:,j,:),Nsim2*Nsim1,1); - % Mingze's note: line below is changed to make sure we rely on a fixed precision - [sortF, ind] = sort(round(FHr, 9)); - sortL = Lr(ind); - win = (Nsim2*Nsim1)/20; %/10 seems to give about sufficient smoothness - LHs = fftsmooth(sortL,win); - newInd = zeros(size(ind)); - newInd(ind) = 1:length(FHr); - LHsn = reshape(LHs(newInd),Nsim2,1,Nsim1).*sc(:,j,:); - LHj(:,j,:) = LHsn; - - end - - - %integrate over cohorts and discount to get portfolio payoff distribution at t+H - LH1j = LHj; - LH1j(ind2) = 0; - LH2j = LHj; - LH2j(ind1) = 0; - - LH = squeeze(mean( LH1j.*exp(-r*(rmat-HN)*(T/N)) + LH2j.*exp(-r*(rmat-HN+N)*(T/N)) , 2)); - FH = squeeze(mean( FHr1 + FHr2 , 2 )); - - face = squeeze(mean(face1.*exp(-r*(rmat-HN)*(T/N)) + face2.*exp(-r*(rmat-HN+N)*(T/N)), 2)); - - BH = min(D,LH*exp(-y*H)); - EHex = LH*exp(-y*H) - BH; - EH = LH-BH; - GH = g*max(D-LH*exp(-y*H),0); - - - %now integrate conditional on f_t over factor distribution at t+H - %simply taking mean here works because no factor shocks until t - %so factor paths are all the same until t - Lt = mean(LH)'*exp(-r*H); - Bt = mean(BH)'*exp(-r*H); - Et = mean(EH)'*exp(-r*H); - Gt = mean(GH)'*exp(-r*H); - mFt = mean(Ft)'; - - %RN default indicator - def = ones(size(EHex)); - ldef = EHex > 0; - def(ldef) = 0; - - mdef = mean(def)'; - - - %take numerical first derivative to get instantaneous equity vol - %consider SD/dstep move of f - %this is ok even though future replenishment/removal of f as collateral - %here just SD/dstep move in only source of stochastic shocks - %of interest here is how this feeds through to Et (including through dampening collateral replenishment/removal) - %(if one looked at an SD move in the dampened asset value, it would have a correspondingly - % bigger derivative) - - sigEt = (dstep/2)*(log(Et(szfs+1:2*szfs,1)) - log(Et(2*szfs+1:3*szfs,1))); %since move is 2 times SD/10 - sigLt = (dstep/2)*(log(Lt(szfs+1:2*szfs,1)) - log(Lt(2*szfs+1:3*szfs,1))); %since move is 2 times SD/10 - - - Lt = Lt(1:szfs,1); - Bt = Bt(1:szfs,1); - Et = Et(1:szfs,1); - LH = LH(:,1:szfs); - BH = BH(:,1:szfs); - EH = EH(:,1:szfs); - FH = FH(:,1:szfs); - mFt = mFt(1:szfs,1); - def = def(:,1:szfs); - mdef = mdef(1:szfs,1); - face = face(:,1:szfs); - Gt = Gt(1:szfs,1); - - - diff --git a/tests/measures/modified_merton/matlab/ModMertonCreateLookup.m b/tests/measures/modified_merton/matlab/ModMertonCreateLookup.m deleted file mode 100644 index f110005f..00000000 --- a/tests/measures/modified_merton/matlab/ModMertonCreateLookup.m +++ /dev/null @@ -1,48 +0,0 @@ - - -function [xLt, xBt, xEt, xFt, xmdef, xsigEt] = ModMertonCreateLookup(d,y,T,H,bookD,rho,ltv,xfs,xr,xF,xsig,N,Nsim2) - - -rng(1,'twister') -% w = normrnd(0,1,[Nsim2, 3*N]); -w = norminv(rand(Nsim2, 3*N),0,1); - -J = size(xsig,2); -K = size(xr,3); -Q = size(xF,4); -G = size(xfs,1); - -fs = xfs(:,1,1,1); - -xLt = zeros(G,J,K,Q); -xBt = zeros(G,J,K,Q); -xEt = zeros(G,J,K,Q); -xFt = zeros(G,J,K,Q); -xmdef = zeros(G,J,K,Q); -xsigEt = zeros(G,J,K,Q); - -for j = 1:J - - for k = 1:K - - for q = 1:Q - % j - % k - % q - - param = [xr(1,j,k,q); T; xF(1,j,k,q); H; bookD*exp(xr(1,j,k,q)*H); rho; ltv; xsig(1,j,k,q); d; y]; %get face value of debt from current book value of debt - - [Lt, Bt, Et, ~, ~, ~, sigEt, mFt, ~, mdef] = ModMertonComputation(fs, param, N, Nsim2, w); - - xLt(:,j,k,q) = Lt; - xBt(:,j,k,q) = Bt; - xEt(:,j,k,q) = Et; - xFt(:,j,k,q) = mFt; - xmdef(:,j,k,q) = mdef; - xsigEt(:,j,k,q) = sigEt; - - end - end -end - - diff --git a/tests/measures/modified_merton/matlab/ModMertonEmpirical_unobsbookF.m b/tests/measures/modified_merton/matlab/ModMertonEmpirical_unobsbookF.m deleted file mode 100644 index 138296af..00000000 --- a/tests/measures/modified_merton/matlab/ModMertonEmpirical_unobsbookF.m +++ /dev/null @@ -1,172 +0,0 @@ - -% Output: computes modified Merton model risk-neutral default probabilities (mdef) -% Input: -% - file with empirical Equity values and (instant.) equity S.D. for set of banks: -% variables sE and E -% - file with debt and equity values, equity vol, ... as function of borrower -% asset vol, borrower asset value, ... computed in ModMertonComputation.m - - -clear all; -close all; -clc; - -%working directory here. -direc = ['/Users/amiyatos/Dropbox/BankCreditRisk/PublicCode/']; - -compute =0; %set to 1 to run ModMertonComputation.m, otherwise it uses saved file (ValueSurface.mat) - %need to run the code with compute=1 first to get the valuesurface. -N = 10; %number of loan cohorts -Nsim2 = 5000; %number of simulated factor realization paths - -d = 0.005; %depreciation rate of borrower assets -y = 0.002; %bank payout rate as a percent (p.a) of asset value -T = 10; %loan maturity -H = 5; %bank debt maturity -bookD = 1; %current book value of bank debt (normalized to 1, normalize all other balance sheet variables accordingly) -rho = 0.5; %share of factor variance in total borrower asset variance: we can't identify and need to assume a value (with robustness checks) -ltv = 0.66; %initial LTV - -% Let F = face value of (zero-coupon loans) -% D = face value of bank's (zero-coupon) debt -% -% bookF = book value of assets -% = in empirical data, approx, under ass. that issued at par w/ coupon, this is the face value of the loan -% (w/o loss provisions subtracted), i.e., the initial amount transferred to the borrower -% with zero-coupon loans in our model we should then set (done in ModMertonComputation.m) -% F = bookF * exp(mu*T) -% since banks do not have zero coupon loans in practice, their book -% value of loans does not grow with maturity -% but in our case, the face value needs to incorporate the accumulated -% and compounded interest payments: hence bookF * exp(mu*T) -% After scaling BS-variables by book value of bank debt, we get -% bookF = book value asset/book value debt -% F = (book value asset/book value debt) * exp(mu*T) -% with an initial loan to value ratio of ltv, we then start with inital -% collateral of -% F * exp(-mu * T)/ltv = bookF/ltv -% -% book value of debt = D * exp(-r * H) -% after scaling BS-variables by book value of debt, we compute -% D = exp(r*H) (implemented in ModMertonCreateLookup.m) -% - - -%Load empirical data -%File qtr_bankdd.csv in the example below contains the dataset with permco, -%year, month, market value of equity (E) scaled by book debt, equity -%volatility (sE), risk free rate (r). Please change your input variables -%accordingly. -%test_inputdata is an input test dataset containing E, sE and r. Alongwith -%permco, year , month identifier. - -filename=[direc,'test_inputdata.csv']; -qtr_bankdd=csvread(filename,1,0); - -E=qtr_bankdd(:,1); -permco=qtr_bankdd(:,2); -year=qtr_bankdd(:,3); -month=qtr_bankdd(:,4); -r=qtr_bankdd(:,5); -sE=qtr_bankdd(:,6); - -% run ModMertonComputation.m -% the grid surface should be wide enough to cover empirically relevant -% range. -[xfs,xsig,xr,xF] = ndgrid( -8:0.05:8, 0.15:0.05:0.25, 0:0.005:0.1, 0.5:0.05:2.5); - - -if compute == 1 - - [xLt, xBt, xEt, xFt, xmdef, xsigEt] = ModMertonCreateLookup(d,y,T,H,bookD,rho,ltv,xfs,xr,xF,xsig,N,Nsim2); - - param = [T; H; bookD; rho; d; y; ltv]; - - save([direc,'ValueSurface'], 'xLt', 'xBt', 'xEt', 'xFt', 'xmdef', 'xsigEt', 'xfs', 'xsig', 'xr', 'xF', ... - 'N', 'Nsim2', 'param'); - -end - -load([direc,'ValueSurface']) - -dataN = size(E,1); -rs = size(xr,3); %number of interest rate obs -minr = xr(1,1,1,1); -maxr = xr(1,1,rs,1); -vol=ones(dataN,1)*0.2; %feed asset volatility value here. - -for a = 1:rs - - sigEt = squeeze(xsigEt(:,:,a,:)); - Et = squeeze(xEt(:,:,a,:)); - Bt = squeeze(xBt(:,:,a,:)); - mdef = squeeze(xmdef(:,:,a,:)); - Lt = squeeze(xLt(:,:,a,:)); - sig = squeeze(xsig(:,:,a,:)); - fs = squeeze(xfs(:,:,a,:)); - bookF = squeeze(xF(:,:,a,:)); - - %eliminate NaNs and Inf in equity volatility (with linear interpol this - %does not affect other observations) - ind = isnan(sigEt); - sigEt(ind) = 99; - ind = isinf(sigEt); - sigEt(ind) = 99; - - %perform inversion by 3D-interpolating linearly as a function of Et, sigEt, F - %for a given interest rate - %use "macro" (Matlab structures can't seem to handle - %ScatteredInterpolant Elements) - eval(sprintf('yfs%d = scatteredInterpolant(Et(:),sigEt(:),sig(:),fs(:))', a)); - eval(sprintf('yLt%d = scatteredInterpolant(Et(:),sigEt(:),sig(:),Lt(:))', a)); - eval(sprintf('yBt%d = scatteredInterpolant(Et(:),sigEt(:),sig(:),Bt(:))', a)); - eval(sprintf('ybookF%d = scatteredInterpolant(Et(:),sigEt(:),sig(:),bookF(:))', a)); - eval(sprintf('ymdef%d = scatteredInterpolant(Et(:),sigEt(:),sig(:),mdef(:))', a)); - -end - - -%extract interpolated values corresponding to empirical data points -%for each interest rate on the grid -Lr = zeros(dataN,rs); -Br = zeros(dataN,rs); -mdefr = zeros(dataN,rs); -sigr = zeros(dataN,rs); -bookFr = zeros(dataN,rs); -fsr = zeros(dataN,rs); -for a = 1:rs - eval(sprintf('Lr(:,%d) = yLt%d(E,sE,vol);', a, a)); - eval(sprintf('Br(:,%d) = yBt%d(E,sE,vol);', a, a)); - eval(sprintf('mdefr(:,%d) = ymdef%d(E,sE,vol);', a, a)); - eval(sprintf('bookFr(:,%d) = ybookF%d(E,sE,vol);', a, a)); - eval(sprintf('fsr(:,%d) = yfs%d(E,sE,vol);', a, a)); -end - -%find closest interest rates on grid -rstep = (maxr-minr)/(rs-1); -rmat = repmat(r,1,rs); -rgrid = repmat(minr:rstep:maxr,dataN,1); -dr = (rgrid-rmat)/rstep; -Wl = 1+dr; -Wu = 1-dr; -ind1 = (dr <= -1); -ind2 = (dr >= 1); -indl = (dr < 0); -indu = (dr > 0); -W = zeros(size(rmat)); -W(indl) = Wl(indl); -W(indu) = Wu(indu); -W(ind1) = 0; -W(ind2) = 0; - -L = sum(Lr.*W,2); -B = sum(Br.*W,2); -mdef = sum(mdefr.*W,2); -bookF = sum(bookFr.*W,2); -fs = sum(fsr.*W,2); - - -%write relevant output to mdef file. -save([direc,'mdef_output'], 'L', 'B', 'mdef', 'fs', 'E', 'bookF', 'r', 'permco', 'year', 'month', 'sE','vol'); - - \ No newline at end of file diff --git a/tests/measures/modified_merton/matlab/ModMertonSimulation.m b/tests/measures/modified_merton/matlab/ModMertonSimulation.m deleted file mode 100644 index 167bb8d2..00000000 --- a/tests/measures/modified_merton/matlab/ModMertonSimulation.m +++ /dev/null @@ -1,471 +0,0 @@ - - - -clear all; -close all; -clc; - -%output directory -direc = ['.']; - -comp = 1; %1 to re-calculate, 0 to use already saved file; - -fs = [-0.8:0.05:0.8]'/(0.2*sqrt(0.5)*sqrt(10)); %range for dW_0 shocks - -N = 10; %number of loan cohorts -Nsim2 = 1000; %number of simulated factor realization paths (10,000 works well) - -r = 0.01; %risk-free rate; -d = 0.005; %depreciation rate of borrower assets -y = 0.002; %bank payout rate as a percent of face value of loan portfolio -T = 10; %loan maturity -bookD = 0.63; -H = 5; %bank debt maturity -D = bookD*exp(r*H)*mean(exp(r*([1:T])')); %face value of bank debt: as if bookD issued at start of each cohort, so it grows just like RN asset value -rho = 0.5; -sig = 0.2; -ltv = 0.66; %intial ltv -g = 0.5; %prob of govt bailout (only used for bailout valuation analysis) - - -for j = 3; %1:10 % j = 3 for the plots in the main part of the paper - - j - bookF = 0.6+j*0.02; %initial loan amount = book value of assets (w/ coupon-bearing loans the initial amount would be book value) - rep = int2str(j); - - if comp == 1 - - - param = [r; T; bookF; H; D; rho; ltv; sig; d; y; g]; - - [Lt, Bt, Et, LH, BH, EH, sigEt, mFt, def, mdef, face, FH, Gt, mu, F, sigLt] = ModMertonComputation(fs, param, N, Nsim2); - -% save([direc,'Simoutput'], 'Lt', 'Bt', 'Et', 'LH', 'BH', 'EH', 'sigEt', ... -% 'mFt', 'def', 'mdef', 'face', 'FH', 'Gt', 'mu', 'F',... -% 'Nsim2', 'N', 'param'); - - - - else - - load([direc,'Simoutput']) - - r = param(1); - T = param(2); - F = param(3); - H = param(4); - D = param(5); - rho = param(6); - ltv = param(7); - sig = param(8); - d = param(9); - y = param(10); - g = param(11); - - end - - [M,j0] = min(abs(mFt-exp(r*T/2))); - %j0 = find(abs(mFt-1) < 0.01); - mface = max(face(:,j0))*exp(-r*((T-H)/2)); %approx. - - - options = optimset('TolFun',1.0e-16,'MaxIter',100000, 'TolX',1.0e-16, ... - 'MaxFunEvals',100000, 'Display', 'iter'); - - K = size(sigEt,1); - mertdd = zeros(K,1); - mertdef = zeros(K,1); - mertGG = zeros(K,1); - mertsp = zeros(K,1); - mertA = zeros(K,1); - merts = zeros(K,1); - xmertdd = zeros(K,1); - xmertdef = zeros(K,1); - mdefsingle1 = zeros(K,1); - mFtsingle1 = zeros(K,1); - Ltsingle1 = zeros(K,1); - Ltsingle2 = zeros(K,1); - bookFsingle2 = zeros(K,1); - mdefsingle2 = zeros(K,1); - mFtsingle2 = zeros(K,1); - bookFsingle3 = zeros(K,1); - mdefsingle3 = zeros(K,1); - mFtsingle3 = zeros(K,1); - Ltsingle3 = zeros(K,1); - - Et1 = []; - sigEt1 = []; - fs1 = []; - bookF1 = []; - - - % - % Merton model fit to equity value and volatility from our model - % - - for k = 1:K - - initb = [Et(k,1)+D*exp(-r*H); sigEt(k,1)/2]; - [bout] = fsolve(@(b) MertonSolution(b, Et(k,1), D, r, y, H, sigEt(k,1)), initb, options); - A = bout(1); - s = max(bout(2),0.0001); - mertdd(k,1) = (log(A)-log(D)+(r-y-s^2/2)*H)/(s*sqrt(H)); % RN distance to default over horizon H; - % no subtraction of d because these are bank, not borrower assets - mertdef(k,1) = normcdf(-mertdd(k,1)); - [C, P] = blsprice(A , D, r, H, s, y); %payout rate y here just approx - mertGG(k,1) = g*P; - mertsp(k,1) = (1/H)*log((D*exp(-r*H))/((D*exp(-r*H))-P)); - mertA(k,1) = A; - merts(k,1) = s; - - end - - mktCR = Et./(Et+Bt); - sp = (1/H)*log((D*exp(-r*H))./Bt); - - % - % save files for different bookF values for MonotonicityAnalysis.m - % - - save([direc,'SimRNPD',rep], 'mertdef', 'mdef', 'bookF', 'sp', 'mertsp', 'fs', 'mFt',... - 'Nsim2', 'N', 'param'); - - - % - % fit alternative (simplified) models - % - - if j == 3 %main case discussed in the paper for one specific bookF - - %for alternative model (1): - %since both the model that produced Et and sigEt and the model that - %we are using to try to fit these Et and sigEt are based on numerical - %approximation, gradient-based methods doesn't work for fitting - %Therefore, work with interpolant to find fs, bookF combinations that fit - %equity value and volatility - - - % (1) Perfectly correlated borrowers with overlapping cohorts - - rho = 0.99; %approx to rho = 1, code can't handle rho = 1; - sig = 0.20*sqrt(0.5); - sfs = [-2.6:0.05:0.8]'/(0.2*sqrt(0.5)*sqrt(10)); %[-0.8:0.05:0.8] - - %we have D = bookD*exp(r*H)*mean(exp(r*([1:T])')) here - %and D = bookD*exp(xr(1,j,k,q)*H); in ModMertonCreateLookup, - %so adjust bookD1 here - bookD1 = bookD*mean(exp(r*([1:T])')); - [xfs,xsig,xr,xF] = ndgrid( sfs, sig, r, 0.4:0.01:1.44); - - [xLt, xBt, xEt, xFt, xmdef, xsigEt] = ModMertonCreateLookup(d,y,T,H,bookD1,rho,ltv,xfs,xr,xF,xsig,N,Nsim2); - xxsigEt = squeeze(xsigEt); - xxEt = squeeze(xEt); - xxmdef = squeeze(xmdef); - xxFt = squeeze(xFt); - ymdef = scatteredInterpolant(xxEt(:),xxsigEt(:),xxmdef(:),'natural','none'); - yFt = scatteredInterpolant(xxEt(:),xxsigEt(:),xxFt(:),'natural','none'); - mdefsingle1 = ymdef(Et,sigEt); - mFtsingle1 = yFt(Et,sigEt); - %recomputing Et, sigEt based on fs1, bookF1 gets back Et, sigEt to - %a very good approximation - - - % (2) Single cohort of borrowers - - T = 5; - rho = 0.5; sig = 0.2; - [xfs,xsig,xr,xF] = ndgrid( sfs, sig, r, 0.4:0.01:1.44); - [xLt, xBt, xEt, xFt, xmdef, xsigEt] = ModSingleMertonCreateLookup(d,y,T,H,bookD1,rho,ltv,xfs,xr,xF,xsig,N,Nsim2); - xxsigEt = squeeze(xsigEt); - xxEt = squeeze(xEt); - xxmdef = squeeze(xmdef); - xxFt = squeeze(xFt); - ymdef = scatteredInterpolant(xxEt(:),xxsigEt(:),xxmdef(:),'natural','none'); - yFt = scatteredInterpolant(xxEt(:),xxsigEt(:),xxFt(:),'natural','none'); - mdefsingle2 = ymdef(Et,sigEt); - mFtsingle2 = yFt(Et,sigEt); - - - % (3) Single (or perfectly correlated) borrower model - - T = 5; - rho = 0.99; sig = 0.2*sqrt(0.5); %approx of perfect correlation - [xfs,xsig,xr,xF] = ndgrid( sfs, sig, r, 0.4:0.01:1.44); - [xLt, xBt, xEt, xFt, xmdef, xsigEt] = ModSingleMertonCreateLookup(d,y,T,H,bookD1,rho,ltv,xfs,xr,xF,xsig,N,Nsim2); - xxsigEt = squeeze(xsigEt); - xxEt = squeeze(xEt); - xxmdef = squeeze(xmdef); - xxFt = squeeze(xFt); - ymdef = scatteredInterpolant(xxEt(:),xxsigEt(:),xxmdef(:),'natural','none'); - yFt = scatteredInterpolant(xxEt(:),xxsigEt(:),xxFt(:),'natural','none'); - mdefsingle3 = ymdef(Et,sigEt); - mFtsingle3 = yFt(Et,sigEt); - - - % (4) Merton model with asset value and asset volatility implied our modified model - - for k = 1:K - A = Lt(k,1); - s = sigLt(k,1); - xmertdd(k,1) = (log(A)-log(D)+(r-y-s^2/2)*H)/(s*sqrt(H)); - xmertdef(k,1) = normcdf(-xmertdd(k,1)); - end - - - % - % Some comparisons and figures for main part of the paper - % - - jup = j0+8; - jdn = j0-8; - disp('shock') - disp([fs(j0) fs(jup)]) - disp('Agg Borrower Asset Value') - disp([mFt(j0) mFt(jup)]) - disp('Market equity ratio') - disp([mktCR(j0) mktCR(jup)]) - disp('Mod RN def prob') - disp([mdef(j0) mdef(jup)]) - disp('Merton RN def prob') - disp([mertdef(j0) mertdef(jup)]) - disp('Mod Credit spread') - disp([sp(j0) sp(jup)]) - disp('Merton Credit spread') - disp([mertsp(j0) mertsp(jup)]) - - - A = [mFt(j0) mFt(jup) mFt(jdn); ... - Lt(j0) Lt(jup) Lt(jdn); ... - mktCR(j0) mktCR(jup) mktCR(jdn); ... - mdef(j0) mdef(jup) mdef(jdn); ... - sp(j0)*100 sp(jup)*100 sp(jdn)*100; ... - -9999 -9999 -9999; ... - mertdef(j0) mertdef(jup) mertdef(jdn); ... - mertsp(j0)*100 mertsp(jup)*100 mertsp(jdn)*100]; - Af = [' ' ' ' ' ']; - Aform = [Af; Af; Af; Af; Af; Af; Af; Af; Af]; - row = {'Agg. Borrower Asset Value', 'Bank Asset Value', 'Bank Market Equity/Market Assets', 'Bank 5Y RN Default Prob.', 'Bank Credit Spread (\%)', ' ', 'Merton 5Y RN Default Prob.', 'Merton Credit Spread (\%)'}; - head = {'Borrower asset value const.', 'Borrower asset value $+30\%$', 'Borrower asset value $-30\%$'}; - savename = [direc,'SimSummary.tex']; - matrix2latex_Stefan(A, savename, 'rowLabels', row, 'columnLabels',... - head, 'alignment', 'c', 'format', '%6.2f', 'size', 'footnotesize', 'specform', Aform); - - - f = figure - subplot(3,1,1) - hold on - scatter(FH(:,j0), LH(:,j0)+face(:,j0)*(exp(y*H) - 1),5) %LH is net of dividends, add back for this plot - line([0,mface],[0,mface],'LineWidth',2,'Color','r', 'LineStyle', '--') - line([mface,2.5],[mface,mface],'LineWidth',2,'Color','r','LineStyle', '--') - set(gca,'XLim',[0 2.5]) - set(gca,'YLim',[0 1.2]) - title('(a) Bank asset value') - ylabel('Bank asset value','FontSize',12) - %xlabel('Aggregate borrower asset value','FontSize',12) - hold off - subplot(3,1,2) - hold on - scatter(FH(:,j0),EH(:,j0),6) - line([0,D],[0,0],'LineWidth',2,'Color','r', 'LineStyle', '--') - line([D,mface],[0,mface-D],'LineWidth',2,'Color','r', 'LineStyle', '--') - line([mface,2.5],[mface-D,mface-D],'LineWidth',2,'Color','r', 'LineStyle', '--') - set(gca,'XLim',[0 2.5]) - %set(gca,'YLim',[0 1]) - title('(b) Bank equity value') - ylabel('Bank equity value','FontSize',12) - %xlabel('Aggregate borrower asset value','FontSize',12) - hold off - subplot(3,1,3) - hold on - scatter(FH(:,j0),BH(:,j0),6) - line([0,D],[0,D],'LineWidth',2,'Color','r', 'LineStyle', '--') - line([D,2.5],[D,D],'LineWidth',2,'Color','r', 'LineStyle', '--') - %set(gca,'XLim',[0 2]) - set(gca,'XLim',[0 2.5]) - title('(c) Bank debt value') - ylabel('Bank debt value','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - hold off - set(gcf, 'PaperSize', [6 7]); - set(gcf, 'PaperPositionMode', 'manual'); - %set(gcf, 'PaperPosition', [0 0 5.5 8]); - set(gcf, 'PaperUnits', 'normalized') - set(gcf, 'PaperPosition', [0 0 1 1]) - eval(['print(''',direc,'PayoffsAtDMat'',''-dpdf'')']) - - - f= figure - scatter(mFt,mktCR) - - f= figure - scatter(mFt,Et) - ylabel('Bank equity value','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'mVe.pdf'')']); - - f= figure - hold on - scatter(mFt,mdef,'MarkerEdgeColor','b') - scatter(mFt,mertdef,'MarkerEdgeColor','r', 'Marker', '+') - hold off - legend('Actual','Merton Model') - ylabel('RN bank default probability','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'mdef.pdf'')']); - - f = figure - hold on - scatter(mFt,mdef,'MarkerEdgeColor','b') - scatter(mFt,mertdef,'MarkerEdgeColor','r', 'Marker', '+') - hold off - legend('Actual','Merton Model') - set(gca,'YLim',[0 0.5]) - set(gca,'XLim',[0.6 1.6]) - ylabel('RN bank default probability','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'mdef2.pdf'')']); - - - f = figure - hold on - scatter(mFt,mdef,'MarkerEdgeColor','b') - plot(mFt,mdefsingle2,'--k') - plot(mFt,mdefsingle3,'--r') - scatter(mFt,mertdef,'MarkerEdgeColor','r', 'Marker', '+') - hold off - lgd = legend('Actual','Single cohort','Single borrower','Merton Model') - lgd.FontSize = 12; - ylabel('RN bank default probability','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'mdefsingles.pdf'')']); - - - - f = figure - hold on - scatter(mFt,mdef,'MarkerEdgeColor','b') - plot(mFt,xmertdef,'--k') - scatter(mFt,mertdef,'MarkerEdgeColor','r', 'Marker', '+') - hold off - lgd = legend('Actual','Merton w/ actual asset value and volatility','Merton Model') - lgd.FontSize = 12; - ylabel('RN bank default probability','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'mertalt.pdf'')']); - - - f = figure - hold on - scatter(mFt,Gt,'MarkerEdgeColor','b') - scatter(mFt,mertGG,'MarkerEdgeColor','r', 'Marker', '+') - hold off - legend('Actual','Merton Model') - set(gca,'YLim',[0 0.05]) - set(gca,'XLim',[0.6 1.6]) - ylabel('Value of government guarantee','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'mgg.pdf'')']); - - f = figure - hold on - scatter(mFt,sp,'MarkerEdgeColor','b') - scatter(mFt,mertsp,'MarkerEdgeColor','r', 'Marker', '+') - hold off - legend('Actual','Merton Model') - set(gca,'YLim',[0 0.03]) - set(gca,'XLim',[0.6 1.6]) - ylabel('Credit spread','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'msp.pdf'')']); - - f = figure - scatter(mFt,sigEt) - ylim([0 0.7]) - ylabel('Inst. bank equity vol.','FontSize',12) - xlabel('Aggregate borrower asset value','FontSize',12) - eval(['saveTightFigure(f,''',direc,'sigVe.pdf'')']); - - %construct Merton model equity volatility with constant asset volatility - [Cdelta, Pdelta] = blsdelta(Lt , D, r, H, 0.03, y); - [C, P] = blsprice(Lt , D, r, H, 0.03, y); - xeqvol = 0.03*Cdelta.*(Lt./C); - xlev = Lt./C; - - - f = figure - hold on - %scatter(log(Lt./Et),log(sigEt)) - %scatter(log(Lt./Et),log((Lt./Et)*merts(17)),'MarkerEdgeColor','r', 'Marker', '+') - scatter(log(Lt./Et),sigEt) - scatter(log(xlev(4:end)),xeqvol(4:end),'MarkerEdgeColor','r', 'Marker', '+') %=if asset vol was the same as in our model - hold off - xlim([0 4]) - ylabel('Inst. bank equity vol.','FontSize',12) - xlabel('Bank assets/equity','FontSize',12) - eval(['saveTightFigure(f,''',direc,'sigE.pdf'')']); - - figure - scatter(sigEt,Et) - - f = figure - hold on - line([0,0.8],[0,0.8],'LineWidth',2,'Color','r') - line([0.8,2],[0.8,0.8],'LineWidth',2,'Color','r') - line([0,0.6],[0,0],'LineWidth',2,'Color','b', 'LineStyle', ':') - line([0.6,0.8],[0,0.2],'LineWidth',2,'Color','b', 'LineStyle', ':') - line([0.8,2],[0.2,0.2],'LineWidth',2,'Color','b', 'LineStyle', ':') - line([0,0.6],[0,0.6],'LineWidth',2,'Color','g', 'LineStyle', '--') - line([0.6,2],[0.6,0.6],'LineWidth',2,'Color','g', 'LineStyle', '--') - text(1.2, 0.25 , 'Bank equity', 'Color', 'k','FontSize',16); - text(1.2, 0.65 , 'Bank debt', 'Color', 'k','FontSize',16); - text(1.2, 0.85 , 'Bank assets', 'Color', 'k','FontSize',16); - ylabel('Payoff','FontSize',16) - xlabel('Borrower asset value','FontSize',16) - set(gca,'FontSize',16) - set(gca,'XLim',[0 2]) - set(gca,'YLim',[0 1]) - hold off - eval(['saveTightFigure(f,''',direc,'payoffs.pdf'')']); - - x = 0:0.01:2; - f = figure - hold on - plot(x,1.6*(normcdf(x*2)-0.5),'LineWidth',2,'Color','r') - hold off - text(0.45, 0.4 , 'Bank asset value', 'Color', 'r','FontSize',16); - ylabel('Bank asset value','FontSize',16) - xlabel('Borrower asset value','FontSize',16) - set(gca,'FontSize',16) - set(gca,'XLim',[0 2]) - set(gca,'YLim',[0 1]) - hold off - eval(['saveTightFigure(f,''',direc,'payoffs1.pdf'')']); - - dy = [1.6*(normcdf(1*2)-0.5) - 2*(normpdf(1*2))*0.7; 1.6*(normcdf(1*2)-0.5) + 2*(normpdf(1*2))*0.7]; - dx = [0.3; 1.7]; - x = 0:0.01:2; - f = figure - hold on - plot(x,1.6*(normcdf(x*2)-0.5),'LineWidth',2,'Color','r') - line(dx,dy,'LineWidth',2,'Color','k', 'LineStyle', ':') - hold off - text(0.45, 0.4 , 'True nonlinear bank asset value', 'Color', 'r','FontSize',16); - text(0.1, 0.85 , 'Locally fitted lognormal model', 'Color', 'k','FontSize',16); - ylabel('Bank asset value','FontSize',16) - xlabel('Borrower asset value','FontSize',16) - set(gca,'FontSize',16) - set(gca,'XLim',[0 2]) - set(gca,'YLim',[0 1]) - hold off - eval(['saveTightFigure(f,''',direc,'payoffs2.pdf'')']); - - end - -end - - - - - - diff --git a/tests/measures/modified_merton/matlab/ModSingleCohortComputation.m b/tests/measures/modified_merton/matlab/ModSingleCohortComputation.m deleted file mode 100644 index c5358c66..00000000 --- a/tests/measures/modified_merton/matlab/ModSingleCohortComputation.m +++ /dev/null @@ -1,137 +0,0 @@ - -function [Lt, Bt, Et, LH, BH, EH, sigEt, mFt, def, mdef, face, FH, Gt, mu, F, sigLt] = ModSingleCohortComputation(fs, param, N, Nsim2, w) - - - r = param(1); %log risk free rate - T = param(2); %original maturity of bank loans - bookF = param(3); %cash amount of loan issued = book value for a coupon-bearing loan issued at par - H = param(4); %bank debt maturity - D = param(5); %face value of bank debt - rho = param(6); %borrower asset value correlation - ltv = param(7); %initial LTV - sig = param(8); %borrower asset value volatility - d = param(9); %depreciation rate of borrower assets - y = param(10); %bank payout rate - - %With single borrower cohort, N just determines discretization horizon of - %shocks, not the number of cohorts - - %optional: calculate value of govt guarantee, with prob g, govt absorbs - %Loss given default (bank and equity values not adjusted for presence of - %govt guarantee) - if size(param,1) > 10 - g = param(11); - else - g = 0; - end - - %optional: provide simulated factor shocks (for faster repeated computations) - %if not provided as input, then generate here - if nargin < 5 - rng(1,'twister') - w = normrnd(0,1,[Nsim2, N]); - end - - ival = log(bookF)-log(ltv); %initial log asset value of borrower at origination - sigf = sqrt(rho)*sig; - HN = H*(N/T); %maturity in N time; - szfs = size(fs,1); - fs = [fs; fs; fs]; %use second and third block for numerical derivative - Nsim1 = size(fs,1); - - %Euler discretization - f = [zeros(Nsim2,1) cumsum( (r-d-0.5*sig^2)*(T/N) + sigf*sqrt(T/N)*w , 2)]; - f1 = f(:,N+1); %from start of first loan to maturity of first loan w/ shocks until t removed - - %add fs shocks after loan origination - fsa(1,:) = fs*sigf*sqrt(T); - dstep = 10; %1/dstep of SD step to evaluate numerical derivative - df = sigf/dstep ; - fsa = fsa + df*cat(2,zeros(Nsim2,szfs),ones(Nsim2,szfs),-ones(Nsim2,szfs)); %divide by 2 to make comparable with average fs shock with multiple cohorts - f1j = repmat(f1,[1,Nsim1]) + fsa; - - %solve for promised yield on loan (a fixed point): - %do not remove factor shocks until t in this calculation - options = optimset('TolFun',1.0e-12,'MaxIter',100000, 'TolX',1.0e-12, ... - 'MaxFunEvals',100000, 'Display', 'off'); - initmu = r+0.01; - [muout,fval,exitflag,output] = fsolve(@(mu) FindFaceValueIndiv(mu, bookF*exp(mu*T), ival, sig, T, r, d), initmu, options); - if exitflag < 1 - disp('Face value not found') - end - mu = muout; %output is promised total yield - F = bookF*exp(mu*T); %loan face value; - - %payoffs at loan maturities - L1 = LoanPayoff(F, f1j, ival, rho, sig, T); - face1 = ones(size(f1j))*F; - - %factor realizations at t and t+H - ft = fsa + ival; - fH1 = f(:,1+HN); - fH1j = repmat(fH1,[1,Nsim1]) + fsa + ival; - FH1j = exp(fH1j).* exp(0.5*(1-rho)*H*sig^2); - Ft = exp(ft); - - %get conditional payoff distribution based on t+H information - FHr1 = FH1j; - Lr1 = L1; - - LHj = zeros(Nsim2,Nsim1); - FHr = reshape(FHr1(:,:),Nsim2*Nsim1,1); - Lr = reshape(Lr1(:,:),Nsim2*Nsim1,1); - [sortF, ind] = sort(FHr); - sortL = Lr(ind); - win = (Nsim2*Nsim1)/20; %/10 seems to give about sufficient smoothness - LHs = fftsmooth(sortL,win); - newInd = zeros(size(ind)); - newInd(ind) = 1:length(FHr); - %LHsn = reshape(LHs(newInd),Nsim2,1,Nsim1).*sc(:,j,:) - (face1(:,j,:)+face2(:,j,:))*(exp(y*H) - 1); - LH1j = reshape(LHs(newInd),Nsim2,Nsim1); - - - %get portfolio payoff distribution at t+H - LH = LH1j.*exp(-r*(T-H)) ; - FH = FHr1; - face = face1.*exp(-r*(T-H)); - - BH = min(D,LH*exp(-y*H)); - EHex = LH*exp(-y*H) - BH; - EH = LH-BH; - GH = g*max(D-LH*exp(-y*H),0); - - - %now integrate conditional on f_t over factor distribution at t+H - Lt = mean(LH)'*exp(-r*H); - Bt = mean(BH)'*exp(-r*H); - Et = mean(EH)'*exp(-r*H); - Gt = mean(GH)'*exp(-r*H); - mFt = mean(Ft)'; - - %RN default indicator - def = ones(size(EHex)); - ldef = EHex > 0; - def(ldef) = 0; - - mdef = mean(def)'; - - %take numerical first derivative to get instantaneous equity vol - %consider SD/dstep move of f - sigEt = (dstep/2)*(log(Et(szfs+1:2*szfs,1)) - log(Et(2*szfs+1:3*szfs,1))); %since move is 2 times SD/10 - sigLt = (dstep/2)*(log(Lt(szfs+1:2*szfs,1)) - log(Lt(2*szfs+1:3*szfs,1))); %since move is 2 times SD/10 - - Lt = Lt(1:szfs,1); - Bt = Bt(1:szfs,1); - Et = Et(1:szfs,1); - LH = LH(:,1:szfs); - BH = BH(:,1:szfs); - EH = EH(:,1:szfs); - FH = FH(:,1:szfs); - mFt = mFt(1:szfs,1); - def = def(:,1:szfs); - mdef = mdef(1:szfs,1); - face = face(:,1:szfs); - Gt = Gt(1:szfs,1); - - - diff --git a/tests/measures/modified_merton/matlab/ModSingleCohortSolution.m b/tests/measures/modified_merton/matlab/ModSingleCohortSolution.m deleted file mode 100644 index c632f837..00000000 --- a/tests/measures/modified_merton/matlab/ModSingleCohortSolution.m +++ /dev/null @@ -1,26 +0,0 @@ -function [err] = ModSingleCohortSolution(b, param, N, Nsim2, E, sigE) - -fs = b(1); -param(3) = b(2); - -%{ -skip = 0; -sig = b(2); -esig = 0; -if sig < 0 - sig = 0; - esig = 9999999; - skip = 1; -end -eA = 0; -if fs < 0 - fs = 0; - eA = 9999999; - skip = 1; -end -%} - -[Lt, Bt, Et, LH, BH, EH, sigEt, mFt, def, mdef, face, FH, Gt, mu, F, sigLt] = ModSingleCohortComputation(fs, param, N, Nsim2); -err = [E - Et; sigE-sigEt]; - - diff --git a/tests/measures/modified_merton/matlab/ModSingleMertonCreateLookup.m b/tests/measures/modified_merton/matlab/ModSingleMertonCreateLookup.m deleted file mode 100644 index ad7448f3..00000000 --- a/tests/measures/modified_merton/matlab/ModSingleMertonCreateLookup.m +++ /dev/null @@ -1,47 +0,0 @@ - - -function [xLt, xBt, xEt, xFt, xmdef, xsigEt] = ModSingleMertonCreateLookup(d,y,T,H,bookD,rho,ltv,xfs,xr,xF,xsig,N,Nsim2) - - -rng(1,'twister') -w = normrnd(0,1,[Nsim2, 3*N]); - -J = size(xsig,2); -K = size(xr,3); -Q = size(xF,4); -G = size(xfs,1); - -fs = xfs(:,1,1,1); - -xLt = zeros(G,J,K,Q); -xBt = zeros(G,J,K,Q); -xEt = zeros(G,J,K,Q); -xFt = zeros(G,J,K,Q); -xmdef = zeros(G,J,K,Q); -xsigEt = zeros(G,J,K,Q); - -for j = 1:J - - for k = 1:K - - for q = 1:Q - j - k - q - - param = [xr(1,j,k,q); T; xF(1,j,k,q); H; bookD*exp(xr(1,j,k,q)*H); rho; ltv; xsig(1,j,k,q); d; y]; %get face value of debt from current book value of debt - - [Lt, Bt, Et, ~, ~, ~, sigEt, mFt, ~, mdef] = ModSingleCohortComputation(fs, param, N, Nsim2, w); - - xLt(:,j,k,q) = Lt; - xBt(:,j,k,q) = Bt; - xEt(:,j,k,q) = Et; - xFt(:,j,k,q) = mFt; - xmdef(:,j,k,q) = mdef; - xsigEt(:,j,k,q) = sigEt; - - end - end -end - - diff --git a/tests/measures/modified_merton/matlab/Readme.txt b/tests/measures/modified_merton/matlab/Readme.txt deleted file mode 100644 index d567c545..00000000 --- a/tests/measures/modified_merton/matlab/Readme.txt +++ /dev/null @@ -1,18 +0,0 @@ -Code for Bank Risk Dynamics and Distance to Default -by Stefan Nagel and Amiyatosh Purnanandam -6/28/2019 - -*** These code files are made available for non-commercial purposes only *** - -------------------- - -(1) Simulation: - -main program: ModMertonSimulation.m -calls ModMertonComputation.m to calculate modified Merton model RNPD for a range of dW_0 shocks - - -(2) Empirical application: - -main program: ModMertonEmpirical_unobsbookF.m -takes files with bank-level data on equity values/book debt, equity return volatility to compute modified Merton model RNPD by calling ModMertonCreateLookup.m (which calls ModMertonComputation.m) \ No newline at end of file diff --git a/tests/measures/modified_merton/matlab/fftsmooth.m b/tests/measures/modified_merton/matlab/fftsmooth.m deleted file mode 100644 index ba6de2ce..00000000 --- a/tests/measures/modified_merton/matlab/fftsmooth.m +++ /dev/null @@ -1,23 +0,0 @@ -function [xout] = fftsmooth(x,w) - -%NOTE: so far this function works only for even number of obs and even -%number of kernel window elements - -%x = column vector of inputs to be smoothed -%w = window size (in # of obs) - -n = size(x,1); -xpad = [zeros(n,1); x]; -k = [zeros(n-w/2,1); ones(w,1)/w; zeros(n-w/2,1)]; -Fx = fft(xpad); -Fk = fft(k); -Fxk = Fx .* Fk; -xk = ifft(Fxk); - -%extrapolate linearly at edges -dl = (xk(w/2+2)-xk(w/2+1)); %/(w-1); -lex = xk(w/2+1) - ([w/2:-1:1])'*dl; -ul = (xk(n-w/2)-xk(n-w/2-1)); %/(w-1); -uex = xk(n-w/2) + ([1:w/2])'*ul; - -xout = [lex; xk(w/2+1:n-w/2); uex]; diff --git a/tests/measures/modified_merton/matlab/matrix2latex_Stefan.m b/tests/measures/modified_merton/matlab/matrix2latex_Stefan.m deleted file mode 100644 index d3323910..00000000 --- a/tests/measures/modified_merton/matlab/matrix2latex_Stefan.m +++ /dev/null @@ -1,267 +0,0 @@ -function matrix2latex_Stefan(matrix, filename, varargin) - -% function: matrix2latex(...) -% Author: M. Koehler -% Contact: koehler@in.tum.de -% Version: 1.1 -% Date: May 09, 2004 - -% modified by Stefan Nagel June 2007 - -% This software is published under the GNU GPL, by the free software -% foundation. For further reading see: http://www.gnu.org/licenses/licenses.html#GPL - -% Usage: -% matrix2late(matrix, filename, varargs) -% where -% - -9999 is a code for an empty cell -% - matrix is a 2 dimensional numerical or cell array -% - filename is a valid filename, in which the resulting latex code will -% be stored -% - varargs is one ore more of the following (denominator, value) combinations -% + 'rowLabels', array -> Can be used to label the rows of the -% resulting latex table -% + 'columnLabels', array -> Can be used to label the columns of the -% resulting latex table -% + 'alignment', 'value' -> Can be used to specify the alginment of -% the table within the latex document. Valid arguments are: 'l', 'c', -% and 'r' for left, center, and right, respectively -% + 'format', 'value' -> Can be used to format the input data. 'value' -% has to be a valid format string, similar to the ones used in -% fprintf('format', value); -% + 'size', 'value' -> One of latex' recognized font-sizes, e.g. tiny, -% HUGE, Large, large, LARGE, etc. -% + 'specform', array -> 'p' for parentheses, 'b' for brackets, ' ' -% otherwise -% + 'topwidth', array -> additional header line w/ merged cells -% + 'topcollabels', array -> labels for additional header line -% + 'topcollines', array -> '_' for underlined cells, ' ' otherwise -% -% Example input: -% matrix = [1.5 1.764; 3.523 0.2]; -% rowLabels = {'row 1', 'row 2'}; -% columnLabels = {'col 1', 'col 2'}; -% matrix2latex(matrix, 'out.tex', 'rowLabels', rowLabels, 'columnLabels', ... -% columnLabels, 'alignment', 'c', 'format', '%-6.2f', 'size', 'tiny'); -% -% The resulting latex file can be included into any latex document by: -% /input{out.tex} -% - - - - [height width] = size(matrix); - - rowLabels = []; - colLabels = []; - alignment = 'l'; - format = []; - textsize = []; - topwidth = []; - topcolLabels = []; - topcolLines = []; - specform = repmat(' ', height, width); - - if (rem(nargin,2) == 1 || nargin < 2) - error('matrix2latex: ', 'Incorrect number of arguments to %s.', mfilename); - end - - okargs = {'rowlabels', 'columnlabels', 'alignment', 'format', 'size', ... - 'specform', 'topwidth', 'topcollabels', 'topcollines'}; - - for j=1:2:(nargin-2) - pname = varargin{j}; - pval = varargin{j+1}; - k = strmatch(lower(pname), okargs); - if isempty(k) - error('matrix2latex: ', 'Unknown parameter name: %s.', pname); - elseif length(k)>1 - error('matrix2latex: ', 'Ambiguous parameter name: %s.', pname); - else - switch(k) - case 1 % rowlabels - rowLabels = pval; - if isnumeric(rowLabels) - rowLabels = cellstr(num2str(rowLabels(:))); - end - case 2 % column labels - colLabels = pval; - if isnumeric(colLabels) - colLabels = cellstr(num2str(colLabels(:))); - end - case 3 % alignment - alignment = lower(pval); - if alignment == 'right' - alignment = 'r'; - end - if alignment == 'left' - alignment = 'l'; - end - if alignment == 'center' - alignment = 'c'; - end - if alignment ~= 'l' && alignment ~= 'c' && alignment ~= 'r' - alignment = 'l'; - warning('matrix2latex: ', 'Unkown alignment. (Set it to \''left\''.)'); - end - case 4 % format - format = lower(pval); - case 5 % format - textsize = pval; - case 6 % brackets or parentheses - specform = pval; - case 7 % top header - topwidth = pval; - case 8 % top header - topcolLabels = pval; - if isnumeric(topcolLabels) - topcolLabels = cellstr(num2str(topcolLabels(:))); - end - case 9 % top header - topcolLines = pval; - end - end - end - - fid = fopen(filename, 'wt'); - - if isnumeric(matrix) - matrix = num2cell(matrix); - - for h=1:height - for w=1:width - if(~isempty(format)) - if matrix{h, w} == -9999 - matrix{h, w} = ' '; - elseif specform(h,w) == 'p' - matrix{h, w} = ['(',num2str(matrix{h, w}, format),')']; - elseif specform(h,w) == 'b' - matrix{h, w} = ['[',num2str(matrix{h, w}, format),']']; - else - matrix{h, w} = num2str(matrix{h, w}, format); - end - else - if matrix{h, w} == -9999 - matrix{h, w} = ' '; - elseif specform(h,w) == 'p' - matrix{h, w} = ['(',num2str(matrix{h, w}),')']; - elseif specform(h,w) == 'b' - matrix{h, w} = ['[',num2str(matrix{h, w}),']']; - else - matrix{h, w} = num2str(matrix{h, w}); - end - end - end - end - end - - if(~isempty(textsize)) - fprintf(fid, '\\begin{%s}', textsize); - end - - fprintf(fid, '\\begin{tabular}{' ); - - if(~isempty(rowLabels)) - fprintf(fid, 'l'); - end - for i=1:width - fprintf(fid, '%c', alignment); %Note: %c = single character format - end - fprintf(fid, '}\r\n'); - - fprintf(fid, '\\hline\\hline\r\n'); - - if(~isempty(topcolLabels)) - if(~isempty(rowLabels)) - fprintf(fid, '& '); - end - count = 1; - subcount = 1; - for tw = 1:width - if topwidth(count) == 1 - if tw == width - fprintf(fid, '%s ', topcolLabels{count}); - else - fprintf(fid, '%s& ', topcolLabels{count}); - end - count = count+1; - else - if subcount == topwidth(count) %& \multicolumn{5}{c}{head1} & & head2 \\ \cline{2-6}\cline{8-8} - twcstr = int2str(subcount); - fprintf(fid, '\\multicolumn{%s}{c}', twcstr); - if tw == width - fprintf(fid, '{%s} ', topcolLabels{count}); - else - fprintf(fid, '{%s} & ', topcolLabels{count}); - end - subcount = 1; - count = count+1; - else - subcount = subcount+1; - end - end - end - fprintf(fid, '\\\\ '); - count = 1; - subcount = 1; - if(~isempty(rowLabels)) - shift = 1; - else - shift = 0; - end - for tw = 1:width - if topwidth(count) == 1 - if topcolLines(count) == '_' - startstr = int2str(tw+shift); - endstr = int2str(tw+shift); - fprintf(fid, '\\cline{%s',startstr); - fprintf(fid, '-%s}', endstr); - end - count = count+1; - else - if subcount == topwidth(count) - startstr = int2str(tw-subcount+1+shift); - endstr = int2str(tw+shift); - if topcolLines(count) == '_' - fprintf(fid, '\\cline{%s',startstr); - fprintf(fid, '-%s}', endstr); - end - subcount = 1; - count = count+1; - else - subcount = subcount+1; - end - end - end - fprintf(fid, '\r\n'); - end - - - if(~isempty(colLabels)) - if(~isempty(rowLabels)) - fprintf(fid, '& '); - end - for w=1:width-1 - fprintf(fid, '%s &', colLabels{w}); %Note: %s = string format, \\ results in a backslash - end - fprintf(fid, '%s\\\\\\hline\r\n', colLabels{width}); %Note: \r\n is carriage return and new line - end % \\ are row separators in tex, to - % generate them in Matlab requires four \ - for h=1:height - if(~isempty(rowLabels)) - fprintf(fid, '%s &', rowLabels{h}); - end - for w=1:width-1 - fprintf(fid, '%s &', matrix{h, w}); - end - fprintf(fid, '%s\\\\\r\n', matrix{h, width}); - end - - fprintf(fid, '\\hline\\hline\r\n'); - fprintf(fid, '\\end{tabular}\r\n'); - - if(~isempty(textsize)) - fprintf(fid, '\\end{%s}', textsize); - end - - fclose(fid); diff --git a/tests/measures/modified_merton/matlab/mdef_output.mat b/tests/measures/modified_merton/matlab/mdef_output.mat deleted file mode 100644 index b0ceebaf5072552b696d008d433d2933cbd127ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 996 zcmeZu4DoSvQZUssQ1EpO(M`+DN!3vZ$Vn_o%P-2cQV4Jk_w+L}(NS}aZCnRt%B$+8Z zYq+Fvfa~dI218{DV~Kdq1x|J$;FM{U-Zo*P{O`e%buD=UsWW)$`g- z>gVZYE|J8ZHqvHYi}a$>k99DqXuI>zVFv{pFME zKC$h&t^fJ3dceZ>ZGYQSO{?ct`rl+`NUjmQMZm<(22YkPSyl)#anH*$U7`(cfU!GGrF%|TDJ1Z+V%u{nK{c-4K4~+lsHTcO`#Eo_u!gW{~(>#t1z@CRCqcy3lya)8`Na zZL-xk=4?6c%FHn5mq)V=C($0IlqL ALjV8( diff --git a/tests/measures/modified_merton/matlab/saveTightFigure.m b/tests/measures/modified_merton/matlab/saveTightFigure.m deleted file mode 100644 index 55efe04f..00000000 --- a/tests/measures/modified_merton/matlab/saveTightFigure.m +++ /dev/null @@ -1,25 +0,0 @@ -function saveTightFigure(h,outfilename) -% SAVETIGHTFIGURE(H,OUTFILENAME) Saves figure H in file OUTFILENAME without -% the white space around it. -% -% by ``a grad student" -% http://tipstrickshowtos.blogspot.com/2010/08/how-to-get-rid-of-white-margin-in.html - -% get the current axes -ax = get(h, 'CurrentAxes'); - -% make it tight -%ti = get(ax,'TightInset'); -%set(ax,'Position',[ti(1) ti(2) 1-ti(3)-ti(1) 1-ti(4)-ti(2)]); - -% adjust the papersize -set(ax,'units','centimeters'); -pos = get(ax,'Position'); -ti = get(ax,'TightInset'); -set(h, 'PaperUnits','centimeters'); -set(h, 'PaperSize', [pos(3)+ti(1)+ti(3) pos(4)+ti(2)+ti(4)]); -set(h, 'PaperPositionMode', 'manual'); -set(h, 'PaperPosition',[0 0.3 pos(3)+ti(1)+ti(3) pos(4)+ti(2)+ti(4)]); - -% save it -saveas(h,outfilename); diff --git a/tests/measures/modified_merton/matlab/test_inputdata.csv b/tests/measures/modified_merton/matlab/test_inputdata.csv deleted file mode 100644 index 5816ad9f..00000000 --- a/tests/measures/modified_merton/matlab/test_inputdata.csv +++ /dev/null @@ -1,5 +0,0 @@ -E,PERMCO,year,month,r,sE -0.078227933,25,1988,10,0.084341148,0.33067155 -0.20261438,589,2010,1,0.036621183,0.379312011 -0.219369416,9662,2004,4,0.042580448,0.222623649 -0.180155399,15933,2015,1,0.018625464,0.26723748 diff --git a/tests/measures/modified_merton/test_fftsmooth.py b/tests/measures/modified_merton/test_fftsmooth.py index 7045149a..364285b6 100644 --- a/tests/measures/modified_merton/test_fftsmooth.py +++ b/tests/measures/modified_merton/test_fftsmooth.py @@ -15,9 +15,14 @@ class FFTSmoothTestCase(unittest.TestCase): def setUp(self) -> None: - mp = pathlib.Path(__file__).parent.joinpath("matlab").as_posix() + frds_path = [ + i for i in pathlib.Path(__file__).parents if i.as_posix().endswith("frds") + ].pop() + self.mp = frds_path.joinpath( + "src", "frds", "measures", "modified_merton", "matlab" + ).as_posix() self.eng = matlab.engine.start_matlab() - self.eng.cd(mp, nargout=0) + self.eng.cd(self.mp, nargout=0) def test_fftsmooth(self): Nsim1 = 99 diff --git a/tests/measures/modified_merton/test_find_face_value_indiv.py b/tests/measures/modified_merton/test_find_face_value_indiv.py index 50b903aa..c783814e 100644 --- a/tests/measures/modified_merton/test_find_face_value_indiv.py +++ b/tests/measures/modified_merton/test_find_face_value_indiv.py @@ -13,9 +13,14 @@ class FindFaceValueIndivTestCase(unittest.TestCase): def setUp(self) -> None: - mp = pathlib.Path(__file__).parent.joinpath("matlab").as_posix() + frds_path = [ + i for i in pathlib.Path(__file__).parents if i.as_posix().endswith("frds") + ].pop() + self.mp = frds_path.joinpath( + "src", "frds", "measures", "modified_merton", "matlab" + ).as_posix() self.eng = matlab.engine.start_matlab() - self.eng.cd(mp, nargout=0) + self.eng.cd(self.mp, nargout=0) def test_find_face_value_indiv(self): r = 0.01 diff --git a/tests/measures/modified_merton/test_loan_payoff.py b/tests/measures/modified_merton/test_loan_payoff.py index 6d1f1c72..94813be9 100644 --- a/tests/measures/modified_merton/test_loan_payoff.py +++ b/tests/measures/modified_merton/test_loan_payoff.py @@ -14,12 +14,17 @@ class LoanPayoffTestCase(unittest.TestCase): def setUp(self) -> None: - mp = pathlib.Path(__file__).parent.joinpath("matlab").as_posix() + frds_path = [ + i for i in pathlib.Path(__file__).parents if i.as_posix().endswith("frds") + ].pop() + self.mp = frds_path.joinpath( + "src", "frds", "measures", "modified_merton", "matlab" + ).as_posix() self.eng = matlab.engine.start_matlab() - self.eng.cd(mp, nargout=0) + self.eng.cd(self.mp, nargout=0) def test_loan_payoff(self): - result = self.eng.GenTestDataLoanPayoff(nargout=6) + result = self.eng.FRDSGenTestDataLoanPayoff(nargout=6) F, _, ival, rho, sig, T = result f1j = np.asarray(result[1]) diff --git a/tests/measures/modified_merton/test_matlab_python_conversion.py b/tests/measures/modified_merton/test_matlab_python_conversion.py index 61834efd..f96007ce 100644 --- a/tests/measures/modified_merton/test_matlab_python_conversion.py +++ b/tests/measures/modified_merton/test_matlab_python_conversion.py @@ -14,7 +14,12 @@ class MatlabPythonConversionTestCase(unittest.TestCase): def setUp(self) -> None: - self.mp = pathlib.Path(__file__).parent.joinpath("matlab").as_posix() + frds_path = [ + i for i in pathlib.Path(__file__).parents if i.as_posix().endswith("frds") + ].pop() + self.mp = frds_path.joinpath( + "src", "frds", "measures", "modified_merton", "matlab" + ).as_posix() self.eng = matlab.engine.start_matlab() self.eng.cd(self.mp, nargout=0) diff --git a/tests/measures/modified_merton/test_merton_solution.py b/tests/measures/modified_merton/test_merton_solution.py index 59a14891..1fe79b59 100644 --- a/tests/measures/modified_merton/test_merton_solution.py +++ b/tests/measures/modified_merton/test_merton_solution.py @@ -17,9 +17,14 @@ class MertonSolutionTestCase(unittest.TestCase): def setUp(self) -> None: - mp = pathlib.Path(__file__).parent.joinpath("matlab").as_posix() + frds_path = [ + i for i in pathlib.Path(__file__).parents if i.as_posix().endswith("frds") + ].pop() + self.mp = frds_path.joinpath( + "src", "frds", "measures", "modified_merton", "matlab" + ).as_posix() self.eng = matlab.engine.start_matlab() - self.eng.cd(mp, nargout=0) + self.eng.cd(self.mp, nargout=0) # fmt: off fs = np.arange(-0.8, 0.85, 0.05) / (0.2 * np.sqrt(0.5) * np.sqrt(10)) @@ -110,3 +115,7 @@ def test_fsolve_merton_solution(self): assert_array_almost_equal(np.array(bout_py), np.array(bout_matlab).ravel(), decimal=9) # fmt: on + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/measures/modified_merton/test_mod_merton_computation.py b/tests/measures/modified_merton/test_mod_merton_computation.py index 3a22d5ff..d2c50ace 100644 --- a/tests/measures/modified_merton/test_mod_merton_computation.py +++ b/tests/measures/modified_merton/test_mod_merton_computation.py @@ -14,9 +14,14 @@ class ModMertonComputationTestCase(unittest.TestCase): def setUp(self) -> None: - mp = pathlib.Path(__file__).parent.joinpath("matlab").as_posix() + frds_path = [ + i for i in pathlib.Path(__file__).parents if i.as_posix().endswith("frds") + ].pop() + self.mp = frds_path.joinpath( + "src", "frds", "measures", "modified_merton", "matlab" + ).as_posix() self.eng = matlab.engine.start_matlab() - self.eng.cd(mp, nargout=0) + self.eng.cd(self.mp, nargout=0) def test_mod_merton_computation(self): # fmt: off diff --git a/tests/measures/modified_merton/test_mod_merton_create_lookup.py b/tests/measures/modified_merton/test_mod_merton_create_lookup.py index 538269ed..26a83502 100644 --- a/tests/measures/modified_merton/test_mod_merton_create_lookup.py +++ b/tests/measures/modified_merton/test_mod_merton_create_lookup.py @@ -19,7 +19,12 @@ class ModMertonCreateLookupTestCase(unittest.TestCase): def setUp(self) -> None: - self.mp = pathlib.Path(__file__).parent.joinpath("matlab").as_posix() + frds_path = [ + i for i in pathlib.Path(__file__).parents if i.as_posix().endswith("frds") + ].pop() + self.mp = frds_path.joinpath( + "src", "frds", "measures", "modified_merton", "matlab" + ).as_posix() self.eng = matlab.engine.start_matlab() self.eng.cd(self.mp, nargout=0)