function PercentR = willpctr(varargin)
%WILLPCTR Williams PercentR (%R).
%
% Syntax: 
%
%   PercentR = willpctr(Data)
%   PercentR = willpctr(Data,NumPeriods)
%
% Description:
%
%   PercentR calculates the Williams PercentR (%R) values for a data series of
%   with high, low, and closing prices. By default, Williams PercentR values
%   are based on 14 periods.
%
% Input Argument:
%
%   Data    - A matrix, table, or timetable. For matrix input, Data is an 
%             M-by-3 matrix of high, low, and closing prices stored in the 
%             corresponding columns, respectively. Timetables and tables with M 
%             rows contain variables named 'High', 'Low', and 'Close' (case insensitive).
%
% Optional Input:
%
%  NumPeriods           - Positive integer scalar indicating the moving window
%                         for Williams PercentR. The default is 14.
%
% Output Argument:
%
%   PercentR     - Williams PercentR series with the same number of rows (M) 
%                  and type as the input data.
%
% Example:   
%              load SimulatedStock.mat
%              PercentR = willpctr(TMW);
%              PercentR = willpctr(TMW,14);
%
%   See also WILLAD, STOCHOSC.
%
%   Reference: Achelis, Steven B., Technical Analysis From A To Z,
%              Second Printing, McGraw-Hill, 1995, pg. 316-317

%   Copyright 1995-2018 The MathWorks, Inc.

%--------------------- Parse/Validation ----------------------------------%
numPeriodsValidate = @(x) validateattributes(x,{'numeric'}, {'scalar','integer','positive'},'','number of periods');
optionalValidate = {numPeriodsValidate};

try
    narginchk(1,Inf);
    output = internal.finance.ftseriesInputParser(varargin,3,{'high','low','close'},{},{}, ...
    {'NumPeriods'},{14},optionalValidate,0);
catch ME
    throwAsCaller(ME)
end

[data,optional,dates,datatypeFlag] = output{:};
highp = data(:,1);
lowp = data(:,2);
closep   = data(:, 3);
numPeriods = optional.NumPeriods;

% Check for data sufficiency.
numObs = length(highp);
validateattributes(numPeriods,{'numeric'},{'scalar','<=',numObs},'','number of periods');

%--------------------- Calculation ---------------------------------------%
llv = llow(lowp,numPeriods);
hhv = hhigh(highp,numPeriods);

% Calculate the Williams PercentR.
PercentR = -100 * (hhv-closep)./(hhv-llv) ;

% Handle denominator is 0 issue.
PercentR(isinf(PercentR)) = NaN;

%--------------------- Output Preparation --------------------------------%
switch datatypeFlag
    case 0 % double
        if ~isempty(dates)
            PercentR = [dates, PercentR];
        end
    case 1 % table
        PercentR = table(PercentR,'VariableNames',{'WillPercentR'});
        PercentR.Properties.Description = ...
            ['WillPercentR: ',varargin{1}.Properties.Description];
    case 2 % timetable
        PercentR = timetable(PercentR,'RowTimes',dates,'VariableNames',{'WillPercentR'});
        PercentR.Properties.Description = ...
            ['WillPercentR: ',varargin{1}.Properties.Description];
end

end