%% Compute LIBOR Fallback
% This example shows how to compute a USD LIBOR fallback. Regulators and industry groups have recommended that firms transition away from the London inter-bank offered rate (LIBOR) and prepare to replace them with overnight Alternative Reference Rates (ARRs). What happens to contracts with a notional value of trillions of dollars if they refer to a benchmark that no longer exists? If the LIBOR benchmark is no longer published, references to that benchmark rate must change and benchmark rates “fall back” to a new benchmark in contracts. For example, if a 30-year floating-rate instrument with a three-month coupon based on the LIBOR rate is created in 2008 and expires in 2038, then the rate will need to change in 2023 because in 2023, the publication of a LIBOR rate permanently ceases. To calculate three-month coupon payments after 2023, you must use a LIBOR fallback. This example is based on the ISDA® 2020 IBOR Fallbacks Protocol.
%% Spread Adjustments
% Use spread adjustments from the ISDA® website at LIBOR Cessation and the Impact on Fallbacks Protocol.

Adjustment = [.00644 .03839 .11448 .18456 .26161 .42826 .71513]'/100;
TenorLabel = ["ON","1W","1M","2M","3M","6M","12M"]';
Tenors = [caldays(1) calweeks(1) calmonths([1 2 3 6 12])];
SpreadAdjustmentTable = table(TenorLabel,Adjustment);
nTenors = height(SpreadAdjustmentTable);

%% Example Data
% Run this example using the following example data.

RateRecordDate = datetime(2021,2,26);
RateTenor = "1M";
ARR_DC = 360;

%% Obtain Calculation Date
% Use RateRecordDate and Tenors to calculate CalculationDate.

CalculationDate = RateRecordDate + Tenors(RateTenor == TenorLabel);
if ~isbusday(CalculationDate)
    CalculationDate = busdate(CalculationDate);
end

%% Obtain Historical Data
% For this example, the historical data is hard-coded. However, you can also use Datafeed Toolbox™ with Federal Reserve Economic Data (FRED®) to obtain the historical data.

getFredData = false;
if getFredData
    ARR_ID = 'SOFR';
    c = fred;
    c.DataReturnFormat = 'timetable';
    c.DatetimeType = 'datetime';
    FredData = fetch(c,ARR_ID,RateRecordDate,CalculationDate);
    SOFRData = FredData.Data{1};
    SOFRData(isnan(SOFRData{:,1}),:) = [];
else
    SOFRRates = [0.01 0.02 0.04 0.04 0.02 0.02 0.02 0.02 0.02 0.01 ...
        0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01]';
    SOFRDates = busdays(RateRecordDate,CalculationDate);
    SOFRData = timetable(SOFRDates,SOFRRates);
end

%% Compute Spread Adjustment
% Obtain the spread adjustment from SpreadAdjustmentTable.

SpreadAdj = Adjustment(RateTenor == TenorLabel);

%% Compute ARR
% Compute the alternative reference rate (ARR) using the relevant reference rate data.

tau = days(diff(SOFRData.Properties.RowTimes))/ARR_DC;
relRate = SOFRData{1:end-1,1};
CompRate = prod(1 + tau.*1/100.*relRate) - 1;
ARR = ARR_DC/days(CalculationDate - RateRecordDate)*CompRate;
ARR = round(ARR,7);

%% Compute Fallback Rate
% FallbackRate is the sum of ARR and SpreadAdj.

FallbackRate = ARR + SpreadAdj

% Copyright 2021 The MathWorks, Inc.