Documentation |
On this page… |
---|
Financial Time Series Object Structure Indexing a Financial Time Series Object |
A financial time series object is designed to be 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 series1 and series2 will differ from the above because of the use of random numbers. |
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.
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 just 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 is 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 four 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 NaNs 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 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 the these objects. The overloaded functions are those most commonly needed to work with time series data.