% README: This is a Matlab function file to calculate 1-, 6- and 12-month
% trimmed mean inflation rates using the same methods as used to produce
% the Federal Reserve Bank of Dallas's trimmed mean PCE inflation rate. The
% function takes as inputs matrices of prices and quantities (described in
% more detail below) and outputs series of annualized 1-, 6- and 12-month
% inflation rates.
%
% The techniques are described in Dallas Fed Working Paper 0506 (2005). The
% Dallas Fed series are based on 178 underlying component series, publicly
% available from the BEA (Tables 2.4.4U, 2.4.5U, 2.4.6U). For a list of the
% 178 components, see here:
% http://www.dallasfed.org/-/media/Documents/research/pce/tech.pdf
%
% The function only calls on functions available in the core Matlab program
% (no toolboxes needed) and should run on any version of Matlab or, with
% minor modification, GNU-Octave.
function y = tmrates(P, Q, dates)
% INPUTS:
% P = T-by-k matrix of T prices for k components (from BEA Table 2.4.4U);
% Q = T-by-k matrix of real quantities (Table 2.4.6U);
% One can also use N./P for Q, where N = T-by-k matrix of nominal
% quantities (Table 2.4.5U);
% dates = OPTIONAL T-by-1 column of Excel dates.
% OUTPUT:
% y is T-by-3 matrix with columns consisting of 1-month rates,
% 6-month rates, and 12-month rates, with -9999's for the #N/A's at the
% beginning of each column (e.g., the column of 6-month rates begins with
% 6 entries of -9999 before the first value in the series).
% Calculate trimmed mean series, with trimming proportions alpha = 24%,
% beta = 31% (assuming you want to replicate the Dallas Fed series). Here
% we call the function trimpce, defined below, to do this:
dptrim = trimpce(P,Q,24,31);
% Cumulate dptrim to get an index series starting at a value of 100:
ptrim = [100;zeros(size(dptrim))];
for t = 1:length(dptrim);
ptrim(t+1) = (1+dptrim(t))*ptrim(t);
end;
% If dates provided AND dates include Jan-2009, normalize index series to
% January 2009 = 100. If no dates or if dates don't include Jan-2009, then
% t = 1 stays normalized to 100 (as it was formed above).
%
% The normalization to Jan-2009 = 100 is inessential, and simply follows
% BEA's normalizations of 2009 = 100. If one added ptrim (the index series)
% to the list of function outputs, then normalizing it to 2009 = 100 would
% produce a series more directly comparable to BEA's published PCE price
% indices.
%
% Check to see if dates argument is provided:
if nargin==3;
% Matlab datenumbers and Excel datenumbers differ by a constant. The
% Matlab year corresponding to an Excel datenumber for 2009 is 109.
d = datevec(dates);
t0 = find(d(:,1)==109,1,'first');
% Normalize only if Jan-2009 is in dates:
if ~isempty(t0) && d(t0,2)==1;
ptrim = 100*ptrim/ptrim(t0);
end
end
% Calculate annualized 1-mo, 6-mo and 12-mo rates:
dpt_1mo = 100*((ptrim(2:end,:)./ptrim(1:end-1,:)).^12 - 1);
dpt_6mo = 100*((ptrim(7:end,:)./ptrim(1:end-6,:)).^2 - 1);
dpt_12mo = 100*((ptrim(13:end,:)./ptrim(1:end-12,:)) - 1);
% Pad with -9999's at the top so all series have length T:
dpt_1mo = [-9999; dpt_1mo];
dpt_6mo = [-9999*ones(6,1); dpt_6mo];
dpt_12mo = [-9999*ones(12,1); dpt_12mo];
% Arrange output to place back in Excel:
y = [dpt_1mo, dpt_6mo, dpt_12mo];
end
% These are the sub-function files called above and, really, do all the
% heavy lifting:
function [dp, trimpts] = trimpce(P,Q,lt,ut)
% TRIMPCE.M - Calculates trimmed or median PCE
% given data P and Q and trim points lt, ut.
% Syntax: [p, trimpts] = trimpce(P,Q,lt,ut);
% Trim points are in percent.
% Formula for the weights is detailed in Dallas Fed WP#0506.
[nr,nc] = size(P);
% Here we just form some matrices of zeros that will be filled in with
% values in the steps below:
dp = zeros(nr-1,1);
trimpts = zeros(nr-1,2);
dP = zeros(nr-1,nc);
wts1 = zeros(nr-1,nc);
wts2 = zeros(nr-1,nc);
wts = zeros(nr-1,nc);
% This loop calculates component price changes and puts together the
% weights for the aggregation.
for t = 2:nr;
dP(t-1,:) = (P(t,:)-P(t-1,:))./P(t-1,:);
wts1(t-1,:) = (Q(t,:).*P(t-1,:))/(Q(t,:)*P(t-1,:)');
wts2(t-1,:) = (Q(t-1,:).*P(t-1,:))/(Q(t-1,:)*P(t-1,:)');
wts(t-1,:) = .5*wts1(t-1,:) + .5*wts2(t-1,:);
wts(t-1,:) = wts(t-1,:)/sum(wts(t-1,:));
end;
% Given the matrix of price changes dP, the weights wts, and the
% trimming points lt and ut, the function mytrim (defined below)
% calculates the trimmed mean rate for each month as well as the price
% change rates for the items at the two cut-off points:
for t = 1:(nr-1);
[dp(t), trimpts(t,:)] = mytrim(dP(t,:),wts(t,:),lt,ut);
trimpts(t,:) = [dP(t,trimpts(t,1)),dP(t,trimpts(t,2))];
end;
end
function [m, trimpt] = mytrim(x,prob,lt,ut)
% MYTRIM.M - Function to calculate trimmed mean
% of data x distributed according to weights (or
% probabilities) prob.
% Syntax: [m, trimpt] = mytrim2(x,prob,lt,ut);
[x1,ind] = sort(x);
prob1 = prob(ind);
c = cumsum(prob1);
K = length(x1);
I = 1:K;
t1 = min(I(c>=lt/100));
t2 = min(I(c>=1-ut/100));
if isempty(t2);
t2 = K;
end;
if t2-t1==0;
m = x1(t1);
elseif t2-t1==1;
m = ((c(t1)-lt/100)*x1(t1) + (1-ut/100-c(t2-1))*x1(t2))/(1-lt/100-ut/100);
else
m = (c(t1)-lt/100)*x1(t1) + sum(prob1(t1+1:t2-1).*x1(t1+1:t2-1))+ (1-ut/100-c(t2-1))*x1(t2);
m = m/(1-lt/100 - ut/100);
end;
trimpt = ind([t1 t2]);
end