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.


[edit] Matlab Financial Plots

[edit] 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




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


generate a sampled exponential brownian motion

figure('Color',[0.9412 0.9412 0.9412 ]);
h1 = subplot(2,1,1); plot(T, S); 

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:

S_t = S_0 \exp\left(\mu - \frac{\sigma^2}{2}\right) t + \sigma W_t

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

[edit] 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'
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);






h = [h1; h2];

[edit] 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.

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

[edit] 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:

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);
        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);
        error('xdata:mode', 'unknown mode <%s>', mode);

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

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'),, 0);

[edit] Volumes

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

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_name = opt.get('volumes');
h2     = subplot(2,1,2, 'unit', 'normalized');
[x,y]  = barplot(, 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'));

[edit] 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.

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( max( ax(3:4)])

[edit] Labels

At the end I put some labels:

  • the title
  • the two ylabels (one fo each subplot)
title( data.title); ylabel('price');

[edit] Use this new simplecandleplot function

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

Now we just need to use it:



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.

[edit] External links

Download code