%%% octave 4.0.0 code   by Dario Gasbarra dario.gasbarra@helsinki.fi  21.3.2016
%%% it gives also the face values of the american option

## This program is free software; you can redistribute it and/or modify it under
## the terms of the GNU Lesser General Public License as published by the Free
## Software Foundation; either version 3 of the License, or (at your option) any
## later version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
## for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this program; if not, see <http://www.gnu.org/licenses/>.

## Computes the American call and put option prices using the
## Cox-Ross-Rubinstein binomial tree.
## @seealso {binprice,blkprice, blsprice}

function [AssetPrice, OptionValue, FaceValue] = binpriceFacevalue(Price, Strike,d,r,u,N,OptType )
  %%% OptType=1 for american call option, 
  %%  OptType=0 for american put option
  %%% the function returns at each node of the CRR binary tree
  %%% the price of the asset AssetPrice
  %%% the price of the american option
  %%% and the face value of the option 
  
  if ((d<= -1)||( r<=d)||(r>=u)||(u<d))
   fprintf('the model does not satisfy -1<d<r<u ')
  end
  
  if (nargin!=7)
    print_usage ();
  elseif (! isbool (OptType) && ! isequal (OptType, 0) && ...
          ! isequal (OptType, 1))
    error ("binprice: OPTTYPE must be logical, 0 (call) or 1 (put)");
  endif

  AssetPrice = OptionValue = FaceValue=zeros (N);
 
  ## Martingale measure
  a=(1+r);
  p = (r- d) / (u - d);
  q = 1 - p;

  ## Build tree
  AssetPrice(1, 1) = Price;
  for n = 2:N
    AssetPrice(1:(n - 1), n) = (1+u) * AssetPrice(1:(n - 1), n - 1);
    AssetPrice(n, n) = (1+d) * AssetPrice(n - 1, n - 1);
  endfor

  ## Initial condition
  opt = 2 * OptType - 1;
  FaceValue(:,N)=OptionValue(:, N) = max (opt * (AssetPrice(:, N) - Strike), 0);

  ## Time-stepping loop
  for n = (N - 1):-1:1
    HoldValue = (q * OptionValue(2:(n + 1), n + 1) + ...
                 p * OptionValue(1:n,       n + 1)) / a;
    FaceValue(1:n, n)=max( opt * (AssetPrice(1:n, n) - Strike),0.0);
    %OptionValue(1:n, n) = max (HoldValue, opt * (AssetPrice(1:n, n) - Strike));
   OptionValue(1:n, n) = max (HoldValue,FaceValue(1:n, n));
 endfor

endfunction

## Tests
%K= 60; S0 = 50; d=-0.1, r = 0.01, u=0.2, T = 10;
% [S,americancall, fv_americancall] = binpriceFacevalue(K,S0,d,r,u,T,0);
% [S,americanput, fv_americanput]= binpriceFacevalue(K,S0,r,sigma,Dt,T,1);

