Code covered by the BSD License  

Highlights from
Analyzing Investment Strategies with CVaR Portfolio Optimization

image thumbnail

Analyzing Investment Strategies with CVaR Portfolio Optimization

by

Bob Taylor

 

18 Dec 2012 (Updated )

Scripts and data to demonstrate the new PortfolioCVaR object in Financial Toolbox.

uncovered_engine(X, T, ...
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);
%
% Inputs:
%	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].
%	Costs/Frictions
%		stock_cost - Proportional cost to buy or sell stock [scalar].
%
% Outputs:
%	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].
%
% Comments:
%	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.

% initialization

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;
end

% 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);
	end
	
	% 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;
	end
	
	% update test variables
	if nargout > 2
		HU(iter) = current_shares;
		CU(iter) = current_cash;
		WU(iter) = current_cash + current_shares*current_price;
	end
end

% 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);
	end
end

% final scenario returns

rU = (current_cash + current_shares*X(end))/initial_wealth - 1;

Contact us