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
BrinsonAttributioncalculator.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_resultskernel. 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 integerperiodcolumn 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
calculateruns.- Parameters:
sector_mapping – Sector name to asset-column mapping; empty disables sector aggregation.
-
const std::map<std::string, std::vector<std::string>> §or_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
methodargument acceptsbrinsonand the historicalbrinson_hoodalias, 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
methodis 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
returnswith the allocation, selection, interaction, total, portfolio-return and benchmark-return columns.
-
explicit BrinsonAttribution(std::map<std::string, std::vector<std::string>> sector_mapping = {})
-
class FamaFrenchModel
Native owning Fama-French model facade.
The model stores its specification (
3factor,5factoror4factor_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,5factoror4factor_mom.risk_free_rate – Finite risk-free rate stored with the model.
- Throws:
fincore_error – If
model_typeis 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,5factoror4factor_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_columnselects 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 thefitted_returnscolumn.- 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_datawith onefitted_returnscolumn.
-
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_windowselects a trailing window;std::nulloptor zero uses an expanding window from the first row. Rows with at mostKobservations forKfactors 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
returnswithalphafollowed 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>_attributionentry 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) andunexplained(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.
-
explicit FamaFrenchModel(std::string model_type = "5factor", double risk_free_rate = 0.0)
-
class StyleResult
Native owning facade for
StyleResult.The source container exposes
exposures,returns_by_styleandoverall_returnsplus 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 returnmapping in deterministic key order.The
styleandreturncolumns ofreturns_by_styleare 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.
-
StyleResult(dataframe exposures, dataframe returns_by_style, dataframe overall_returns)
-
struct attribution_alignment
Attribution inputs after asset and date alignment.
Public Members
-
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.
-
factor_loading_table factor_loadings
-
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.
-
double allocation
-
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.
-
double allocation
-
struct factor_loading_table
Factor-loading table aligned by date, asset and factor labels.
valuesis a flatteneddates x assets x factorsbuffer; NaN marks a missing loading.align_and_warnrequires its length to match the label dimensions and uses the date and asset labels for alignment.
-
struct factor_regression_result
Result of an ordinary least-squares factor regression.
All frames own their data.
coefficientshas an ordinal index and the columnsfactorandcoefficient, withalphafirst followed by the requested factor names in request order.
-
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_valuesare deliberately absent rather than fabricated.
-
struct idiosyncratic_risk_result
Result of the idiosyncratic-risk calculation.
-
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_capsis empty the size styles are replaced byequal_weight.value_scorestakes precedence overbook_to_pricewhen 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].
-
std::span<const double> market_caps = {}
-
struct style_analysis_result
Frames produced by
style_analysis.
-
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 inwarningsinstead 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_analysiswith 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>_returncolumn 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
assetand 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>_returncolumn 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_namesand 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_resultscolumns, whileportfolio_cumulativeandbenchmark_cumulativecompound the per-period portfolio and benchmark returns aswealth - 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 theallocation,selection,interaction,total,portfolio_returnandbenchmark_returncolumns.- 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_returnswith 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_betais 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 minusbeta^2times 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
MKTcolumn 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_analysiswith default options, builds style return series withanalyze_performance_by_style, and assigns each style its centered Pearson correlation with the equal-weighted portfolio return multiplied by the style’s mean return. Theresidualis 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
styleandcontributioncolumns plus a finalresidualrow.
-
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 instyle_returnscolumn order, followed by theresidualrow, 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
residualare 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
styleandcontributioncolumns plus a finalresidualrow.
-
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
windowobservations 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>_largecolumns, then all<asset>_smallcolumns, then<asset>_winner,<asset>_loser,<asset>_value,<asset>_growth,<asset>_high_voland<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), andspecific_returnis the sum of those contributions.common_returnismean(returns) - risk_free_rateandunexplainediscommon_return - alpha - specific_return. The output index is ordinal and rows follow this order:alpha, each<factor>_attributionin request order,specific_return,common_returnandunexplained.- Parameters:
returns – Frame containing the dependent return column.
factor_returns – Frame containing the factor columns.
factor_column_names – Non-empty distinct factor names;
alphais 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
componentandcontributioncolumns and an ordinal index.
-
dataframe fincore::factor_regression_predictions(const factor_regression_result ®ression, const dataframe &factor_returns, std::span<const std::string_view> factor_column_names)
Predicts returns from a fitted factor regression.
The coefficient table in
regressionmust be structurally valid: an ordinal index of lengthK + 1and thefactor/coefficientcolumns, withalphafirst and the remaining labels matchingfactor_column_namesin order. Predictions arealpha + 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;
alphais 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_returnswith onepredicted_returnsdouble 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.
copyis 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 ofcopyreturn 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::nulloptmirrors the source’sNone.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 + 1observations are required forKfactors. 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;
alphais 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 + 1observations, 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_windowlimits the window to that many trailing observations;std::nulloptuses an expanding window from the first row. Rows with at mostKobservations forKfactors 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;
alphais 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
returnswithalphafollowed 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_stylereports each style’s arithmetic mean return;overall_returnsreports 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, selectedfactorsand fittedbetas). It adds no independent computation in the pinned source, so the native alias deliberately maps to the owningFamaFrenchModelrather 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
factorsoption (nulloptmirrors the source’sNone) 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.