skfolio.datasets.make_synthetic_characteristics#
- skfolio.datasets.make_synthetic_characteristics(n_assets=500, n_observations=2520, *, n_industries=10, start_date='2015-01-01', systematic_variance_ratio=0.5, late_listing_proba=0.15, delisting_proba=0.15, missing_ratio=0.01, random_state=None)[source]#
Generate a synthetic characteristics
AssetPanel.The panel generated contains the minimal set of fields required by the default
skfoliodescriptors andCharacteristicsFactorModel. It is designed so that fitting a characteristics factor model produces realistic diagnostics: a cross-sectional regression \(R^2\) away from the degenerate values of \(0\) and \(1\), non-trivial information coefficients and idiosyncratic returns with fat tails.Returns are drawn from a factor structure
\[r_{i,t} = \beta_i\,f^{\mathrm{mkt}}_t + f^{\mathrm{ind}(i)}_t + \sum_k B_{i,k}\,f^{k}_t + \varepsilon_{i,t},\]where the per-asset loadings \(B\) are persistent traits. Characteristics are then constructed so that the descriptor of each style is a noisy proxy of the corresponding loading, while accounting identities (for example \(\text{market\_cap} = \text{adj\_close} \times \text{adj\_shares\_outstanding}\)) are preserved.
Fields produced:
returns,adj_close,adj_volume,adj_shares_outstanding,market_cap,ebitda_ttm,enterprise_value,net_income_ttm,sales_ttm,dividends_ttm,net_buybacks_ttm,book_equity,operating_cash_flow_ttm,total_debt,total_assets,industry,cost_of_revenue_ttm,capex_ttm,short_interest,eps_ntm,dps_ntm,eps_ntm_std.- Parameters:
- n_assetsint, default=500
Number of assets (coverage universe).
- n_observationsint, default=2520
Number of observations.
- n_industriesint, default=10
Number of industry groups. Must not exceed 16.
- start_datestr, default=”2015-01-01”
First observation date. Observations follow a business-day calendar.
- systematic_variance_ratiofloat, default=0.5
Share of cross-sectional return variance explained by the factor structure. The realized cross-sectional regression \(R^2\) of a fitted model is close to this value. Must lie in the open interval \((0, 1)\).
- late_listing_probafloat, default=0.15
Probability that an asset lists after the first observation.
- delisting_probafloat, default=0.15
Probability that an asset delists before the last observation.
- missing_ratiofloat, default=0.01
Fraction of active fundamental observations set to NaN to emulate reporting gaps. Price, volume, shares and market cap are left intact.
- random_stateint, optional
Seed for the random number generator.
- Returns:
- panelAssetPanel
Synthetic asset panel with the fields listed above.
industryis aFieldCategorical.
Notes
The generator is driven by a small set of time-invariant latent asset traits (size, value, quality, risk, growth and liquidity). These traits set the factor loadings \(B\), the market beta and the idiosyncratic volatility level and anchor the level of every fundamental and market field so that accounting identities (such as \(\text{market\_cap} = \text{adj\_close} \times \text{adj\_shares\_outstanding}\)) hold. Each characteristic is therefore a noisy proxy of the trait that drives its matching style factor.
Factor returns combine a fat-tailed market factor, zero-mean industry factors and mean-reverting style factors. Idiosyncratic returns mix a transitory shock with a slow persistent component and a fast mean-reverting component. These give the momentum and short-term reversal factors a realistic positive Sharpe without changing the idiosyncratic variance.
To support alpha-research examples, the idiosyncratic shock also contains a small predictable component driven by a persistent latent bearish signal \(z_{i,t}\). Short interest and analyst forecast dispersion are constructed as noisy increasing functions of \(z_{i,t}\), while the next-period return contribution is
\[\varepsilon^{\mathrm{signal}}_{i,t+1} = -\sigma_i\sqrt{w_{\mathrm{signal}}}\,z_{i,t}.\]Consequently, high values of either descriptor predict lower future idiosyncratic returns without same-period look-ahead.
Forward-looking and lower-coverage fields (
eps_ntm,dps_ntm,eps_ntm_std,enterprise_value,ebitda_ttmandcost_of_revenue_ttm) carry partial coverage to mirror real data, while price, volume, shares and market cap are always populated on active assets.Examples
>>> from skfolio.datasets import make_synthetic_characteristics >>> panel = make_synthetic_characteristics(n_assets=200, n_observations=1000) >>> panel.n_assets, panel.n_observations (200, 1000)