A CDO Square (also CDO^2 or CDO$ ^2 $) is basically a CDO with a CDO portfolio as underlying. As in the CDO, the CDO Square divides the risk of the underlying instruments into specific tranches.
First, let's reconsider a CDO whose underlyings pay coupons. In ThetaML, an array Coupon denotes the discounted process of coupon payments. The CDO has a maturity of T and the cash flows are discounted with the numeraire EUR. In order to price the CDO, two tranche levels (e.g. Tranche = [0.1, 0.3]) are required.
The result of the model CDO is the price P of the CDO tranche as well as a process C with the stochastic discounted payments of the CDO.
%% CDO model following the Vasicek Model %% Price of tranche with Tranche to Tranche %% defaults model CDO import T "maturity" import EUR "numeraire" import Coupon "Payment of underlyings" import Tranche "Tranche level" export P "CDO value" export sum "Sum of discounted payments" export perc "Accumulated defaults" export C "Payment on CDO" P = E(V!) sum=0 max_payments = sum(Coupon!,2)/EUR!; loop T*4 % payment each quater year Theta 1/4 % compute percentage of defaulted assets perc= 1 - sum(Coupon,2)/(max_payments*EUR) % compute payments for specific tranche C = (max(Tranche-max(Tranche,perc),0)); sum=sum + C; end V = sum end
This CDO is now called from the model CDO_square with 5 different parameter sets. 5 different CDO payment processes are created and saved into an array C of processes. These payment processes are again used in a CDO structure to price the CDO Square.
%% CDO Square model calling CDO %% Price of first 10% (equity) tranche %% of a portfolio with mezzanine tranches model CDO_square import T "maturity" import EUR "numeraire" import Coupon "Payment of underlyings" export P "Price of CDO Square" export sum "Sum" export C "Payment on CDO" type Coupon float type C float P = E(V!) index_CDO = [1,2,3,4] index_CDO_square = 1 loop 5 call CDO export Coupon[index_CDO] to Coupon export T, EUR export [0.1, 0.3] to Tranche import C[index_CDO_square] from C index_CDO = index_CDO + 4 index_CDO_square = index_CDO_square + 1 end call CDO export C to Coupon export T, EUR export [0.0, 0.1] to Tranche import sum import V from P end
An example using a stochastic process is shown in Theta.m
function state = Theta(dt, state) % A theta file which delivers a multi-dimensional payment process % with asset prices S and payment Coupon. The individual underlyings % are modeled with a correlation rho. if nargin == 0 state.S.comment = 'Stock price'; state.EUR.comment = 'Numeraire'; state.rho.comment = 'Correlation'; state.sigma.comment= 'Volatility'; state.Coupon.comment='Coupon'; else % risk free interest rate r = 0.05; % Reduced coupon below Barrier1, default below Barrier2 Barrier1 = 30; Barrier2 = 10; % initial Coupon Coupon_0 = 6; % risk-neutral drift mu = r; % correlation rho=mean(state.rho); sigma = ones(1,size(state.S,2))*mean(state.sigma); Z=zeros(length(sigma),length(sigma)); for i=1:length(sigma) for k=1:length(sigma) if i==k Z(i,i)=sigma(i)^2; else Z(i,k)=rho^2*sigma(i)*sigma(k); end end end A=(chol(Z))'; B=randn(size(state.S')); for i = 1:length(sigma) state.S(:,i) = state.S(:,i) .* exp( (mu-0.5*sigma(i)^2)*dt + sqrt(dt)*(A(i,:)*B)'); end state.EUR = state.EUR*exp(-r*dt); state.S(state.S<Barrier2) = 0; % compute coupon value risk-neutrally discounted state.Coupon = Coupon_0 * max(0,min(1,(state.S-Barrier2)/(Barrier1-Barrier2))) .* repmat(state.EUR,1,size(state.S,2)); end end