Black1976 swaption pricing for a bespoke deal

by

 

This function prices a swaption portfolio with any cash-low structure

swaptionbyblk_bank( U, V, Curve )
function [price, delta, swp_premium, par_swap] = swaptionbyblk_bank( U, V, Curve )
%---------------------------------------------------------------------------------
% This function prices swaptions in the Black1976 model for any given cash-flow
% structure. It assumes (without checking) that the matrix U is an n by 5 (at least)
% matrix containing, respectively by column, the cash-flow code, the payment date 
% (matlab format), the cash-flow (negative for fixed payer and positive otherwise), 
% the coupon rate and finally the day-count basis. The earliest cash-flow is assumed to be
% a no coupon payment used to determine the settlement date of the swap. The coupon
% rate is expected to be constant and the strike is determined by the last coupon rate
% in line. The current date is the settlement date of the curve object, while the
% volatility matrix is assumed to be 10y by 10y (Exp-by-Mat) volatility surface.
%
% The option exposure is assumed to be long (option buyer) with the convention that
% a negative fixed leg cash-flow (fix payer) entails call option exposure. 
% On the other side, a positive fixed leg cash-flow (fix reciever) is associated
% to a long put swaption exposure.
%
% input
% U : code, date, principal, coupon, basis
% V : volatility matrix
% Curve : interest rate curve object

items=unique(U(:,1));
n_item=size(items,1);
CouponRate=cell(size(items));
Principal=cell(size(items));
CFDates=cell(size(items));
Basis=zeros(size(items));
accrued=zeros(size(items));
FixedLeg=zeros(size(items));
FloatLeg=zeros(size(items));
Annuity=zeros(size(items));
Settle=zeros(size(items));
Maturity=zeros(size(items));
oggi=Curve.Settle;
K=zeros(size(items));
price=zeros(size(items));
delta=zeros(size(items));

for i=1:n_item

	H=U(U(:,1)==items(i),:);
    [~,u]=sort(H(:,2));
    H=H(u,:);
    m=find(H(:,2)<=oggi,1,'last');
    if isempty(m), m=0; end
    
    CouponRate(i)={H(:,4)/100};
    Principal(i)={H(:,3)};
    CFDates(i)={H(:,2)};
    Basis(i)=H(1,5);
    CFDates_num=size(H,1);
    K(i)=H(end,4);% record the fix rate
    Settle(i)=H(1,2);
    Maturity(i)=H(end,2);
    if m<CFDates_num,
        
        switch m
            
            case 0

                alpha=yearfrac(CFDates{i}(1:end-1),CFDates{i}(2:end),Basis(i));
                disc_factors=Curve.getDiscountFactors(CFDates{i}(:));
                disc_fwdRates=diff(-disc_factors);
                FloatLeg(i)=Principal{i}(2:end)'*disc_fwdRates;
                FixedLeg(i)=(Principal{i}(2:end).*CouponRate{i}(2:end))'*(disc_factors(2:end).*alpha);
                Annuity(i)=(Principal{i}(2:end))'*(disc_factors(2:end).*alpha);
            
            otherwise

                cpnfrac=daysdif(oggi,CFDates{i}(m+1),Basis(i))/daysdif(CFDates{i}(m),CFDates{i}(m+1),Basis(i));
                accrued(i)=-(1-cpnfrac)*Principal{i}(m+1)*CouponRate{i}(m+1);
                alpha=yearfrac([oggi;CFDates{i}(m+1:end-1)],CFDates{i}(m+1:end),Basis(i));
                disc_factors=[1;Curve.getDiscountFactors(CFDates{i}(m+1:end))];
                disc_fwdRates=diff(-disc_factors);
                FloatLeg(i)=Principal{i}(m+1:end)'*disc_fwdRates;
                FixedLeg(i)=(Principal{i}(m+1:end).*CouponRate{i}(m+1:end))'*(disc_factors(2:end).*alpha);
                Annuity(i)=abs(Principal{i}(m+1:end))'*(disc_factors(m+1:end).*alpha);
           
        end
    
    else
        
        FloatLeg(i)=nan;
        FixedLeg(i)=nan;
        Annuity(i)=nan;
        
    end
    
end

t=yearfrac(oggi,Settle,Basis);
m=yearfrac(Settle,Maturity,Basis);
[X,Y]=meshgrid((0:10)');
V=[[V(1,1);V(:,1)],[V(1,:);V]]/100;% expand V to include the 0's
v=interp2(X,Y,V,max(t,0),m);% avoid the possibly expired swaptions
v(t<=0)=0;
swp_premium = -(FixedLeg - FloatLeg);
par_swap = abs(FloatLeg) ./ Annuity;
[call put] = blsprice(par_swap,K/100,0,max(t,1e-15),v);
[Dcall Dput] = blsdelta(par_swap,K/100,0,max(t,1e-15),v);
    for i=1:n_item,
        if FixedLeg(i)>0,
            price(i)=put(i)*Annuity(i);
            delta(i)=Dput(i)*Annuity(i);
        else
            price(i)=call(i)*Annuity(i);
            delta(i)=Dcall(i)*Annuity(i);
        end
    end 

end

Contact us