liberata_metrics.metrics.market_metrics module
- liberata_metrics.metrics.market_metrics.compute_fair_marketprice(capital: spmatrix, mask_reviewers: slice, mask_replicators: slice, manuscript_memberships: spmatrix, contributor_index_map_subset: Dict[str, int], num_contributors: int) Tuple[spmatrix, spmatrix][source]
Compute tag-level fair market prices (FMP) for reviewers and replicators based on the capital allocated to these roles across all manuscripts. The function performs the following steps: 1. Masks the global capital allocation by reviewer and replicator roles using the provided
mask matrices (mask_reviewers and mask_replicators).
- Computes the per-manuscript capital allocated to reviewers and replicators using
get_per_manuscript_cap, restricted to the specified subset of contributors.
Aggregates the per-manuscript capital up to tags using the manuscript_memberships matrix.
- Divides the aggregated capital per tag by the number of manuscripts associated with each tag
to yield the fair market price (FMP) for reviewers and replicators per tag.
- Parameters:
capital (sparse.spmatrix) – Contributor-level capital matrix. Shape: (n_manuscripts, n_contributors).
mask_reviewers (sparse.spmatrix) – Manuscript-by-contributor mask indicating reviewer involvement. Shape: (n_manuscripts, n_contributors). Used to select reviewers’ share of capital per manuscript.
mask_replicators (sparse.spmatrix) – Manuscript-by-contributor mask indicating replicator involvement. Shape: (n_manuscripts, n_contributors). Used to select replicators’ share of capital per manuscript.
manuscript_memberships (sparse.spmatrix) – Tag-by-manuscript membership matrix (shape: n_tags x n_manuscripts). Used to aggregate per-manuscript capital up to tags. Membership entries may be binary or weighted.
contributor_index_map_subset (Dict[str, int]) – Mapping from contributor identifier (string) to column index in the mask matrices for the subset of contributors of interest. The function uses the mapped indices to select columns from mask_reviewers and mask_replicators.
- Returns:
A tuple containing two sparse arrays (each of length n_tags): - reviewer_fmp: tagwise fair market price for reviewers. - replicator_fmp: tagwise fair market price for replicators.
- Return type:
Tuple[sparse.spmatrix, sparse.spmatrix]
- Raises:
ValueError – If input matrix/vector shapes are incompatible (e.g., contributor counts, manuscript counts, or tag counts do not align) the function may raise errors propagated from underlying sparse operations or from get_per_manuscript_cap.
KeyError – If contributor_index_map_subset contains indices that do not correspond to columns in the provided mask matrices, column selection may fail.
Notes
- The function attempts a fast column-slicing of mask_reviewers and mask_replicators
for the contributor subset and falls back to an explicit hstack/getcol approach if slicing is not supported.
- Elementwise multiplications and sums assume broadcasting consistent with sparse matrix
shapes: reviewer/replicator masks are treated as per-manuscript indicators and are multiplied with per-manuscript capital vectors produced by get_per_manuscript_cap.
manuscript_memberships is expected to map manuscripts to tags (rows correspond to tags).
- The returned fair market price values are not normalized by the number of reviewers
or replicators unless such normalization is performed earlier (e.g., in get_per_manuscript_cap).
- All inputs are expected to be sparse-compatible to avoid dense expansion; be mindful of
memory usage when converting between sparse and dense formats.
Examples
Shape conventions (illustrative): - mask_reviewers / mask_replicators: (n_manuscripts, n_contributors) - capital: (n_manuscripts, n_contributors) - contributor_index_map_subset: subset of contributor -> column index mappings - get_per_manuscript_cap(masked_capital, subset_map) -> returns array of length n_manuscripts - manuscript_memberships: (n_tags, n_manuscripts)
- liberata_metrics.metrics.market_metrics.compute_relative_performance(shares: spmatrix, capital_history: List[spmatrix], time_history: List[float], manuscript_memberships: spmatrix, contributor_index_map_subset: Dict[str, int]) float[source]
Compute portfolio relative performance against manuscript-domain benchmarks.
This metric evaluates the weighted quality/performance of manuscripts held by a contributor-defined portfolio. For each manuscript in the portfolio, the manuscript expected return is divided by the expected return of its domain (as defined by manuscript tag memberships), then aggregated using portfolio manuscript weights.
Conceptually, the function computes:
rho_Pi = (1 / sum_{m in Pi} s_m) * sum_{m in Pi} s_m * (mu_m / mu_d(m))
where: -
Piis the set of manuscripts held by the portfolio, -s_mis the portfolio weight/share in manuscriptm, -mu_mis the manuscript expected return, -mu_d(m)is the expected return of manuscriptm’s domain/tag.Processing overview
1. Infer portfolio manuscript weights with
allocation_weightsusing the providedsharesmatrix and contributor subset. 2. For each manuscript in the inferred portfolio: - Estimate manuscript expected return from manuscript-level slices ofcapital_historyviaget_expected_returns.- Identify the manuscript’s tag/domain membership from
manuscript_memberships.
- Build domain-level capital history using
mix_by_tagand estimate domain expected return via
get_expected_returns.
- Build domain-level capital history using
Accumulate the weighted ratio
s_m * (mu_m / mu_d(m)).
Normalize by total portfolio shares/weights.
- param shares:
Sparse manuscript-by-contributor matrix of shares/weights used to infer the portfolio composition for
contributor_index_map_subset. Must be compatible withallocation_weightsindexing conventions.- type shares:
scipy.sparse.spmatrix
- param capital_history:
Chronological sequence of sparse capital matrices used to estimate returns over time. Each entry should be aligned to the same manuscript and contributor indexing scheme.
- type capital_history:
List[scipy.sparse.spmatrix]
- param time_history:
Time points corresponding to
capital_history. Must be the same length ascapital_historyand strictly increasing for return-per-time calculations inget_expected_returns.- type time_history:
List[float]
- param manuscript_memberships:
Sparse tag-by-manuscript membership matrix of shape
(n_tags, n_manuscripts)where entry[t, m]indicates membership of manuscriptmin tag/domaint.- type manuscript_memberships:
scipy.sparse.spmatrix
- param contributor_index_map_subset:
Mapping from contributor identifier to contributor column index for the portfolio entity being evaluated.
- type contributor_index_map_subset:
Dict[str, int]
- returns:
Relative performance score for the selected portfolio. Values above 1.0 indicate average outperformance versus domain baselines, while values below 1.0 indicate underperformance.
- rtype:
float
- raises TypeError:
If
sharesis not a scipy sparse matrix.- raises ValueError:
If
contributor_index_map_subsetis empty, or if called helper functions reject invalid input shapes/history lengths.
Notes
Portfolio manuscript membership is inferred from non-zero allocation
weights returned by
allocation_weights. - Domain return extraction depends onmanuscript_membershipsand assumes consistent manuscript row indexing across all inputs. - The implementation currently propagates edge-case behavior from helper functions (for example, domain-return zero handling) rather than explicitly applying a zero-safe division at this level.Examples
>>> rp = compute_relative_performance( ... shares=shares, ... capital_history=capital_history, ... time_history=time_history, ... manuscript_memberships=manuscript_memberships, ... contributor_index_map_subset=subset_map, ... ) >>> isinstance(rp, float) True
- liberata_metrics.metrics.market_metrics.compute_risk_adjusted_excess_return(capital_history: List[spmatrix], time_history: List[float], manuscript_memberships: spmatrix, contributor_index_map_subset: Dict[str, int], manuscript_index: int) ndarray[source]
Compute manuscript-level risk-adjusted excess return (alpha).
For the selected manuscript, this function estimates:
alpha_m = mu_m - beta_m * mu_d(m)
where manuscript and domain expected returns are derived from
capital_historyandtime_historyusingget_expected_returns, andbeta_mis computed viacompute_sensitivity.Domain returns are constructed by: 1. extracting the manuscript’s tag/domain memberships from
manuscript_memberships; 2. aggregating capital history by tag withmix_by_tag; and 3. selecting/summing the relevant domain rows for the manuscript.- Parameters:
capital_history (List[scipy.sparse.spmatrix]) – Chronological list of sparse capital matrices. Each matrix should use consistent manuscript and contributor indexing.
time_history (List[float]) – Time points corresponding to
capital_historyused to compute expected returns per unit time.manuscript_memberships (scipy.sparse.spmatrix) – Sparse tag-by-manuscript matrix indicating manuscript-domain membership.
contributor_index_map_subset (Dict[str, int]) – Mapping from contributor identifier to contributor column index for the portfolio subset used in return calculations.
manuscript_index (int) – Row index of the manuscript for which to compute risk-adjusted excess return.
- Returns:
Risk-adjusted excess return (alpha) for the specified manuscript.
- Return type:
np.ndarray
- Raises:
IndexError – If
manuscript_indexis out of bounds for any matrix incapital_historyor formanuscript_memberships.ValueError – Propagated from helper functions when histories are invalid (for example, length mismatches or insufficient points).
TypeError – Propagated from helper functions when non-sparse inputs are supplied where sparse matrices are expected.
Notes
This routine computes alpha for a single manuscript index.
If domain expected returns are constant/degenerate, sensitivity estimation
may be unstable depending on NumPy behavior.
Examples
>>> alpha = compute_risk_adjusted_excess_return( ... capital_history=capital_history, ... time_history=time_history, ... manuscript_memberships=manuscript_memberships, ... contributor_index_map_subset=subset_map, ... manuscript_index=10, ... )
- liberata_metrics.metrics.market_metrics.compute_risk_adjusted_relative_performance(capital_history: List[spmatrix], time_history: List[float], manuscript_memberships: spmatrix, contributor_index_map_subset: Dict[str, int]) float[source]
Compute risk-adjusted relative performance for an entire portfolio.
This function extends manuscript-level risk-adjusted excess return to a portfolio-level quantity by evaluating every manuscript row in the first capital matrix. For each manuscript, it computes the risk-adjusted excess return
alpha_mand then normalizes it by the manuscript’s domain-level expected returnmu_d(m). The final result is the sum of these manuscript-wise contributions.Conceptually, the metric follows:
RARP = sum_{m in Pi} lpha_m / mu_d(m)
where: -
Piis the set of manuscripts in the portfolio, -alpha_mis the risk-adjusted excess return for manuscriptm, -mu_d(m)is the expected return of the manuscript’s domain/tag.The manuscript-level
alpha_mvalues are computed by callingcompute_risk_adjusted_excess_returnfor each manuscript index. Domain returns are then reconstructed fromcapital_historyusingmix_by_tagand the manuscript’s tag membership inmanuscript_memberships.- Parameters:
capital_history (List[scipy.sparse.spmatrix]) – Chronological sequence of sparse capital matrices. The first matrix is used to determine the manuscript rows iterated over, and all matrices should share the same manuscript indexing convention.
time_history (List[float]) – Time points corresponding to
capital_history. These are passed toget_expected_returnswhen computing manuscript and domain expected returns.manuscript_memberships (scipy.sparse.spmatrix) – Sparse tag-by-manuscript membership matrix of shape
(n_tags, n_manuscripts). Entry[t, m]indicates whether manuscriptmbelongs to tag/domaint.contributor_index_map_subset (Dict[str, int]) – Mapping from contributor identifier to contributor column index for the subset of contributors used in the portfolio calculation.
- Returns:
Risk-adjusted relative performance score for the portfolio.
- Return type:
float
- Raises:
ValueError – If
contributor_index_map_subsetis empty.TypeError – May be raised by helper functions if the provided histories are not sparse-compatible.
IndexError – May be raised if manuscript indices are out of bounds for the supplied matrices.
Notes
The loop iterates over
range(capital_history[0].shape[0]).The current implementation accumulates
alpha / domain_returnsfor
every manuscript and returns the total. - Division by zero is not handled explicitly here; any zero-domain-return behavior is inherited from the underlying arithmetic and helper calls.
Examples
>>> rarp = compute_risk_adjusted_relative_performance( ... capital_history=capital_history, ... time_history=time_history, ... manuscript_memberships=manuscript_memberships, ... contributor_index_map_subset=subset_map, ... ) >>> isinstance(rarp, float) True
Compute tag-level risk premiums for reviewers and replicators corresponding to manuscripts authored by a given subset of contributors. This function calculates, for each tag, the difference between the capital that reviewers (or replicators) have obtained from manuscripts authored by the specified contributor subset and the fair market price (FMP) for that tag. The computation proceeds in these steps: 1. Select the subset of author columns from mask_authors and create a per-manuscript mask
indicating which manuscripts were authored by selected contributors.
- Mask the global capital allocation by reviewer/replicator role (mask_reviewers
/ mask_replicators) and compute the per-manuscript capital given for QC services, i.e., peer review and replication.
- Restrict reviewer/replicator per-manuscript capital to manuscripts authored by the
selected contributors.
Aggregate per-manuscript capital up to tags via manuscript_memberships (tags x manuscripts).
- Subtract the provided tag-level fair market price vectors (reviewer_fmp, replicator_fmp)
to produce tag-level risk premiums.
- Parameters:
capital (sparse.spmatrix) – Contributor-level capital vector or sparse column matrix. Expected length (or number of rows) equals the number of contributors (n_contributors). This represents the capital each contributor has available/allocated (units consistent with FMP).
mask_authors (sparse.spmatrix) – Manuscript-by-contributor binary (or weighted) mask indicating authorship. Shape: (n_manuscripts, n_contributors). Nonzero entry indicates that the contributor authored (or contributed to) the manuscript.
mask_reviewers (sparse.spmatrix) – Manuscript-by-contributor mask indicating reviewer involvement. Shape: (n_manuscripts, n_contributors). Used to select reviewers’ share of capital per manuscript.
mask_replicators (sparse.spmatrix) – Manuscript-by-contributor mask indicating replicator involvement. Shape: (n_manuscripts, n_contributors). Used to select replicators’ share of capital per manuscript.
contributor_index_map_subset (Dict[str, int]) – Mapping from contributor identifier (string) to column index in the mask matrices for the subset of contributors of interest. The function uses the mapped indices to select columns from mask_authors, mask_reviewers and mask_replicators.
reviewer_fmp (sparse.sparray) – Tag-level fair market price vector for reviewers. Shape: (n_tags,). Units must match those of capital after aggregation.
replicator_fmp (sparse.sparray) – Tag-level fair market price vector for replicators. Shape: (n_tags,). Units must match those of capital after aggregation.
manuscript_memberships (sparse.spmatrix) – Tag-by-manuscript membership matrix (shape: n_tags x n_manuscripts). Used to aggregate per-manuscript capital up to tags. Membership entries may be binary or weighted.
- Returns:
A tuple containing two sparse arrays (each of length n_tags): - reviewer_risk_premium: tagwise (aggregated) reviewer capital on manuscripts authored by the selected contributors minus reviewer_fmp. - replicator_risk_premium: tagwise (aggregated) replicator capital on manuscripts authored by the selected contributors minus replicator_fmp.
- Return type:
Tuple[sparse.sparray, sparse.sparray]
- Raises:
ValueError – If input matrix/vector shapes are incompatible (e.g., contributor counts, manuscript counts, or tag counts do not align) the function may raise errors propagated from underlying sparse operations or from get_per_manuscript_cap.
KeyError – If contributor_index_map_subset contains indices that do not correspond to columns in the provided mask matrices, column selection may fail.
Notes
- The function attempts a fast column-slicing of mask_authors for the contributor subset
and falls back to an explicit hstack/getcol approach if slicing is not supported.
- Elementwise multiplications and sums assume broadcasting consistent with sparse matrix
shapes: author masks are treated as per-manuscript indicators and are multiplied with per-manuscript capital vectors produced by get_per_manuscript_cap.
manuscript_memberships is expected to map manuscripts to tags (rows correspond to tags).
- The returned risk premium values are not normalized by the number of authors, reviewers,
or replicators unless such normalization is performed earlier (e.g., in get_per_manuscript_cap).
- All inputs are expected to be sparse-compatible to avoid dense expansion; be mindful of
memory usage when converting between sparse and dense formats.
Examples
Shape conventions (illustrative): - mask_authors: (n_manuscripts, n_contributors) - mask_reviewers / mask_replicators: (n_manuscripts, n_contributors) - capital: (n_contributors,) or (n_contributors, 1) - contributor_index_map_subset: subset of contributor -> column index mappings - get_per_manuscript_cap(masked_capital, subset_map) -> returns array of length n_manuscripts - manuscript_memberships: (n_tags, n_manuscripts) - reviewer_fmp / replicator_fmp: (n_tags,)
- liberata_metrics.metrics.market_metrics.compute_sensitivity(manuscript_expected_returns: float, domain_expected_returns: float) float[source]
Compute sensitivity (beta) of manuscript returns to domain returns.
This function returns the ratio of covariance between manuscript expected returns and corresponding domain expected returns to the variance of domain expected returns:
beta = Cov(mu_m, mu_d(m)) / Var(mu_d(m))
- Parameters:
manuscript_expected_returns (float) – Manuscript expected return value(s). While typed as
floatin the current signature, this implementation delegates to NumPy covariance and variance routines and is typically meaningful when array-like values are provided.domain_expected_returns (float) – Domain expected return value(s) aligned with
manuscript_expected_returns.
- Returns:
Sensitivity (beta) estimate. Returns 0.0 if domain variance is zero or very close to zero (within numerical epsilon).
- Return type:
float
Notes
The implementation uses
np.var(..., ddof=0), i.e., population variance.
This is appropriate when working with return series. - Returns 0.0 when domain variance is near zero to avoid division by zero.
Examples
>>> beta = compute_sensitivity(np.array([3.0, 5.0, 7.0, 9.0]), np.array([1.0, 2.0, 3.0, 4.0])) >>> isinstance(beta, float) True
- liberata_metrics.metrics.market_metrics.compute_utility_function(capital_history: List[spmatrix], time_history: List[float], contributor_index_map_subset: Dict[str, int], risk_willingness: float) ndarray[source]
Compute mean-variance utility for a contributor subset over time.
This function derives expected returns from the provided capital history, estimates volatility over the same history, and combines the two using a standard quadratic utility formulation.
The computation proceeds in these steps: 1. Compute expected returns for the selected contributors using
get_expected_returns. 2. Compute volatility for the same contributor subset usingget_volatility. 3. Combine expected return and volatility with the risk willingness coefficient to produce a utility vector.- Parameters:
capital_history (List[sparse.spmatrix]) – Sequence of sparse capital matrices, ordered over time. Each matrix is expected to contain manuscript-by-contributor capital allocations for a single time point.
time_history (List[float]) – Time values corresponding to
capital_history. These are passed toget_expected_returnswhen computing the expected return series.contributor_index_map_subset (Dict[str, int]) – Mapping from contributor identifier to the corresponding column index in the capital matrices. Only the contributors in this subset are included in the utility calculation.
risk_willingness (float) – Risk preference coefficient used in the mean-variance utility formula. Larger values penalize volatility more strongly.
- Returns:
A 1D NumPy array containing utility values for the selected contributors. The result is computed as:
utility = expected_returns - 0.5 * risk_willingness * volatility- Return type:
np.ndarray
- Raises:
ValueError – If the input histories are incompatible in length or if the expected return / volatility helpers reject the provided data.
TypeError – If any history element is not sparse-compatible in a way that the downstream helper functions can process.
Notes
The function assumes the helper routines return aligned vectors for the
same contributor subset. - No normalization is performed here beyond the risk-adjusted utility expression. - The returned values are higher when expected returns increase and lower when volatility increases.
Examples
>>> utility = compute_utility_function(capital_history, time_history, contributor_index_map_subset, 1.5) >>> utility.shape (n_contributors,)