function [rU, WU, CU, HU] = uncovered_engine(X, T, ...
initial_equity, distribution, risk_free_rate, stock_cost)
%uncovered_engine - Generate scenarios for an uncovered and a covered buy-write strategy.
% [rU, WU, CU, HU] = uncovered_engine(X, T, ...
% initial_equity, distribution, risk_free_rate, stock_cost);
% Stock Information
% X - Stock total return prices including initial price [scalar].
% T - Duration of investment period in years (terminal time - initial time) [scalar].
% Fund Details
% initial_equity - Initial (uncovered) total value of stock and cash held in asset [scalar].
% distribution - Annualized fund distribution [scalar].
% Other Details
% risk_free_rate - Annualized risk-free rate [scalar].
% stock_cost - Proportional cost to buy or sell stock [scalar].
% rU - Total return for uncovered strategy [scalar].
% WU - Sequence of total wealth for uncovered strategy [vector].
% CU - Sequence of cash for uncovered strategy [vector].
% HU - Sequence of holdings for uncovered strategy [vector].
% 1) This function generates scenarios for an uncovered portfolio strategy. To introduce some
% degree of "realism" into the model, several inputs can be specified to control the
% simulations. The next few comments provide additional details on these inputs.
% 2) X and T are stock total return prices and "times" in years that are assumed to be generated
% by a geometric Brownian motion process with stochastic differential equation in the form
% dX(t) = mu*X(t)*dt + volatility*X(t)*dB(t)
% for t > 0.
% Copyright (C) 2012 The MathWorks, Inc.
N = numel(X) - 1; % N is the number of samples in X excluding the initial price
tau = T/N; % tau is the time interval between samples in "years"
periods_per_day = floor(N/(252*T) + 0.5); % periods_per_day is number of periods in a "day"
% initial position
current_price = X(1); % initial price
current_time = 0; % initial time
current_shares = floor(initial_equity/current_price); % initial number of shares
current_cash = max(0, (initial_equity - current_shares*current_price)); % initial cash
initial_wealth = current_cash + current_shares*current_price;
% generate scenarios
% track shares, strike, cash, and wealth over time for testing
if nargout > 2
HU = zeros(N+1,1); % (H)oldings in stocks
CU = zeros(N+1,1); % (C)ash
WU = zeros(N+1,1); % (W)ealth
HU(1) = current_shares;
CU(1) = current_cash;
WU(1) = current_cash + current_shares*current_price;
% loop over investment period for uncovered strategy
for iter = 2:N+1
current_price = X(iter);
current_time = tau*(iter - 1);
% accrue interest on cash account at end of each day
if mod(iter, periods_per_day) == 1 % note that period 1 happens outside loop
current_cash = current_cash*(1 + risk_free_rate*tau*periods_per_day);
% buy more stock if enough cash available
if current_cash > (current_price + stock_cost)
adjusted_stock_price = current_price + stock_cost;
shares_purchased = floor(current_cash/adjusted_stock_price);
current_shares = current_shares + shares_purchased;
current_cash = current_cash - shares_purchased*adjusted_stock_price;
% update test variables
if nargout > 2
HU(iter) = current_shares;
CU(iter) = current_cash;
WU(iter) = current_cash + current_shares*current_price;
% at the end of the period, pay a distribution and sell shares if not enough cash
distribution = distribution*T;
needed_cash = distribution*(current_cash + current_shares*X(end)) - current_cash;
if needed_cash > 0
adjusted_stock_price = X(end) + stock_cost;
shares_sold = ceil(needed_cash/adjusted_stock_price);
current_shares = current_shares - shares_sold;
current_cash = current_cash + shares_sold*(X(end) - stock_cost);
if nargout > 2
HU(end) = current_shares;
CU(end) = current_cash;
WU(end) = current_cash + current_shares*X(end);
% final scenario returns
rU = (current_cash + current_shares*X(end))/initial_wealth - 1;