Prices result

Types

PortfolioOptimisers.PricesResultType
struct PricesResult{__T_X, __T_F, __T_B, __T_iv, __T_ivpa, __T_pnl, __T_span} <: AbstractPricesResult

A container for aligned, time-indexed price-level data.

PricesResult is the prices-level mirror of ReturnsResult: it bundles asset prices with optional factor, benchmark, and implied volatility series, all as TimeSeries.TimeArrays. It is the input to price-level preprocessing estimators and prices-to-returns conversion, and the type that defines timestamp-window slicing for pipeline cross-validation via port_opt_view.

The asset price series X is the master clock: port_opt_view selects observation windows on X and aligns the other series to the selected timestamps.

The AssetPanel pnl and the Listing Span span are the exceptions to that alignment. Neither is a TimeArray — a Panel Field may be a 3-dimensional array, a static panel has no clock at all, and a span is two integers per asset — so they cannot be aligned by timestamp, only indexed positionally. Their axes are therefore held parallel to X: the asset axis to TimeSeries.colnames(X), and, for the time-varying shape, the observation axis to TimeSeries.timestamp(X) row for row. Every routine that drops an asset or an observation from X must drop it from both in the same step, which is what port_opt_view, MissingDataFilter and prices_to_returns do, through panel_carrier_view and span_carrier_view.

Fields

  • X: Asset price data (observations × assets). The master clock for timestamp-window slicing.
  • F: Optional factor price data (observations × factors).
  • B: Optional benchmark price data (observations × 1) or (observations × assets).
  • iv: Optional implied volatility data (observations × assets). An absent value is carried as NaN, and the estimator that reads the series excludes the asset from its fit.
  • ivpa: Implied volatility risk premium adjustment, if a vector (assets × 1).
  • pnl: Optional AssetPanel: the Panel Fields of the universe, and its two universe masks. Not a TimeArray: its axes are held positionally parallel to X.
  • span: Optional Listing Span: which assets are listed at each observation of the price clock, observations × assets, held positionally parallel to X. A PortfolioOptimisers.ListingSpan when PriceIngestion derived it by the Span Rule, and any other AbstractMatrix{Bool} when a caller declared their own listing calendar. nothing says the carrier was not built by the ingestion layer.

Constructors

PricesResult(;    X::TimeSeries.TimeArray,    F::Option{<:TimeSeries.TimeArray} = nothing,    B::Option{<:TimeSeries.TimeArray} = nothing,    iv::Option{<:TimeSeries.TimeArray} = nothing,    ivpa::Option{<:Num_VecNum} = nothing,    pnl::Option{<:AssetPanel} = nothing,    span::Option{<:AbstractMatrix{Bool}} = nothing,) -> PricesResult

Keywords correspond to the struct's fields.

Validation

  • !isempty(X).
  • If F is not nothing: !isempty(F).
  • If B is not nothing: !isempty(B), and size(values(B), 2) in (1, size(values(X), 2)).
  • If iv is not nothing: !isempty(iv), size(values(iv), 2) == size(values(X), 2), and every value is finite and non-negative where it is present (an absent one is NaN, or missing on a carrier built by hand; see assert_nonneg_where_present).
  • If ivpa is not nothing: all(x -> x > 0, ivpa), all(x -> isfinite(x), ivpa); if a vector, length(ivpa) == size(values(X), 2).
  • pnl's asset axis is size(values(X), 2), and its observation axis is size(values(X), 1) when it is time-varying. See check_asset_panel.
  • If span is not nothing: size(span) == size(values(X)). Raises a DimensionMismatch.

Examples

julia> X = TimeArray(Date(2020, 1, 1):Day(1):Date(2020, 1, 3),                     [100.0 101.0; 102.0 103.0; 104.0 105.0], ["A", "B"]);julia> pr = PricesResult(; X = X);julia> size(values(pr.X))(3, 2)

Related

source

Functions

PortfolioOptimisers.port_opt_viewMethod
port_opt_view(
    pr::PricesResult,
    _::Colon,
    _::Colon
) -> PricesResult

Return a view of the PricesResult for the observation window i and the assets j of the asset price series X.

The asset price series is the master clock: i selects rows of X, and the factor, benchmark, and implied volatility series are aligned to the selected timestamps (rows whose timestamps are absent from a series are dropped from that series). j selects asset columns and defaults to :, so a call giving only i is an observation window over the whole universe.

Algorithm

The method that Julia selects is the algorithm. The timestamp methods do the work, and the integer method routes into them.

  1. i and j are both Colon: return pr itself. No view is built.

  2. i is a vector of timestamps and j is a Colon: index X, F, B and iv by the timestamps i. Recover the rows of a time-varying Asset Panel from the surviving timestamps with feature_row_indices, and view the panel on that observation axis with panel_carrier_view. A static panel has no observation axis and ignores the row index. View the Listing Span on the same surviving timestamps with span_carrier_view. Carry ivpa through untouched, because the asset index does not reach it. Rebuild the PricesResult.

  3. i is a vector of timestamps and j is a vector of asset indices:

    1. Index X by the timestamps i, then keep the asset columns j.
    2. Index F by the timestamps i alone. j is an asset index, and the factors are a separate axis, so every factor column is kept.
    3. Index B by the timestamps i. Keep its columns j when B holds one column per asset, and keep its single column otherwise. The test is B's own width, because a shared benchmark has one column to give whatever j asks for.
    4. Index iv by the timestamps i and the asset columns j, and view ivpa at j.
    5. Recover the rows of a time-varying Asset Panel with feature_row_indices, and view the panel at those rows and the assets j with panel_carrier_view, handing it the asset names so that a tensor Panel Field whose labels are the asset names (features_are_assets) is cut on its label axis too.
    6. View the Listing Span at the surviving timestamps and the assets j with span_carrier_view.
    7. Rebuild the PricesResult.
  4. i and j are integer indices, ranges or Colons: read the timestamps TimeSeries.timestamp(pr.X)[i], and call step 2 or step 3 with them. This is the method a caller reaches with port_opt_view(pr, 2:3).

Arguments

  • pr: A PricesResult object.
  • i: Observation window into the rows of pr.X. Either integer indices (AbstractVector{<:Integer}, AbstractRange, or Colon) or a vector of timestamps (AbstractVector{<:Dates.AbstractTime}).
  • j: Asset window into the columns of pr.X. Integer indices, an AbstractRange, or Colon for the whole universe. A Colon leaves X, B, iv and ivpa alone, which is why ivpa passes through untouched on the observation-only arity and is viewed at j on the other.

Returns

  • new_pr::PricesResult: A new PricesResult containing only the data for the selected window.

Examples

julia> X = TimeArray(Date(2020, 1, 1):Day(1):Date(2020, 1, 3),                     [100.0 101.0; 102.0 103.0; 104.0 105.0], ["A", "B"]);julia> pr = PricesResult(; X = X);julia> pv = PortfolioOptimisers.port_opt_view(pr, 2:3);julia> first(timestamp(pv.X))2020-01-02julia> size(values(pv.X))(2, 2)

Related

source