Attribution

Brinson-Fachler, Brinson-Hood-Beebower, Fama-French and style attribution.

See the usage guide for task-oriented examples. Signatures below are generated from the public headers at the same commit as the rest of this site.

class BrinsonAttribution

Native owning facade corresponding to the source’s stateful BrinsonAttribution calculator.

The facade stores an optional sector mapping and applies it to returns (mean), benchmark returns (mean) and weights (sum) before delegating to the canonical brinson_results kernel. Missing benchmark returns default to the portfolio returns; missing weights default to equal weights. The native result keeps the kernel’s timestamp index and full effect columns (the source’s integer period column and RangeIndex are Python identity, not a native claim).

Public Functions

explicit BrinsonAttribution(std::map<std::string, std::vector<std::string>> sector_mapping = {})

Constructs the facade with an optional sector mapping.

The mapping is stored as supplied and validated when calculate runs.

Parameters:

sector_mapping – Sector name to asset-column mapping; empty disables sector aggregation.

const std::map<std::string, std::vector<std::string>> &sector_mapping() const noexcept

Returns the stored sector-to-asset mapping.

Returns:

Const reference to the mapping owned by this facade.

dataframe calculate(const dataframe &returns, std::optional<dataframe> benchmark_returns = std::nullopt, std::optional<dataframe> weights = std::nullopt, std::string_view method = "brinson") const

Computes native Brinson attribution for the supplied returns.

The method argument accepts brinson and the historical brinson_hood alias, both selecting the BHB arithmetic decomposition. When a sector mapping is present, returns and benchmark returns are averaged across each sector’s assets and weights are summed before attribution. Missing benchmark returns default to the portfolio returns, missing weights default to equal weights, and benchmark weights are always equal weights.

Parameters:
  • returns – Portfolio returns with one double column per asset.

  • benchmark_returns – Optional benchmark returns; defaults to returns.

  • weights – Optional portfolio weights; defaults to equal weights.

  • method – Attribution method name.

Throws:
  • fincore_error – If method is unknown, a mapping entry names an empty sector or asset list, a mapped asset column length does not match the index, or no return column remains.

  • input_error – If a mapped asset column is missing or the Brinson kernel rejects the resolved inputs.

Returns:

A frame indexed like returns with the allocation, selection, interaction, total, portfolio-return and benchmark-return columns.

class FamaFrenchModel

Native owning Fama-French model facade.

The model stores its specification (3factor, 5factor or 4factor_mom), risk-free rate, fitted alpha and betas. Estimation delegates to the existing native factor-regression kernel. All returned frames own their data.

Public Functions

explicit FamaFrenchModel(std::string model_type = "5factor", double risk_free_rate = 0.0)

Constructs a Fama-French model for a supported specification.

Parameters:
  • model_type – One of 3factor, 5factor or 4factor_mom.

  • risk_free_rate – Finite risk-free rate stored with the model.

Throws:

fincore_error – If model_type is unsupported or the risk-free rate is not finite.

const std::string &model_type() const noexcept

Returns the configured model type.

Returns:

One of 3factor, 5factor or 4factor_mom.

double risk_free_rate() const noexcept

Returns the configured risk-free rate.

Returns:

The risk-free rate supplied at construction.

std::span<const std::string_view> factors() const noexcept

Returns the factor names selected by the model type.

Returns:

A non-owning view valid for the lifetime of this model.

const std::map<std::string, double> &betas() const noexcept

Returns the fitted factor betas.

Returns:

Factor-to-beta mapping, empty before a successful fit.

std::optional<double> alpha() const noexcept

Returns the fitted intercept.

Returns:

The alpha from the most recent fit, empty before fitting.

fama_french_fit_result fit(const dataframe &returns, const dataframe &factor_data, std::string_view returns_column = {})

Fits the configured model and stores its alpha and betas.

An empty returns_column selects the first double column, matching the source’s single-asset DataFrame behaviour. The fit delegates to the native least-squares factor regression.

Parameters:
  • returns – Frame containing the dependent return series.

  • factor_data – Frame containing the configured factor columns and sharing returns’ index.

  • returns_column – Optional dependent column name.

Throws:
  • fincore_error – If no double returns column can be selected.

  • input_error – If the regression rejects the inputs or is rank deficient.

Returns:

The native fit result and the factor betas for this model.

dataframe predict(const dataframe &factor_data) const

Predicts fitted returns from factor data using the stored model.

The result is alpha + sum(beta_i * factor_i) for every input row and is stored under the fitted_returns column.

Parameters:

factor_data – Frame containing all configured factor columns.

Throws:

fincore_error – If the model has not been fitted (code fincore.model_not_fit) or a factor column length does not match the frame index.

Returns:

A frame indexed like factor_data with one fitted_returns column.

dataframe get_factor_exposures(const dataframe &returns, const dataframe &factor_data, std::optional<std::size_t> rolling_window = std::nullopt, std::string_view returns_column = {}) const

Computes alpha and factor betas over expanding or trailing windows.

rolling_window selects a trailing window; std::nullopt or zero uses an expanding window from the first row. Rows with at most K observations for K factors are NaN. This method does not update the model’s stored alpha or betas.

Parameters:
  • returns – Frame containing the dependent return column.

  • factor_data – Frame containing the configured factor columns.

  • rolling_window – Optional trailing window length.

  • returns_column – Optional dependent column name; an empty value selects the first double column.

Throws:
  • fincore_error – If the frames do not share the same index or the dependent column cannot be selected.

  • input_error – If an eligible window regression fails.

Returns:

A frame indexed like returns with alpha followed by one column per configured factor.

std::map<std::string, double> attribution_decomposition(const dataframe &returns, const dataframe &factor_data, std::string_view returns_column = {})

Fits the model and decomposes its mean return.

The returned map contains alpha, one <factor>_attribution entry per configured factor (beta * mean(factor)), specific_return (the sum of those contributions), common_return (the mean dependent return minus the configured risk-free rate) and unexplained (common_return - alpha - specific_return). The fit updates the model’s stored alpha and betas.

Parameters:
  • returns – Frame containing the dependent return series.

  • factor_data – Frame containing the configured factor columns.

  • returns_column – Optional dependent column name.

Throws:
  • fincore_error – If the dependent return column cannot be selected.

  • input_error – If the regression rejects the inputs.

Returns:

A map from component name to contribution.

class StyleResult

Native owning facade for StyleResult.

The source container exposes exposures, returns_by_style and overall_returns plus deterministic summary/dictionary projections. The native class owns copies of all three frames.

Public Functions

StyleResult(dataframe exposures, dataframe returns_by_style, dataframe overall_returns)

Constructs a result from three existing frames.

The frames are moved into the result and are not validated here.

Parameters:
  • exposures – Asset-by-style exposure frame.

  • returns_by_style – Style/return summary frame.

  • overall_returns – Portfolio return frame.

explicit StyleResult(style_analysis_result result)

Constructs a result by consuming a style analysis result.

Parameters:

result – Analysis result whose frames are moved into this object.

const dataframe &exposures() const noexcept

Returns the owned exposure frame.

Returns:

Const reference to the asset-by-style exposures.

const dataframe &returns_by_style() const noexcept

Returns the owned style/return summary frame.

Returns:

Const reference to the style and return columns.

const dataframe &overall_returns() const noexcept

Returns the owned portfolio return frame.

Returns:

Const reference to the overall returns.

std::map<std::string, double> style_summary() const

Returns a style -> average return mapping in deterministic key order.

The style and return columns of returns_by_style are used when present; a missing return column falls back to the first double column, and a missing style column labels values by timestamp. Later duplicate style labels replace earlier values.

Throws:

fincore_error – If no numeric return column exists or the style and return columns do not align.

Returns:

Mapping from style label to its stored return.

std::map<std::string, dataframe> to_dict() const

Returns a dictionary of the three owned frames.

Keys are exposures, returns_by_style and overall_returns; each value is a detached copy.

Returns:

Map from source key to a copied frame.

struct attribution_alignment

Attribution inputs after asset and date alignment.

Public Members

dataframe returns

Returns restricted to aligned dates.

dataframe positions

Positions with unloaded non-cash assets and unaligned dates removed.

dataframe factor_returns

Factor returns restricted to aligned dates.

factor_loading_table factor_loadings

Loadings copied unchanged from the input table.

std::vector<std::string> warnings

Alignment warnings, with the missing-asset warning first.

struct brinson_cumulative_result

Summed Brinson effects and compounded returns across all periods.

Public Members

double allocation

Sum of the period allocation effects.

double selection

Sum of the period selection effects.

double interaction

Sum of the period interaction effects.

double total

Sum of the period total effects.

double portfolio_cumulative

Compounded portfolio return, wealth - 1.

double benchmark_cumulative

Compounded benchmark return, wealth - 1.

struct brinson_period_result

Brinson-Hood-Beebower effects for one period.

Each effect is the direct arithmetic contribution for that period; no normalization or compounding is applied.

Public Members

double allocation

Allocation effect for the period.

double selection

Selection effect for the period.

double interaction

Interaction effect for the period.

double total

Sum of allocation, selection and interaction.

double portfolio_return

Weighted portfolio return for the period.

double benchmark_return

Weighted benchmark return for the period.

struct factor_loading_table

Factor-loading table aligned by date, asset and factor labels.

values is a flattened dates x assets x factors buffer; NaN marks a missing loading. align_and_warn requires its length to match the label dimensions and uses the date and asset labels for alignment.

Public Members

std::vector<timestamp> dates

Dates with available loadings.

std::vector<std::string> assets

Asset identifiers with loadings.

std::vector<std::string> factors

Factor identifiers.

std::vector<double> values

Flat loading values, NaN if missing.

struct factor_regression_result

Result of an ordinary least-squares factor regression.

All frames own their data. coefficients has an ordinal index and the columns factor and coefficient, with alpha first followed by the requested factor names in request order.

Public Members

double alpha

Estimated intercept.

double r_squared

1 - SSE/SST; 0 for exactly constant returns.

dataframe coefficients

Alpha and factor coefficient table.

dataframe fitted_returns

Fitted values on the returns index.

dataframe residuals

Observed minus fitted values on the returns index.

struct fama_french_fit_result

Result of the native OLS Fama-French fit.

The native kernel is the canonical least-squares factor regression. The Python Newey-West/WLS covariance options are not part of that kernel, so std_errors/p_values are deliberately absent rather than fabricated.

Public Members

double alpha = {}

Estimated intercept.

std::map<std::string, double> betas

Factor name to fitted beta.

double r_squared = {}

Regression R-squared from the native fit.

dataframe fitted_returns

Fitted values on the returns index.

dataframe residuals

Observed minus fitted values.

struct idiosyncratic_risk_result

Result of the idiosyncratic-risk calculation.

Public Members

std::vector<std::string> assets

Asset names in column order.

std::vector<double> specific_volatility

Specific volatility per asset.

double market_beta = 0.0

Beta applied to every asset.

struct style_analysis_options

Inputs controlling style exposure construction.

Optional per-asset vectors must either be empty or contain one finite value per asset column. When market_caps is empty the size styles are replaced by equal_weight. value_scores takes precedence over book_to_price when both are supplied.

Public Members

std::span<const double> market_caps = {}

Per-asset market caps.

std::span<const double> book_to_price = {}

Per-asset book-to-price values.

std::span<const double> value_scores = {}

Per-asset value scores.

std::size_t momentum_window = {252U}

Trailing momentum observations.

std::array<double, 2U> size_quantiles = {.5, .5}

Lower and upper size cutoffs in [0, 1].

struct style_analysis_result

Frames produced by style_analysis.

Public Members

dataframe exposures

Asset rows with one column per style.

dataframe returns_by_style

Style names and average style returns.

dataframe overall_returns

Equal-weighted returns on the input index.

attribution_alignment fincore::align_and_warn(const dataframe &returns, const dataframe &positions, const dataframe &factor_returns, const factor_loading_table &factor_loadings)

Aligns attribution inputs to the positions’ assets and loading dates.

Position assets without loadings are dropped (except cash) and dates without loadings are removed from returns, positions and factor returns. Warnings are returned in warnings instead of being emitted. Transaction turnover checks and stacked Series positions are not represented by this typed surface.

Parameters:
  • returns – Portfolio returns to restrict to aligned dates.

  • positions – Position frame whose double columns define the assets.

  • factor_returns – Factor returns to restrict to aligned dates.

  • factor_loadings – Loading labels and flattened values; its value count must equal dates x assets x factors.

Throws:

input_error – If an input index contains adjacent duplicate timestamps, positions are empty, the loading buffer size is inconsistent, or no non-cash position has loadings.

Returns:

The aligned frames, the copied loading table and any warnings.

dataframe fincore::analyze_performance_by_style(const dataframe &asset_returns)

Computes per-style return series using default style analysis.

Runs style_analysis with default options and passes its exposures to the two-frame overload. Empty-shaped input yields an empty frame.

Parameters:

asset_returns – Per-asset simple returns.

Throws:

input_error – If style analysis or performance alignment rejects the input.

Returns:

One <style>_return column per style on an ordinal index.

dataframe fincore::analyze_performance_by_style(const dataframe &asset_returns, const dataframe &style_exposures)

Computes per-style return series from explicit style exposures.

The exposure frame must have an ordinal index, exactly one string asset column named asset and at least one double style column. Rows are aligned to return columns by asset identity; missing assets contribute zero and extra exposure assets are ignored. A style with a positive aligned weight total is normalized to sum to one; a style with a non-positive total produces an all-zero return series. Empty-shaped inputs, or an exposure frame with no double style columns, yield an empty frame.

Parameters:
  • asset_returns – Per-asset simple returns.

  • style_exposures – Asset-by-style exposure table.

Throws:

input_error – If either frame is malformed, asset names are invalid or duplicated, values are non-finite, or arithmetic overflows.

Returns:

A frame with one <style>_return column per exposure style on an ordinal index.

brinson_period_result fincore::brinson_attribution(const dataframe &portfolio_returns, const dataframe &benchmark_returns, const dataframe &portfolio_weights, const dataframe &benchmark_weights, std::span<const std::string_view> sector_column_names)

Computes single-period Brinson-Hood-Beebower attribution.

Every input frame must contain a double column for each sector in sector_column_names and all four frames must share the same unique index. The supplied weights are used as given, without normalization.

Parameters:
  • portfolio_returns – Per-sector portfolio returns by period.

  • benchmark_returns – Per-sector benchmark returns by period.

  • portfolio_weights – Per-sector portfolio weights by period.

  • benchmark_weights – Per-sector benchmark weights by period.

  • sector_column_names – Non-empty distinct sector column names; each name must identify a double column in every input frame.

Throws:

input_error – If the sector names are empty or duplicated, an index contains duplicates, the indexes do not match, a selected column is missing or not a double column, or the result does not contain exactly one row.

Returns:

The allocation, selection, interaction, total, portfolio and benchmark effects for the single period.

brinson_cumulative_result fincore::brinson_cumulative(const dataframe &portfolio_returns, const dataframe &benchmark_returns, const dataframe &portfolio_weights, const dataframe &benchmark_weights, std::span<const std::string_view> sector_column_names)

Computes summed effects and compounded returns across all periods.

The four effect fields are arithmetic sums of the per-period brinson_results columns, while portfolio_cumulative and benchmark_cumulative compound the per-period portfolio and benchmark returns as wealth - 1.

Parameters:
  • portfolio_returns – Per-sector portfolio returns by period.

  • benchmark_returns – Per-sector benchmark returns by period.

  • portfolio_weights – Per-sector portfolio weights by period.

  • benchmark_weights – Per-sector benchmark weights by period.

  • sector_column_names – Non-empty distinct sector column names; each name must identify a double column in every input frame.

Throws:

input_error – If the sector names are empty or duplicated, an index contains duplicates, the indexes do not match, or a selected column is missing or not a double column.

Returns:

The summed effects and compounded portfolio and benchmark returns.

dataframe fincore::brinson_results(const dataframe &portfolio_returns, const dataframe &benchmark_returns, const dataframe &portfolio_weights, const dataframe &benchmark_weights, std::span<const std::string_view> sector_column_names)

Computes one row of Brinson-Hood-Beebower effects per input period.

Each input frame must contain a double column for every sector in sector_column_names, and all four frames must share the same unique index. The result keeps that index and holds the allocation, selection, interaction, total, portfolio_return and benchmark_return columns.

Parameters:
  • portfolio_returns – Per-sector portfolio returns by period.

  • benchmark_returns – Per-sector benchmark returns by period.

  • portfolio_weights – Per-sector portfolio weights by period.

  • benchmark_weights – Per-sector benchmark weights by period.

  • sector_column_names – Non-empty distinct sector column names; each name must identify a double column in every input frame.

Throws:

input_error – If the sector names are empty or duplicated, an index contains duplicates, the indexes do not match, or a selected column is missing or not a double column.

Returns:

A frame indexed like portfolio_returns with the six effect and return columns.

idiosyncratic_risk_result fincore::calculate_idiosyncratic_risk(const dataframe &returns, const dataframe &factor_data, std::optional<double> market_beta = std::nullopt, double risk_free = 0.0)

Calculates asset-specific volatility from factor data.

When market_beta is absent, the beta is fitted by ordinary least squares of the first asset’s excess returns on the five Fama-French columns (MKT, SMB, HML, RMW, CMA) and then applied to every asset, matching the pinned routine. Specific volatility is the square root of total variance minus beta^2 times market variance, using risk-free-shifted population variances; a non-positive residual variance yields zero.

Parameters:
  • returns – Frame with at least one double asset-return column.

  • factor_data – Factor frame with the same row count; it must contain a double MKT column and, when fitting the beta, all five Fama-French columns.

  • market_beta – Optional beta applied to every asset; fitted from the first asset when absent.

  • risk_free – Finite risk-free rate subtracted before variance and beta calculations.

Throws:

input_error – If the risk-free rate or beta is not finite, the frames are empty or have different row counts, a required factor column is missing, there are too few rows to fit the beta, the beta regression is singular, or no asset column exists.

Returns:

The asset names, their specific volatilities and the beta used.

dataframe fincore::calculate_regression_attribution(const dataframe &asset_returns)

Computes automatic style attribution from a default style analysis.

Runs style_analysis with default options, builds style return series with analyze_performance_by_style, and assigns each style its centered Pearson correlation with the equal-weighted portfolio return multiplied by the style’s mean return. The residual is the portfolio mean minus the sum of contributions. A style with fewer than three paired observations or near-zero paired deviation contributes zero. Empty-shaped input yields an empty frame.

Parameters:

asset_returns – Per-asset simple returns.

Throws:

input_error – If style analysis, performance alignment or attribution validation rejects the input.

Returns:

A frame with style and contribution columns plus a final residual row.

dataframe fincore::calculate_regression_attribution(const dataframe &portfolio_returns, const dataframe &style_returns, std::span<const std::string_view> selected_styles)

Computes style attribution for explicit portfolio and style returns.

The portfolio series is the row-wise mean of all double columns in portfolio_returns. Selected style columns are aligned by timestamp; a style contributes its centered Pearson correlation with the portfolio series multiplied by its mean on the aligned timestamps. Styles are emitted in style_returns column order, followed by the residual row, which uses the full portfolio mean. Unmatched selectors are ignored. A style with fewer than three paired timestamps or near-zero aligned deviation contributes zero. An empty-shaped portfolio yields an empty frame.

Parameters:
  • portfolio_returns – One or more double portfolio return columns.

  • style_returns – Candidate style return columns.

  • selected_styles – Style column names to attribute; empty names, duplicates and residual are rejected.

Throws:

input_error – If selectors are malformed, a non-empty portfolio has invalid columns or values, a selected style column has invalid structure or non-finite values, or arithmetic overflows.

Returns:

A frame with style and contribution columns plus a final residual row.

dataframe fincore::calculate_style_tilts(const dataframe &asset_returns, std::size_t window = 252U)

Computes rolling cross-sectional style tilt indicators.

Each output row uses the trailing window observations ending before that row. Size splits the average rank of the latest return at the one-third and two-thirds cutoffs (lower third _large, upper third _small); winner/loser splits the compounded trailing return at zero; value/growth splits its average rank at the median; high/low volatility splits the sample deviation of at most the last 60 observations at the median, with ties assigned to high volatility. Output columns are phase-major: all <asset>_large columns, then all <asset>_small columns, then <asset>_winner, <asset>_loser, <asset>_value, <asset>_growth, <asset>_high_vol and <asset>_low_vol, with assets in input column order within each phase.

Parameters:
  • asset_returns – Per-asset simple returns.

  • window – Trailing observations used for ranks and momentum; defaults to 252.

Throws:

input_error – If the frame contains non-double columns, invalid or duplicate asset names, non-finite returns, or an unrepresentable output becomes necessary.

Returns:

A binary tilt frame whose index starts at the first eligible row, or an empty frame when fewer than three rows or fewer than two usable trailing observations are available.

dataframe fincore::factor_attribution_decomposition(const dataframe &returns, const dataframe &factor_returns, std::span<const std::string_view> factor_column_names, double risk_free_rate = 0.0, std::string_view returns_column_name = returns_column)

Decomposes mean returns into alpha, factor, specific, common and unexplained components.

The factors are fitted by ordinary least squares, each factor contributes beta * mean(factor), and specific_return is the sum of those contributions. common_return is mean(returns) - risk_free_rate and unexplained is common_return - alpha - specific_return. The output index is ordinal and rows follow this order: alpha, each <factor>_attribution in request order, specific_return, common_return and unexplained.

Parameters:
  • returns – Frame containing the dependent return column.

  • factor_returns – Frame containing the factor columns.

  • factor_column_names – Non-empty distinct factor names; alpha is reserved and must not be selected.

  • risk_free_rate – Risk-free rate subtracted when forming the common return; must be finite.

  • returns_column_name – Double column used as the dependent variable.

Throws:

input_error – If the selectors, risk-free rate, regression inputs or arithmetic results are invalid or non-finite.

Returns:

A frame with component and contribution columns and an ordinal index.

dataframe fincore::factor_regression_predictions(const factor_regression_result &regression, const dataframe &factor_returns, std::span<const std::string_view> factor_column_names)

Predicts returns from a fitted factor regression.

The coefficient table in regression must be structurally valid: an ordinal index of length K + 1 and the factor/coefficient columns, with alpha first and the remaining labels matching factor_column_names in order. Predictions are alpha + sum(beta_i * factor_i) for each input row.

Parameters:
  • regression – Previously fitted factor regression.

  • factor_returns – Frame containing the requested factor columns.

  • factor_column_names – Non-empty distinct factor names matching the coefficient labels; alpha is reserved.

Throws:

input_error – If the selectors, coefficient table, selected factor values or arithmetic results are invalid or non-finite.

Returns:

A frame indexed like factor_returns with one predicted_returns double column.

dataframe fincore::fetch_ff_factors(std::string_view start, std::string_view end, std::string_view library, const fama_french_provider &provider, bool copy = true)

Fetches Fama-French factors through an explicit provider.

copy is retained for source-signature compatibility. Native results always own their buffers; a provider cannot hand ownership of cached data to the caller, so both values of copy return a detached value.

Parameters:
  • start – Non-empty start date passed to the provider.

  • end – Non-empty end date passed to the provider.

  • library – Non-empty factor library name.

  • provider – Callable returning a non-empty frame with at least one supported column.

  • copy – Retained for source compatibility; ignored.

Throws:

fincore_error – If the provider is not callable, a date or library is empty, or the provider returns an empty or column-less frame.

Returns:

The provider’s validated frame, owned by the caller.

dataframe fincore::fetch_ff_factors(std::string_view start, std::string_view end, const fama_french_provider &provider, std::string_view library = "french", bool copy = true)

Fetches Fama-French factors with the library defaulting to french.

Parameters:
  • start – Non-empty start date passed to the provider.

  • end – Non-empty end date passed to the provider.

  • provider – Callable returning a non-empty frame with at least one supported column.

  • library – Non-empty factor library name; defaults to french.

  • copy – Retained for source compatibility; ignored.

Throws:

fincore_error – If the provider is not callable, a date or library is empty, or the provider returns an empty or column-less frame.

Returns:

The provider’s validated frame, owned by the caller.

dataframe fincore::fetch_style_factors(const std::vector<std::string> &tickers, const std::optional<std::vector<std::string>> &factors, std::string_view library, const style_factor_provider &provider)

Fetches style factors through an injected provider.

Parameters:
  • tickers – Non-empty ticker list with no empty entries.

  • factors – Optional factor names passed through unchanged; std::nullopt mirrors the source’s None.

  • library – Factor library name; must not be empty.

  • provider – Callable returning a non-empty frame with at least one supported column.

Throws:

fincore_error – If the tickers, library or provider are invalid, or the provider returns an empty or column-less frame.

Returns:

The provider’s validated frame, owned by the caller.

dataframe fincore::fetch_style_factors(const std::vector<std::string> &tickers, const std::optional<std::vector<std::string>> &factors, const style_factor_provider &provider, std::string_view library = "us")

Fetches style factors with the library defaulting to us.

Parameters:
  • tickers – Non-empty ticker list with no empty entries.

  • factors – Optional factor names passed through unchanged.

  • provider – Callable returning a non-empty frame with at least one supported column.

  • library – Factor library name; defaults to us.

Throws:

fincore_error – If the tickers, library or provider are invalid, or the provider returns an empty or column-less frame.

Returns:

The provider’s validated frame, owned by the caller.

factor_regression_result fincore::fit_factor_regression(const dataframe &returns, const dataframe &factor_returns, std::span<const std::string_view> factor_column_names, std::string_view returns_column_name = returns_column)

Fits an ordinary least-squares factor regression with an intercept.

The dependent column is regressed on the named factor columns. Both frames must share the same unique index, selected values must be finite, and at least K + 1 observations are required for K factors. The fit uses a Householder QR solve and rejects rank-deficient designs.

Parameters:
  • returns – Frame containing the dependent return column.

  • factor_returns – Frame containing the factor columns.

  • factor_column_names – Non-empty distinct factor names; alpha is reserved and must not be selected.

  • returns_column_name – Double column used as the dependent variable.

Throws:

input_error – If the selectors are empty, duplicated or reserved, the indexes are duplicated or mismatched, a selected column is missing or non-finite, there are fewer than K + 1 observations, the design is rank deficient, or an intermediate is not finite.

Returns:

The intercept, R-squared, coefficient table, fitted values and residuals.

dataframe fincore::rolling_factor_exposures(const dataframe &returns, const dataframe &factor_returns, std::span<const std::string_view> factor_column_names, std::optional<std::size_t> rolling_window = std::nullopt, std::string_view returns_column_name = returns_column)

Computes rolling or expanding factor exposures by least squares.

Each output row fits the requested factors on the window ending at that row. A supplied rolling_window limits the window to that many trailing observations; std::nullopt uses an expanding window from the first row. Rows with at most K observations for K factors are NaN.

Parameters:
  • returns – Frame containing the dependent return column.

  • factor_returns – Frame containing the factor columns.

  • factor_column_names – Non-empty distinct factor names; alpha is reserved and must not be selected.

  • rolling_window – Optional trailing window length; must be positive when supplied.

  • returns_column_name – Double column used as the dependent variable.

Throws:

input_error – If selectors are empty, duplicated, reserved or malformed, the window is zero, an index is duplicated or mismatched, a selected value is non-finite, an eligible window is rank deficient, or arithmetic overflows.

Returns:

A frame indexed like returns with alpha followed by one double column per requested factor.

style_analysis_result fincore::style_analysis(const dataframe &asset_returns, const style_analysis_options &options = {})

Computes style exposures and style return summaries.

Every asset column must be double, have a distinct non-empty name and contain finite values. The exposure table has one row per asset and one column per constructed style; returns_by_style reports each style’s arithmetic mean return; overall_returns reports the equal-weighted portfolio return on the input timestamps. A style with no eligible assets receives zero weights and a NaN summary return.

Parameters:
  • asset_returns – Per-asset simple returns; every column is an asset.

  • options – Style construction options; per-asset vectors must be empty or match the asset count.

Throws:

input_error – If the frame is empty, contains non-double columns, empty or duplicate asset names, non-finite returns or option values, size quantiles outside [0, 1], or unrepresentable sizes.

Returns:

Exposure, style-return summary and overall-return frames, each owning its data.

using fincore::FamaFrenchModelPatch = FamaFrenchModel

Source-compatible compatibility facade for fincore.attribution.fama_french_patch.FamaFrenchModelPatch.

The patch module documented the same model specification fields as the canonical Fama-French model (model_type, risk_free_rate, selected factors and fitted betas). It adds no independent computation in the pinned source, so the native alias deliberately maps to the owning FamaFrenchModel rather than duplicating estimation state.

using fincore::fama_french_provider = std::function<dataframe(std::string_view start, std::string_view end, std::string_view library)>

Injected provider boundary for Fama-French data.

The provider is supplied explicitly on every call; there is no process-global provider or cache state. The returned frame is validated and detached (deep-copied) by fetch_ff_factors.

using fincore::style_factor_provider = std::function<dataframe(const std::vector<std::string> &tickers, const std::optional<std::vector<std::string>> &factors, std::string_view library)>

Injected style-factor provider boundary.

The provider receives an explicit factors option (nullopt mirrors the source’s None) and returns a validated, detached frame.

constexpr std::array<std::string_view, 3U> fincore::FF3_FACTORS{"MKT", "SMB", "HML"}

Standard three-factor Fama-French definitions, matching the pinned source.

constexpr std::array<std::string_view, 4U> fincore::FF4MOM_FACTORS{"MKT", "SMB", "HML", "MOM"}

Four-factor Fama-French definitions with the momentum factor.

constexpr std::array<std::string_view, 5U> fincore::FF5_FACTORS{"MKT", "SMB", "HML", "RMW", "CMA"}

Standard five-factor Fama-French definitions, matching the pinned source.

constexpr std::string_view fincore::brinson_allocation_column = {"allocation"}

Name of the Brinson allocation-effect column.

constexpr std::string_view fincore::brinson_benchmark_return_column{"benchmark_return"}

Name of the Brinson benchmark-return column.

constexpr std::string_view fincore::brinson_interaction_column = {"interaction"}

Name of the Brinson interaction-effect column.

constexpr std::string_view fincore::brinson_portfolio_return_column{"portfolio_return"}

Name of the Brinson portfolio-return column.

constexpr std::string_view fincore::brinson_selection_column = {"selection"}

Name of the Brinson selection-effect column.

constexpr std::string_view fincore::brinson_total_column = {"total"}

Name of the Brinson total-effect column.

constexpr std::string_view fincore::factor_attribution_component_column{"component"}

Name of the component-label column in an attribution summary.

constexpr std::string_view fincore::factor_attribution_contribution_column{"contribution"}

Name of the contribution-value column in an attribution summary.

constexpr std::string_view fincore::factor_prediction_column = {"predicted_returns"}

Name of the predicted-return column.

constexpr std::string_view fincore::factor_regression_alpha_name = {"alpha"}

Label used for the regression intercept.

constexpr std::string_view fincore::factor_regression_coefficient_column{"coefficient"}

Name of the coefficient-value column in a coefficient frame.

constexpr std::string_view fincore::factor_regression_factor_column = {"factor"}

Name of the factor-label column in a coefficient frame.

constexpr std::string_view fincore::factor_regression_fitted_column{"fitted_returns"}

Name of the fitted-return column.

constexpr std::string_view fincore::factor_regression_residual_column{"residuals"}

Name of the residual column.

constexpr std::string_view fincore::style_asset_column = {"asset"}

Name of the string column holding asset identifiers in exposures.

constexpr std::string_view fincore::style_attribution_contribution_column{"contribution"}

Name of the double column holding style attribution contributions.

constexpr std::string_view fincore::style_attribution_residual_name = {"residual"}

Name of the residual row in style attribution results.

constexpr std::string_view fincore::style_equal_weight_column = {"equal_weight"}

Name of the equal-weight style column.

constexpr std::string_view fincore::style_growth_column = {"growth"}

Name of the growth style column.

constexpr std::string_view fincore::style_high_column = {"high"}

Name of the high-volatility style column.

constexpr std::string_view fincore::style_large_column = {"large"}

Name of the large-cap size style column.

constexpr std::string_view fincore::style_loser_column = {"loser"}

Name of the momentum-loser style column.

constexpr std::string_view fincore::style_low_column = {"low"}

Name of the low-volatility style column.

constexpr std::string_view fincore::style_mid_column = {"mid"}

Name of the mid-cap size style column.

constexpr std::string_view fincore::style_name_column = {"style"}

Name of the string column holding style names.

constexpr std::string_view fincore::style_return_column = {"return"}

Name of the double column holding style or portfolio returns.

constexpr std::string_view fincore::style_small_column = {"small"}

Name of the small-cap size style column.

constexpr std::string_view fincore::style_value_column = {"value"}

Name of the value style column.

constexpr std::string_view fincore::style_winner_column = {"winner"}

Name of the momentum-winner style column.