%% American put (example in class)

%%%%%%%%%%%%% Problem parameters %%%%%%%%%%%%%%
S0 = 20; u = 1.1; d = 0.9;
r = 0.1; dt = 7/365; % one month
q = (exp(r*dt)-d) / (u-d); % "risk-neutral probability"
E = 24; % strike
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

depth = 3;

disp('Stock price tree');

T = S0;
fprintf('%3.2f\n', T);

for j = 1:depth
    T = [T*d, T(end)*u];
    fprintf('%3.2f\t', T);
    fprintf('\n');
end

% Shortcut to the last level of the tree
T = S0 * d.^(depth - (0:depth)) .* u.^(0:depth);

% Calculate the option values at the last level
V = max(E-T, 0);

disp('American put value tree (reverse)');
disp(V);

for j = depth-1:-1:0
    V = exp(-r*dt) * ((1-q)*V(1:end-1) + q*V(2:end));
    T = S0 * d.^(j - (0:j)) .* u.^(0:j);
    fprintf('Level %d:\n', j);
    disp(round(100*[V; max(E-T, 0)])/100);
    V = max([V; max(E-T, 0)]);
end

fprintf('Answer: %3.2f\n', V);



%% Advanced Printout: Value of an option and its Delta

%%%%%%%%%%%%% Problem parameters %%%%%%%%%%%%%%
S0 = 15.0; u = 19/15; d = 14/15;
r = 0.05; dt = 1/12;
q = (exp(r*dt)-d) / (u-d); % "risk-neutral probability"
E = 18; % strike
% Payoff function
Payoff = @(S) max(E-S, 0);
% Style
American = true;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Things to try: compare Amer/Euro call, compare Amer/Eur put, set large
% strike in an Amer put

% Shortcut to the last level of the tree
T = S0 * d.^(depth - (0:depth)) .* u.^(0:depth);

% Calculate the option values at the last level
V = Payoff(T);

% Printout format
prec = '%.2f\t';

disp('Option value tree (reverse)');
disp('===========================');
fprintf('Level %d:\n', depth);
fprintf('SPrice:\t\t'); fprintf(prec, T); fprintf('\n');
fprintf('Payoff:\t\t'); fprintf(prec, V); fprintf('\n\n');

% Work back using risk-neutral probability
for j = depth-1:-1:0
    % Previous tree level
    Deltas = (V(2:end) - V(1:end-1)) ./ (T(2:end) - T(1:end-1));
    T = S0 * d.^(j - (0:j)) .* u.^(0:j);
    V = exp(-r*dt) * ((1-q)*V(1:end-1) + q*V(2:end));
    fprintf('Level %d:\n', j);
    fprintf('SPrice:\t\t'); fprintf(prec, T); fprintf('\n');
    if (American)
        fprintf('RecVal:\t\t'); fprintf(prec, V); fprintf('\n');
        fprintf('Payoff:\t\t'); fprintf(prec, Payoff(T)); fprintf('\n');
        V = max([V; Payoff(T)]);
    end
    fprintf('OValue:\t\t'); fprintf(prec, V); fprintf('\n');
    fprintf('ODelta:\t\t'); fprintf(prec, Deltas); fprintf('\n\n');
end

%% Advanced Printout: European put (notes example 2)

%%%%%%%%%%%%% Problem parameters %%%%%%%%%%%%%%
S0 = 100.0; u = 1.1; d = 0.9;
r = 0.05; dt = 1; L = 3;
q = (exp(r*dt)-d) / (u-d); % "risk-neutral probability"
E = 105; % strike
% Payoff function
Payoff = @(S) max(E-S, 0);
% Style
American = false;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Things to try: compare Amer/Euro call, compare Amer/Eur put, set large
% strike in an Amer put

% Shortcut to the last level of the tree
T = S0 * d.^(L - (0:L)) .* u.^(0:L);

% Calculate the option values at the last level
V = Payoff(T);

% Printout format
prec = '%.2f\t';

disp('Option value tree (reverse)');
disp('===========================');
fprintf('Level %d:\n', L);
fprintf('SPrice:\t\t'); fprintf(prec, T); fprintf('\n');
fprintf('Payoff:\t\t'); fprintf(prec, V); fprintf('\n\n');

% Work back using risk-neutral probability
for j = L-1:-1:0
    % Previous tree level
    Deltas = (V(2:end) - V(1:end-1)) ./ (T(2:end) - T(1:end-1));
    T = S0 * d.^(j - (0:j)) .* u.^(0:j);
    V = exp(-r*dt) * ((1-q)*V(1:end-1) + q*V(2:end));
    fprintf('Level %d:\n', j);
    fprintf('SPrice:\t\t'); fprintf(prec, T); fprintf('\n');
    if (American)
        fprintf('RecVal:\t\t'); fprintf(prec, V); fprintf('\n');
        fprintf('Payoff:\t\t'); fprintf(prec, Payoff(T)); fprintf('\n');
        V = max([V; Payoff(T)]);
    end
    fprintf('OValue:\t\t'); fprintf(prec, V); fprintf('\n');
    fprintf('ODelta:\t\t'); fprintf(prec, Deltas); fprintf('\n\n');
end
