Binary arithmetic functions

The standard binary arithmetic functions Atan2, Plus, Minus, Times, Divide, Mod, and Pow can operate on time series data. The Plus, Minus, Times, and Divide functions can also be denoted by their standard operators +, -, *, and /.

Syntax

Function(ts TimeSeries, 
        ts TimeSeries) 
returns TimeSeries;

Function(number  scalar, 
        ts            TimeSeries) 
returns TimeSeries;

Function(ts            TimeSeries, 
        number  scalar) 
returns TimeSeries;

Function(row  row, 
        ts            TimeSeries) 
returns TimeSeries;

Function(ts            TimeSeries, 
        row  row) 
returns TimeSeries;
ts
The source time series. One of the two arguments must be a time series for this variant of the functions. The two inputs must be compatible under the function.
number
A scalar number. Must be compatible with the source time series.
row
A row type. Must be compatible with the source time series.

Description

In the first format, both arguments are time series. The result is a time series that starts at the later of the starting times of the inputs. The end point of the result is the later of the two input end points if both inputs are irregular. The result end point is the earlier of the input regular time series end points if one or more of the inputs is a regular time series. The result time series has one time point for each input time point in the interval.

The element at time t in the resulting time series is formed from the last elements at or before time t in the two input time series. Normally the function is applied column by column to the input columns, except for the time stamp, to produce the output element. In this case, the two input row types must have the same number of columns, and the corresponding columns must be compatible under the function.

However, if there is a variant of the function that operates directly on the row types of the two input time series, then that variant is used. Then the input row types can have different numbers of columns and the columns might be incompatible. The time stamp of the resulting element is ignored; the element placed in the resulting time series has the later of the time stamps of the input elements.

The resulting calendar is the union of the calendars of the input time series. If the input calendars are the same, then the resulting calendar is the same as the input calendar. Otherwise, a new calendar is made. The name of the resulting calendar is a string that contains the names of the calendars of the input time series, separated by a vertical line ( | ). For example, if two time series are joined, and mycal and yourcal are the names of their corresponding calendars, the resulting calendar is named mycal|yourcal.

The resulting time series is regular if both the input time series are regular and irregular if either of the inputs is irregular.

One of the inputs can be a scalar number or a row type. In this case, the resulting time series has the same calendar, sequence of time stamps, and regularity as the input time series. If one of the inputs is a scalar number, then the function is applied to the scalar number and to each non-time stamp column of each element of the input time series.

If an input is a row type, then that row type must be compatible with the time series row type. The function is applied to the input row type and each element of the input time series. It is applied column by column or directly to the two row types, depending on whether there is a variant of the function that handles the row types directly.

Returns

The same type of time series as the first time series input, unless the function is cast, then it returns the type of time series to which it is cast.

For example, suppose that time series tsi has type TimeSeries(ci), and that time series tsr has type TimeSeries(cr), where ci is a row type with INTEGER columns and cr is a row type with SMALLFLOAT columns. Then Plus(tsi, tsr) has type TimeSeries(ci); the fractional parts of the resulting numbers are discarded. This is generally not the wanted effect. Plus(tsi, tsr)::TimeSeries(cr) has type TimeSeries(cr) and does not discard the fractional parts of the resulting numbers.

Example

Suppose that you want to know the average daily value of stock prices. The following statements separate the daily high and low values for the stocks into separate time series in a daily_high table and a daily_low table:
create row type price( timestamp datetime year to fraction(5), 
   val real);
create row type simple_series( stock_id int, data 
   TimeSeries(price));

create table daily_high of type simple_series;

$insert into daily_high
    select stock_id,
          Apply('$high',
                '2011-01-03 00:00:00.00000'
                ::datetime year to fraction(5),
                '2011-01-10 00:00:00.00000'
                ::datetime year to fraction(5),
                stock_data)::TimeSeries(one_real)
        from daily_stocks;

create table daily_low of type simple_series;

insert into daily_low
    select stock_id,
      Apply('$low',
       '2011-01-03 00:00:00.00000'
       ::datetime year to fraction(5),
       '2011-01-10 00:00:00.00000'
       ::datetime year to fraction(5),
       stock_data)::TimeSeries(price)
   from daily_stocks;

The following query uses the symbol form of the Plus and Divide functions to produce a time series of daily average stock prices in the daily_avg table:

create table daily_avg of type simple_series;

insert into daily_avg
    select l.stock_id, (l.data + h.data)/2
        from daily_low l, daily_high h
        where l.stock_id = h.stock_id;