DataViews

AssetDataViews

DataViews are a way to access either raw time series data or Layer data related to an Asset (see Assets) or a Collection.

For example, if a is an Asset that has a corresponding times series with the field name :volume, then dv = DVTimeSeries(a, :volume) creates a DVTimeSeries (short for DataViewTimeSeries) which is a subtype to AssetDataView. dv[i][j] then gives the j:th value of the i:th sample, or simplydv[i] gives the whole view of the volume field that is related to the i:th sample.

Likewise, if we have dvl = DVLayerField(a, :field_name, LayerType), then dv[i][j] gives j:th value of the i:th sample for the field :field_name in the Layer of type LayerType. Here, and in many other cases, the LayerType may be completely omitted if the desired Layer is the outhermost one of the Layers in the Asset.

CollectionDataViews

If instead c is a Collection then cdv = DVTimeSeries(c, :volume) creates a CDV{DVTimeSeries} (where CDV is short for CollectionDataView) which contains the DVTimeSeries for every Asset in the Collection. Then cdv[1] == DVTimeSeries(a, :volume) for the first Asset a given by the iterator over all Assets. cdv[i][j][k] thus gives the k:th value of the time series of :volume corresponding to the j:th sample in the i:th Asset.

FlatCDV

The CDV may also be flattened to a FlatCDV. If fcdv = FlatCDV(cdv) then the views for all samples in the Collection are stored in one dimension so that fcdv[i] gives the corresponding view of the :volume field for the i:th sample in the whole Collection.

The FlatCDV is useful when the value for two different DataViews are to be compared for the same asset and sample without caring about specifics. For example when investigating the correlation between two different DataViews.

Example:

# Create DataViews for volume and closing prices (this doesn't make much sense
# but it's just an easy example)
volume_cdv = DVTimeSeries(collection, :volume)
close = DVTimeSeries(collection, :close)

# Flatten the CDVs
flat_volume = FlatCDV(volume_cdv)
flat_close = FlatCDV(close)


# Now we can easily compare volume and closing prices for each sample
cor_vol_close = cor([flat_volume[i][end] for i in 1:length(flat_volume)],
                  [flat_close[i][end] for i in 1:length(flat_close)])

Mathematical Operations

DataViews support basic mathematical operations between compatible views:

  • Division: /
  • Multiplication: *
  • Addition: +
  • Subtraction: -

Example:

# Calculate ratio between high and low prices
high = DVTimeSeries(asset, :high)
low = DVTimeSeries(asset, :low)
price_ratio = high / low

NonRepainting DataViews

The NonRepainting Dataviews are useful when constructing NonRepainting Layers. If a is an Asset that has a corresponding times series with the field name :volume, then dv = DVNonRepaintingTimeSeries(a, :volume) creates a NonRepaintingDVTimeSeries.. dv then contains a view of the volume field from the first datetime contained in any of the Asset's samples to the last datetime contained in any of the samples.

Below is an example of the use of a NonRepainting DataView taken from the code creating the SMA Layer used in TFire. Since the Simple Moving Average indicator is a non repainting indicator a NonRepainting DataView is used to access the price data.

# input vectors
dvts = DVNonRepaintingTimeSeries(asset, price_field)

DonatedDataViews

Data Views on donated Assets/Collections (see Donation) work just like ordinary DataViews with the exception that the DataView should be applied to a DonatedAssetLink and not to an Asset.

Example:

TFire> collection_sma = add_layer(collection, LayerSMA);

TFire> collection = collection[collection_sma]; # This removes dates that are in collection but not in collection_sma

TFire> col_donated = donate(collection, collection_sma);

TFire> asset_don = get_first_asset(col_donated) # special function to get first asset of a Collection. Useful for debugging etc.
-| Asset |-
Ticker: MMM
Samples: 2020

TFire> donated_dv = DVLayerDictKey(get_donated_asset_link(asset_don, "MMM"), :ma_values, 26)

In the example above we can access the Simple Moving Average Layer from another Collection.

FuturePriceView

A special kind of DataView category is the FuturePriceView. It's the only DataView that is allowed access to data past the evaluation date, specificallt price data. Its primary use is to calculate future returns after the evaluation date.

Returns

There are a couple of built in functions that calculates returns based on FuturePriceViews.

Fundamental Return Functions

If $P_1$ is the price at the evaluation date and $P_i$ is the price at $i$ steps into the future from the evaluation date, then

\[\text{Compound Return}_i = \left( \frac{P_i - P_1}{P_1} \right)\]

and

\[\text{Step Return}_i = \left( \frac{P_i - P_{i-1}}{P_{i-1}} \right)\]

By default the compound_return() and step_return() methods use the FutureAdjClose DataView, which represents the closing price adjusted for dividens etc. Thus. by defafault they give the compound total return. While this is by far the most common way of measuring returns for an equity most return functions take the fut_price_type argument if for example a non adjusted price is to be used.

Some other return functions are:

Other Return Functions

\[\text{Mean Compound Return}_j = \frac{1}{N} \sum_{i=1}^N \left(\frac{P_{i,j}}{P_{i,1}} - 1\right)\]

Here $N$ is the total number of assets, $j$ is the time step, $P_{i,j}$ is the price of asset $i$ at time step $j$, and $P_{i,1}$ is the initial price of asset $i$.

\[\text{Mean-Like Weighted Step Return}_j = \frac{1}{N_j} \sum_{i=1}^{N_j} \frac{P_{i,j+1}}{P_{i,j}} - 1\]

j is the time step, Nj is the number of assets with data available at step j, P{i,j} is the price of asset i at time step j, and P_{i,j+1} is the price of asset i at the next time step.

\[\text{Mean-Like Weighted Compound Return}_j = \prod_{k=1}^j \left(\frac{1}{N_k} \sum_{i=1}^{N_k} \frac{P_{i,k+1}}{P_{i,k}}\right) - 1\]

Where $j$ is the final time step, $k$ represents each intermediate time step from 1 to $j$, $N_k$ is the number of assets with data available at step $k$, $P_{i,k}$ is the price of asset $i$ at time step $k$, and $P_{i,k+1}$ is the price of asset $i$ at the next time step.

Compound Return Envelope:

Let $R_{i,j} = \frac{P_{i,j}}{P_{i,1}} - 1$ be the compound return of asset $i$ at step $j$.

\[\text{Best Return Envelope}_k = \frac{1}{k} \sum_{i=1}^k \max_{j} R_{i,j}\]

\[\text{Worst Return Envelope}_k = \frac{1}{k} \sum_{i=1}^k \min_{j} R_{i,j}\]

Here, $k$ is the number of best (or worst) returns to consider, $R_{i,j}$ is the compound return of asset $i$ at step $j$.

Functions

For a list of DataView related functions see DataViews - Functions.

For a list of DataView related functions see Returns - Functions.