A financial time series object is used as if it were a MATLAB^{®} structure. (See the MATLAB documentation for a description of MATLAB structures or how to use MATLAB in general.)
This part of the tutorial assumes that you know how to use MATLAB and are familiar with MATLAB structures. The terminology is similar to that of a MATLAB structure. The financial time series object term component is interchangeable with the MATLAB structure term field.
A financial time series object always contains three component
names: desc
(description field), freq
(frequency
indicator field), and dates
(date vector). If you
build the object using the constructor fints
,
the default value for the description field is
a blank string (''
). If you build the object from
a text data file using ascii2fts
,
the default is the name of the text data file. The default for the
frequency indicator field is 0
(Unknown
frequency).
Objects created from operations can default the setting to 0
.
For example, if you decide to pick out values selectively from an
object, the frequency of the new object might not be the same as that
of the object from which it came.
The date vector dates
does not have a default set
of values. When you create an object, you have to supply the date
vector. You can change the date vector afterward but, at object creation
time, you must provide a set of dates.
The final component of a financial time series object is one
or more data series vectors. If you do not supply a name for the data series,
the default name is series1
. If you have multiple
data series in an object and do not supply the names, the default
is the name series followed by a number, for example, series1
, series2
,
and series3
.
Here is an exercise on how to extract data from a financial time series object. As mentioned before, you can think of the object as a MATLAB structure. Highlight each line in the exercise in the MATLAB Help browser, press the right mouse button, and select Evaluate Selection to execute it.
To begin, create a financial time series object called myfts
:
dates = (datenum('05/11/99'):datenum('05/11/99')+100)'; data_series1 = exp(randn(1, 101))'; data_series2 = exp(randn(1, 101))'; data = [data_series1 data_series2]; myfts = fints(dates, data);
The myfts
object looks like this:
myfts = desc: (none) freq: Unknown (0) 'dates: (101)' 'series1: (101)' 'series2: (101)' '11-May-1999' [ 2.8108] [ 0.9323] '12-May-1999' [ 0.2454] [ 0.5608] '13-May-1999' [ 0.3568] [ 1.5989] '14-May-1999' [ 0.5255] [ 3.6682] '15-May-1999' [ 1.1862] [ 5.1284] '16-May-1999' [ 3.8376] [ 0.4952] '17-May-1999' [ 6.9329] [ 2.2417] '18-May-1999' [ 2.0987] [ 0.3579] '19-May-1999' [ 2.2524] [ 3.6492] '20-May-1999' [ 0.8669] [ 1.0150] '21-May-1999' [ 0.9050] [ 1.2445] '22-May-1999' [ 0.4493] [ 5.5466] '23-May-1999' [ 1.6376] [ 0.1251] '24-May-1999' [ 3.4472] [ 1.1195] '25-May-1999' [ 3.6545] [ 0.3374]...
There are more dates in the object; only the first few lines are shown here.
Note
The actual data in your |
Now create another object with only the values for series2
:
srs2 = myfts.series2
srs2 = desc: (none) freq: Unknown (0) 'dates: (101)' 'series2: (101)' '11-May-1999' [ 0.9323] '12-May-1999' [ 0.5608] '13-May-1999' [ 1.5989] '14-May-1999' [ 3.6682] '15-May-1999' [ 5.1284] '16-May-1999' [ 0.4952] '17-May-1999' [ 2.2417] '18-May-1999' [ 0.3579] '19-May-1999' [ 3.6492] '20-May-1999' [ 1.0150] '21-May-1999' [ 1.2445] '22-May-1999' [ 5.5466] '23-May-1999' [ 0.1251] '24-May-1999' [ 1.1195] '25-May-1999' [ 0.3374]...
The new object srs2
contains all the dates
in myfts
, but the only data series is series2
.
The name of the data series retains its name from the original object, myfts
.
Note The output from referencing a data series field or indexing a financial time series object is always another financial time series object. The exceptions are referencing the description, frequency indicator, and dates fields, and indexing into the dates field. |
The function fts2mat
extracts
the dates and/or the data series values from an object and places
them into a vector or a matrix. The default behavior extracts just
the values into a vector or a matrix. Look at the next example:
srs2_vec = fts2mat(myfts.series2)
srs2_vec = 0.9323 0.5608 1.5989 3.6682 5.1284 0.4952 2.2417 0.3579 3.6492 1.0150 1.2445 5.5466 0.1251 1.1195 0.3374...
If you want to include the dates in the output matrix, provide
a second input argument and set it to 1
. This results
in a matrix whose first column is a vector of serial date numbers:
format long g srs2_mtx = fts2mat(myfts.series2, 1)
srs2_mtx = 730251 0.932251754559576 730252 0.560845677519876 730253 1.59888712183914 730254 3.6681500883527 730255 5.12842215360269 730256 0.49519254119977 730257 2.24174134286213 730258 0.357918065917634 730259 3.64915665824198 730260 1.01504236943148 730261 1.24446420606078 730262 5.54661849025711 730263 0.12507959735904 730264 1.11953883096805 730265 0.337398214166607
The vector srs2_vec
contains series2
values.
The matrix srs2_mtx
contains dates in the first
column and the values of the series2
data series
in the second. Dates in the first column are in serial date format.
Serial date format is a representation of the date string format (for
example, serial date = 1 is equivalent to 01-Jan-0000). (The serial
date vector can include time-of-day information.)
The long g
display format displays the numbers
without exponentiation. (To revert to the default display format,
use format short
. (See the format
command
in the MATLAB documentation for a description of MATLAB display
formats.) Remember that both the vector and the matrix have 101 rows
of data as in the original object myfts
but are
shown truncated here.
You can also index into the object as with any other MATLAB variable
or structure. A financial time series object lets you use a date string, a cell array of date strings, a date string range, or
normal integer indexing. You
cannot, however, index into the object using serial dates. If you have
serial dates, you must first use the MATLAB datestr
command to convert them into date strings.
When indexing by date string, note that
Each date string must contain the day, month, and year. Valid formats are
'ddmmmyy hh:mm'
or 'ddmmmyyyy
hh:mm'
'mm/dd/yy hh:mm'
or 'mm/dd/yyyy
hh:mm'
'dd-mmm-yy hh:mm'
or 'dd-mmm-yyyy
hh:mm'
'mmm.dd,yy hh:mm'
or 'mmm.dd,yyyy
hh:mm'
All data falls at the end of the indicated time period, that is, weekly data falls on Fridays, monthly data falls on the end of each month, and so on, whenever the data has gone through a frequency conversion.
With date string indexing, you get the values in a financial time series object for a specific date using a date string as the index into the object. Similarly, if you want values for multiple dates in the object, you can put those date strings into a cell array and use the cell array as the index to the object. Here are some examples.
This example extracts all values for May 11, 1999 from myfts
:
format short myfts('05/11/99')
ans = desc: (none) freq: Unknown (0) 'dates: (1)' 'series1: (1)' 'series2: (1)' '11-May-1999' [ 2.8108] [ 0.9323]
The next example extracts only series2
values
for May 11, 1999 from myfts
:
myfts.series2('05/11/99')
ans = desc: (none) freq: Unknown (0) 'dates: (1)' 'series2: (1)' '11-May-1999' [ 0.9323]
The third example extracts all values for three different dates:
myfts({'05/11/99', '05/21/99', '05/31/99'})
ans = desc: (none) freq: Unknown (0) 'dates: (3)' 'series1: (3)' 'series2: (3)' '11-May-1999' [ 2.8108] [ 0.9323] '21-May-1999' [ 0.9050] [ 1.2445] '31-May-1999' [ 1.4266] [ 0.6470]
The next example extracts only series2
values
for the same three dates:
myfts.series2({'05/11/99', '05/21/99', '05/31/99'})
ans = desc: (none) freq: Unknown (0) 'dates: (3)' 'series2: (3)' '11-May-1999' [ 0.9323] '21-May-1999' [ 1.2445] '31-May-1999' [ 0.6470]
A financial time series is unique because it allows you to index
into the object using a date string range. A
date string range consists of two date strings separated by two colons
(::
). In MATLAB this separator is called the
double-colon operator. An example of a MATLAB date string range is '05/11/99::05/31/99'
.
The operator gives you all data points available between those dates,
including the start and end dates.
Here are some date string range examples:
myfts ('05/11/99::05/15/99')
ans = desc: (none) freq: Unknown (0) 'dates: (5)' 'series1: (5)' 'series2: (5)' '11-May-1999' [ 2.8108] [ 0.9323] '12-May-1999' [ 0.2454] [ 0.5608] '13-May-1999' [ 0.3568] [ 1.5989] '14-May-1999' [ 0.5255] [ 3.6682] '15-May-1999' [ 1.1862] [ 5.1284]
myfts.series2('05/11/99::05/15/99')
ans = desc: (none) freq: Unknown (0) 'dates: (5)' 'series2: (5)' '11-May-1999' [ 0.9323] '12-May-1999' [ 0.5608] '13-May-1999' [ 1.5989] '14-May-1999' [ 3.6682] '15-May-1999' [ 5.1284]
As with any other MATLAB variable or structure, you can assign the output to another object variable:
nfts = myfts.series2('05/11/99::05/20/99');
nfts
is the same as ans
in
the second example.
If one of the dates does not exist in the object, an error message
indicates that one or both date indexes are out of the range of the
available dates in the object. You can either display the contents
of the object or use the command ftsbound
to determine the first and last
dates in the object.
Integer indexing is the normal form of indexing in MATLAB.
Indexing starts at 1
(not 0
);
index = 1
corresponds to the first element, index
= 2
to the second element, index = 3
to
the third element, and so on. Here are some examples with and without
data series reference.
Get the first item in series2
:
myfts.series2(1)
ans = desc: (none) freq: Unknown (0) 'dates: (1)' 'series2: (1)' '11-May-1999' [ 0.9323]
Get the first, third, and fifth items in series2
:
myfts.series2([1, 3, 5])
ans = desc: (none) freq: Unknown (0) 'dates: (3)' 'series2: (3)' '11-May-1999' [ 0.9323] '13-May-1999' [ 1.5989] '15-May-1999' [ 5.1284]
Get items 16 through 20 in series2
:
myfts.series2(16:20)
ans = desc: (none) freq: Unknown (0) 'dates: (5)' 'series2: (5)' '26-May-1999' [ 0.2105] '27-May-1999' [ 1.8916] '28-May-1999' [ 0.6673] '29-May-1999' [ 0.6681] '30-May-1999' [ 1.0877]
Get items 16 through 20 in the financial time series object myfts
:
myfts(16:20)
ans = desc: (none) freq: Unknown (0) 'dates: (5)' 'series1: (5)' 'series2: (5)' '26-May-1999' [ 0.7571] [ 0.2105] '27-May-1999' [ 1.2425] [ 1.8916] '28-May-1999' [ 1.8790] [ 0.6673] '29-May-1999' [ 0.5778] [ 0.6681] '30-May-1999' [ 1.2581] [ 1.0877]
Get the last item in myfts
:
myfts(end)
ans = desc: (none) freq: Unknown (0) 'dates: (1)' 'series1: (1)' 'series2: (1)' '19-Aug-1999' [ 1.4692] [ 3.4238]
This example uses the MATLAB special variable end
, which points to the last element of the
object when used as an index. The example returns an object whose
contents are the values in the object myfts
on
the last date entry.
Both integer and date string indexing are permitted when time-of-day
information is present in the financial time series object. You can
index into the object with both date and time specifications, but
not with time of day alone. To show how indexing works with time-of-day
data present, create a financial time series object called timeday
containing
a time specification:
dates = ['01-Jan-2001';'01-Jan-2001'; '02-Jan-2001'; ... '02-Jan-2001'; '03-Jan-2001';'03-Jan-2001']; times = ['11:00';'12:00';'11:00';'12:00';'11:00';'12:00']; dates_times = cellstr([dates, repmat(' ',size(dates,1),1),... times]); timeday = fints(dates_times,(1:6)',{'Data1'},1,'My first FINTS') timeday = desc: My first FINTS freq: Daily (1) 'dates: (6)' 'times: (6)' 'Data1: (6)' '01-Jan-2001' '11:00' [ 1] ' " ' '12:00' [ 2] '02-Jan-2001' '11:00' [ 3] ' " ' '12:00' [ 4] '03-Jan-2001' '11:00' [ 5] ' " ' '12:00' [ 6]
Use integer indexing to extract the second and third data items
from timeday
:
timeday(2:3) ans = desc: My first FINTS freq: Daily (1) 'dates: (2)' 'times: (2)' 'Data1: (2)' '01-Jan-2001' '12:00' [ 2] '02-Jan-2001' '11:00' [ 3]
For date string indexing, enclose the date and time string in
one pair of quotation marks. If there is one date with multiple times,
indexing with only the date returns the data for all the times for
that specific date. For example, the command timeday('01-Jan-2001')
returns
the data for all times on January 1, 2001:
ans = desc: My first FINTS freq: Daily (1) 'dates: (2)' 'times: (2)' 'Data1: (2)' '01-Jan-2001' '11:00' [ 1] ' " ' '12:00' [ 2]
You can also indicate a specific date and time:
timeday('01-Jan-2001 12:00')
ans = desc: My first FINTS freq: Daily (1) 'dates: (1)' 'times: (1)' 'Data1: (1)' '01-Jan-2001' '12:00' [ 2]
Use the double-colon operator ::
to specify
a range of dates and times:
timeday('01-Jan-2001 12:00::03-Jan-2001 11:00')
ans = desc: My first FINTS freq: Daily (1) 'dates: (4)' 'times: (4)' 'Data1: (4)' '01-Jan-2001' '12:00' [ 2] '02-Jan-2001' '11:00' [ 3] ' " ' '12:00' [ 4] '03-Jan-2001' '11:00' [ 5]
Treat timeday
as a MATLAB structure
if you want to obtain the contents of a specific field. For example,
to find the times of day included in this object, enter
datestr(timeday.times)
ans = 11:00 AM 12:00 PM 11:00 AM 12:00 PM 11:00 AM 12:00 PM
Several MATLAB functions have been overloaded to work with financial time series objects. The overloaded functions include basic arithmetic functions such as addition, subtraction, multiplication, and division and other functions such as arithmetic average, filter, and difference. Also, specific methods have been designed to work with the financial time series object. For a list of functions grouped by type, enter
help ftseries
at the MATLAB command prompt.
Financial time series objects permit you to do addition, subtraction, multiplication, and division, either on the entire object or on specific object fields. This is a feature that MATLAB structures do not allow. You cannot do arithmetic operations on entire MATLAB structures, only on specific fields of a structure.
You can perform arithmetic operations on two financial time series objects as long as they are compatible. (All contents are the same except for the description and the values associated with the data series.)
Note Compatible time series are not the same as equal time series. Two time series objects are equal when everything but the description fields are the same. |
Here are some examples of arithmetic operations on financial time series objects.
Load a MAT-file that contains some sample financial time series objects:
load dji30short
One of the objects in dji30short
is called myfts1
:
myfts1 = desc: DJI30MAR94.dat freq: Daily (1) 'dates: (20)' 'Open: (20)' 'High: (20)' 'Low: (20)' 'Close: (20)' '04-Mar-1994' [ 3830.90] [ 3868.04] [ 3800.50] [ 3832.30] '07-Mar-1994' [ 3851.72] [ 3882.40] [ 3824.71] [ 3856.22] '08-Mar-1994' [ 3858.48] [ 3881.55] [ 3822.45] [ 3851.72] '09-Mar-1994' [ 3853.97] [ 3874.52] [ 3817.95] [ 3853.41] '10-Mar-1994' [ 3852.57] [ 3865.51] [ 3801.63] [ 3830.62]...
Create another financial time series object that is identical
to myfts1
:
newfts = fints(myfts1.dates, fts2mat(myfts1)/100,... {'Open','High','Low', 'Close'}, 1, 'New FTS')
newfts = desc: New FTS freq: Daily (1) 'dates: (20)' 'Open: (20)' 'High: (20)' 'Low: (20)' 'Close:(20)' '04-Mar-1994' [ 38.31] [ 38.68] [ 38.01] [ 38.32] '07-Mar-1994' [ 38.52] [ 38.82] [ 38.25] [ 38.56] '08-Mar-1994' [ 38.58] [ 38.82] [ 38.22] [ 38.52] '09-Mar-1994' [ 38.54] [ 38.75] [ 38.18] [ 38.53] '10-Mar-1994' [ 38.53] [ 38.66] [ 38.02] [ 38.31]...
Perform an addition operation on both time series objects:
addup = myfts1 + newfts
addup = desc: DJI30MAR94.dat freq: Daily (1) 'dates: (20)' 'Open: (20)' 'High: (20)' 'Low: (20)' 'Close: (20)' '04-Mar-1994' [ 3869.21] [ 3906.72] [ 3838.51] [ 3870.62] '07-Mar-1994' [ 3890.24] [ 3921.22] [ 3862.96] [ 3894.78] '08-Mar-1994' [ 3897.06] [ 3920.37] [ 3860.67] [ 3890.24] '09-Mar-1994' [ 3892.51] [ 3913.27] [ 3856.13] [ 3891.94] '10-Mar-1994' [ 3891.10] [ 3904.17] [ 3839.65] [ 3868.93]...
Now, perform a subtraction operation on both time series objects:
subout = myfts1 - newfts
subout = desc: DJI30MAR94.dat freq: Daily (1) 'dates: (20)' 'Open: (20)' 'High: (20)' 'Low: (20)' 'Close: (20)' '04-Mar-1994' [ 3792.59] [ 3829.36] [ 3762.49] [ 3793.98] '07-Mar-1994' [ 3813.20] [ 3843.58] [ 3786.46] [ 3817.66] '08-Mar-1994' [ 3819.90] [ 3842.73] [ 3784.23] [ 3813.20] '09-Mar-1994' [ 3815.43] [ 3835.77] [ 3779.77] [ 3814.88] '10-Mar-1994' [ 3814.04] [ 3826.85] [ 3763.61] [ 3792.31]...
You can also perform operations involving a financial time series object and a matrix or scalar:
addscalar = myfts1 + 10000
addscalar = desc: DJI30MAR94.dat freq: Daily (1) 'dates: (20)' 'Open: (20)' 'High: (20)' 'Low: (20)' 'Close: (20)' '04-Mar-1994' [ 13830.90] [ 13868.04] [ 13800.50] [ 13832.30] '07-Mar-1994' [ 13851.72] [ 13882.40] [ 13824.71] [ 13856.22] '08-Mar-1994' [ 13858.48] [ 13881.55] [ 13822.45] [ 13851.72] '09-Mar-1994' [ 13853.97] [ 13874.52] [ 13817.95] [ 13853.41] '10-Mar-1994' [ 13852.57] [ 13865.51] [ 13801.63] [ 13862.70]...
For operations with both an object and a matrix, the size of
the matrix must match the size of the object. For example, a matrix
to be subtracted from myfts1
must be 20
-by-4
,
since myfts1
has 20 dates and 4 data series:
submtx = myfts1 - randn(20, 4)
submtx = desc: DJI30MAR94.dat freq: Daily (1) 'dates: (20)' 'Open: (20)' 'High: (20)' 'Low: (20)' 'Close: (20)' '04-Mar-1994' [ 3831.33] [ 3867.75] [ 3802.10] [ 3832.63] '07-Mar-1994' [ 3853.39] [ 3883.74] [ 3824.45] [ 3857.06] '08-Mar-1994' [ 3858.35] [ 3880.84] [ 3823.51] [ 3851.22] '09-Mar-1994' [ 3853.68] [ 3872.90] [ 3816.53] [ 3851.92] '10-Mar-1994' [ 3853.72] [ 3866.20] [ 3802.44] [ 3831.17]...
Arithmetic operations on two objects that have the same size
but contain different data series names require the function fts2mat
. This function extracts the values
in an object and puts them into a matrix or vector, whichever is appropriate.
To see an example, create another financial time series object
the same size as myfts1
but with different values
and data series names:
newfts2 = fints(myfts1.dates, fts2mat(myfts1/10000),... {'Rat1','Rat2', 'Rat3','Rat4'}, 1, 'New FTS')
If you attempt to add (or subtract, and so on) this new object
to myfts1
, an error indicates that the objects
are not identical. Although they contain the same dates, number of
dates, number of data series, and frequency, the two time series objects
do not have the same data series names. Use fts2mat
to
bypass this problem:
addother = myfts1 + fts2mat(newfts2);
This operation adds the matrix that contains the contents of
the data series in the object newfts2
to myfts1
.
You should carefully consider the effects on your data before deciding
to combine financial time series objects in this manner.
In addition to the basic arithmetic operations, several other
mathematical functions operate directly on financial time series objects.
These functions include exponential (exp
),
natural logarithm (log
), common
logarithm (log10
), and many
more.
The data transformation and the frequency conversion functions convert a data series into a different format.
Data Transformation Functions
Function | Purpose |
---|---|
Box-Cox transformation | |
Differencing | |
Fill missing values | |
Filter | |
Lag time series object | |
Lead time series object | |
Periodic average | |
Smooth data | |
Moving average |
Frequency Conversion Functions
Function | New Frequency |
---|---|
As specified | |
As specified | |
Annual | |
Daily | |
Monthly | |
Quarterly | |
Semiannually | |
Weekly |
As an example look at boxcox
, the Box-Cox transformation function. This function transforms
the data series contained in a financial time series object into another
set of data series with relatively normal distributions.
First create a financial time series object from the supplied whirlpool.dat
data
file.
whrl = ascii2fts('whirlpool.dat', 1, 2, []);
Fill any missing values denoted with NaN
s
in whrl
with values calculated using the linear
method:
f_whrl = fillts(whrl);
Transform the nonnormally distributed filled data series f_whrl
into
a normally distributed one using Box-Cox transformation:
bc_whrl = boxcox(f_whrl);
Compare the result of the Close
data series
with a normal (Gaussian) probability distribution function and the
nonnormally distributed f_whrl
:
subplot(2, 1, 1); hist(f_whrl.Close); grid; title('Nonnormally Distributed Data'); subplot(2, 1, 2); hist(bc_whrl.Close); grid; title('Box-Cox Transformed Data');
Box-Cox Transformation
The bar chart on the top represents the probability distribution
function of the filled data series, f_whrl
, which
is the original data series whrl
with the missing
values interpolated using the linear method. The distribution is skewed
toward the left (not normally distributed). The bar chart on the bottom
is less skewed to the left. If you plot a Gaussian probability distribution
function (PDF) with similar mean and standard deviation, the distribution
of the transformed data is very close to normal (Gaussian).
When you examine the contents of the resulting object bc_whrl
,
you find an identical object to the original object whrl
but
the contents are the transformed data series. If you have the Statistics and Machine Learning Toolbox™ software,
you can generate a Gaussian PDF with mean and standard deviation equal
to those of the transformed data series and plot it as an overlay
to the second bar chart. In the next figure, you can see that it is
an approximately normal distribution.
Overlay of Gaussian PDF
The next example uses the smoothts
function
to smooth a time series.
To begin, transform ibm9599.dat
, a supplied
data file, into a financial time series object:
ibm = ascii2fts('ibm9599.dat', 1, 3, 2);
Fill the missing data for holidays with data interpolated using
the fillts
function and the Spline
fill
method:
f_ibm = fillts(ibm, 'Spline');
Smooth the filled data series using the default Box (rectangular window) method:
sm_ibm = smoothts(f_ibm);
Now, plot the original and smoothed closing price series for IBM^{®} stock:
plot(f_ibm.CLOSE('11/01/97::02/28/98'), 'r') datetick('x', 'mmmyy') hold on plot(sm_ibm.CLOSE('11/01/97::02/28/98'), 'b') hold off datetick('x', 'mmmyy') legend('Filled', 'Smoothed') title('Filled IBM Close Price vs. Smoothed Series')
Smoothed Data Series
These examples give you an idea of what you can do with a financial time series object. This toolbox provides some MATLAB functions that have been overloaded to work directly with these objects. The overloaded functions are those most commonly needed to work with time series data.
ascii2fts
| boxcox
| convertto
| datestr
| diff
| fillts
| filter
| fints
| fts2mat
| ftsbound
| lagts
| leadts
| peravg
| resamplets
| smoothts
| toannual
| todaily
| tomonthly
| toquarterly
| tosemi
| toweekly
| tsmovavg