MATLAB Financial Toolbox

From LiteratePrograms

Jump to: navigation, search

The Matlab Financial Toolbox provide some code dedicated to financial computations and plotting.

We can discuss here of some of them.

Contents

Matlab Financial Plots

Candle sticks and high low graphs

The |candle| function of matlab is poor, first you cannot change its color, and then it does not provide a way to plot volumes on the same figure. Here is a simple attempt to obtain a rich candle stick (or high/low) graph.

First you need to patch the Matlab candle function. It's quite simple: just change the line 66 from

plot(indhilo(:),hilo(:));

to

plot(indhilo(:),hilo(:),'color',color);

To test your new candle function, you can try the following code:

<<test_candle.m>>=
generate a sampled exponential brownian motion
figure('Color',[0.9412 0.9412 0.9412 ]);
h1 = subplot(2,1,1); plot(T, S); 
datetick('x',6,'keeplimits');
generate volumes
generate a structured dataset
h2 = subplot(2,1,2);
candle(Sohlc(:,2), Sohlc(:,3), Sohlc(:,4), Sohlc(:,1), [.5 0 0], t, 6)
linkaxes([h1, h2], 'x');

Using those 3 codeblocks:

  • Generation of an exponential brownian motion

As you know, such a stochastic process (dS = Sμdt + SσdW) has an explicit solution when μ and σ are constants:

you have to be sure to scale your volatility σ and your riskless rate μ (here one point is one day).

Then the sampling process is to have one point every ten days (of course to be more reallistic we could use one point is one minute and take one point every 510 minutes, i.e. 8h30), and to keep the first point, last point, max and min.

<<generate a sampled exponential brownian motion>>=
sgm = 0.23 / sqrt(250);
mu  = (1+ 0.04)^(1/250)-1;
S0  = 100;
nb  = 1000;
sam = 10;
T   = 1+(1:nb)'/250;
S   = S0 * exp( (mu-sgm^2/2)*T + sgm * cumsum(randn(nb,1)));
Soc   = [S(1:sam:end-1), S(sam-1:sam:end-1)];
Shl   = [max(reshape(S, sam, length(S)/sam)); min(reshape(S, sam, length(S)/sam))];
Sohlc = [Soc(:,1), Shl', Soc(:,2)];
t     = T(ceil(sam/2):sam:end-1);
  • Generation of the volumes

You can guess the volumes are log-normal and i.i.d.

<<generate volumes>>=
volumes = ceil(exp( randn(length(Sohlc),1) + 7))+100;
  • Structured dataset

Of course you know that's better to use stuctured datasets in Matlab, so let's keep all you simulations into such a structure:

<<generate a structured dataset>>=
data    = struct('title', 'exp brownian motion', 'value', [Sohlc, volumes], ...
                 'names', {{'open', 'high', 'low', 'close', 'volume'}}, 'date', t);

A custom candleplot function

Now we can use the patched candle Matlab function and a more simple plot function to have a classic combination candle + volumes.

We will use the |options| function which can be found in the Swiss army knife Matlab programs for quantitative finance article.

Its optional arguments are:

  • 'figure' - to give an handle to an existing figure or empty (new figure)
  • 'prop' - proportion of the figure dedicated to the volumes
  • 'candles-color', 'volumes-color', 'volumes-linewidth' - eponyms
  • 'date-format' - from datestr
  • 'mode' - 'candle' (default) or 'highlow'
<<simplecandleplot.m>>=
function h = simplecandleplot(data, varargin)
% CANDLEPLOT - candleplot with volumes
%
% use
%  h = simplecandleplot( data, 'prices', 'open;high;low;close', 'volumes', 'volume', options ... )
% options:
%  'figure' - handle or empty (new figure)
%  'prop'   - proportion of the figure dedicated to the volumes
%  'candles-color', 'volumes-color', 'volumes-linewidth' - eponyms
%  'date-format' - from datestr
%  'mode'   - 'candle' (default) or 'highlow'
%
% example
%  data = xdata('rload', 'bdata-test');
%  candleplot(data, 'prices', 'Open;High;Low;Last', 'volumes', 'Volume', 'dates-format', 13)
%
% See also pdates datestr xdata 
opt = options({'prices', '', 'volumes', '', 'figure', [], 'prop', .2, ...
               'candles-color', [0 .5 .5], 'volumes-color', [0 .5 .5], ...
               'volumes-linewidth', 3, 'dates-format', 2, 'mode', 'candle'}, varargin);
Figure
Prices
Volumes
Positions
Labels
h = [h1; h2];

Figure

that's a simple code to be able to give to the function a handle to an existing figure if we do not want to create a new one.

<<Figure>>=
f = opt.get('figure');
if isempty(f) || ~ishandle(f)
    f = figure('Color',[0.9412 0.9412 0.9412 ]);
else
    figure(f);
end

Prices

Just extract and plot the prices, in this article the |xdata| function is only used to extract a column of a structured dataset, let's implement it:

<<xdata.m>>=
function out = xdata(mode, varargin)
% XDATA - simplest xdata function
% use:
%  val = xdata('get-col', structured_data, names)
switch lower(mode)
    case 'get-col'
        data  = varargin{1};
        names = varargin{2};
        if ~iscell(names)
            names =  regexp(names, '([^;]+)', 'tokens');
            names = cellfun(@(x)(x{1}),names,'UniformOutput', false);
        end
        out = repmat(nan,size(data.value,1),length(names));
        for i=1:length(names)
            idx   = strmatch(names{i}, data.names, 'exact');
            out(:,i) = data.value(:,idx);
        end
    otherwise
        error('xdata:mode', 'unknown mode <%s>', mode);
end

the call to |feval| allow to use othe functions to plot prices (as the |highlow| MAtlab Financial Toolbox built-in function).

<<Prices>>=
prices_names = opt.get('prices');
prices = xdata('get-col', data, prices_names);
h1     = subplot(2,1,1, 'unit', 'normalized');
feval( opt.get('mode') ,  prices(:,2), prices(:,3), prices(:,4), prices(:,1), opt.get('candles-color'), data.date, 0);

Volumes

Extraction and plot of the volumes, here I need a custom |barplot| function, which is very simple:

<<barplot.m>>=
function [xs, ys] = barplot(x,y,varargin)
% BARPLOT - computes new x and y (with nans) for bar plottings
% options:
% - level: 0*
% use:
% [xs, ys] = barplot(x,y,options);
%
% See also moustacheplot 
opt = getopt('init',{'level',0},varargin);
level = getopt('get',opt,'level');
xs = repmat(nan,3*length(x),1);
xs(1:3:length(xs)) = x;
xs(2:3:length(xs)) = x;
ys = repmat(nan,3*length(y),1);
ys(1:3:length(ys)) = y;
ys(2:3:length(ys)) = level;
<<Volumes>>=
volumes_name = opt.get('volumes');
h2     = subplot(2,1,2, 'unit', 'normalized');
[x,y]  = barplot(data.date, xdata('get-col', data, volumes_name));
plot(x,y, 'color', opt.get('volumes-color'), 'linewidth', opt.get('volumes-linewidth'));
dateaxis('X', opt.get('dates-format'));

Positions

Then I need to adjust the relative size of the two subplot. At this stage the two subplots (one for the prices and the other for the volumes) are of the same size, now I will use the optional parameter 'prop' (as proportion) to adjust their relative sizes.

<<Positions>>=
p1 = get(h1, 'position');
p2 = get(h2, 'position');
c  = opt.get('prop');
dp2  = p1(2) - (p2(2)+p2(4));
np24 = p2(4)*c + dp2;
np14 = p1(4) + p2(4) * (1-c);
np12 = p1(2) - p2(4) * (1-c);
set(h1, 'position', [p1(1) np12  p1(3) np14]);
set(h2, 'position', [p1(1) p2(2) p1(3) np24]);
linkaxes([h1;h2], 'x');
ax = axis(h2);
axis(h2, [min(data.date) max(data.date) ax(3:4)])

Labels

At the end I put some labels:

  • the title
  • the two ylabels (one fo each subplot)
<<Labels>>=
axes(h1); 
title( data.title); ylabel('price');
axes(h2); 
ylabel('volume');

Use this new simplecandleplot function

Enlarge
use of the simplecandleplot function
Enlarge
the simplecandleplot function in the highlow mode

Now we just need to use it:

<<test_simplecandle.m>>=
test_candle.m
simplecandleplot( data, 'prices', 'open;high;low;close', 'volumes', 'volume')
simplecandleplot( data, 'prices', 'open;high;low;close', 'volumes', 'volume', 'mode', 'highlow')

And you can try to change the options as in:

simplecandleplot( data, 'prices', 'open;high;low;close', 'volumes', 'volume', 'volumes-color', [.5 0 0])

or in:

 simplecandleplot( data, 'prices', 'open;high;low;close', 'volumes', 'volume', 'prop', .4)

of course we always have here the dateaxis problem (ugly effects), but you can use the real dateticks to change this.

External links

  • Official page of the Matlab Financial Toolbox
Download code
Views