← Back to Home

Equity Fingerprint

Reads a Swiss stock's sector, size, volatility, beta and liquidity from its daily price and volume alone.

Oct 2026 · Personal research project

Overview

Equity Fingerprint asks how much of a company's identity is already written in its price and volume history. The universe is the SIX Swiss Exchange primary listings: 231 tickers, of which 207 had at least 252 prior trading rows and enter the experiments. Daily prices run from 2010-01-04 to 2026-10-07, with 28,016 month end observations from 2014-03. Five targets are read back from that history: the next month's volatility, the next year's beta against the SPI, the next month's traded value, the current market cap, and the sector.

How the data is split

Forward targets train to 2021-12-31, validate on 2022 to 2023 and test from 2024-01-01; for vol_1m that is 16,326, 4,326 and 6,473 observations. Stock targets (sector, log_mcap) use issuer grouped 5 fold cross validation with 10 repeats on 203 and 204 stocks.

Time split for the forward targets, folds for the stock targets. Counts from the committed results files.

What I built

Results

Static targets get one row per stock and are scored with repeated issuer grouped 5 fold cross validation. Forward targets are scored on the 2024 test period and read against a persistence model that only knows the same quantity measured one period earlier. The table below holds the headline numbers.

Headline results: target, model, metric, value and 95% interval or reference.
TargetModelMetricValue95% interval or reference
sectorknn_automacro F10.578[0.505, 0.631], 203 stocks
log_mcapridge_md_extR²0.922[0.896, 0.940], 204 stocks
vol_1mlgbm_fefpfaR²0.630persistence 0.426
beta_1yfpnet_aR²0.630persistence 0.522
beta_1yavg_long2011R²0.650persistence 0.522; +0.016 [+0.006, +0.027] with history from 2011
liquidity_1mlgbm_fefpfaR²0.957persistence 0.949

What can be read back

Size and liquidity are the easiest, volatility and beta are the ones where a model clearly beats yesterday's value, and the sector is the hardest of the five.

What can be read back

Sector macro F1 0.578 on 203 stocks, market cap R² 0.922 on 204 stocks. Forward R² on the 2024 test period: vol_1m 0.630 against 0.426 for persistence, beta_1y 0.630 (0.650 with history from 2011) against 0.522, liquidity_1m 0.957 against 0.949.

Mean over repeats with 95% stock bootstrap intervals for the stock targets; test R² for the forward targets. Source: assets/equity-fingerprint/evidence.json.

Where the sector signal lives

Stocks of one sector tend to move together once the market move is taken out. The map places the 203 stocks by that shared movement; pick a stock to see its nearest neighbours. The matrix below shows which sectors the model mixes up.

Stocks placed by how their returns move together

203 Swiss stocks laid out by the similarity of their daily returns and coloured by sector. Nearest neighbours tend to share a sector, which is why the kNN model reaches macro F1 0.578.

New computation for this page: t-SNE layout of Spearman correlations of daily returns after removing the first principal component (the matrix the sector model chose most often). Positions are a layout aid; only near neighbours carry meaning.

Where the sector model is wrong

Real Estate (82.2% of predictions right), Healthcare (79.7%) and Financial Services (77.3%) are read best. Consumer Cyclical (26.4%), Basic Materials (31.1%) and Communication Services (37.1%, 7 stocks) are read worst.

Rows are the true sector, columns the predicted one, from knn_auto summed over 10 repeats of issuer grouped 5 fold cross validation.

Size from price and volume

Traded value carries most of the size signal. Adding several past month ends per stock lifts R² from 0.891 to 0.922.

Market cap from price and volume

Predicted against true market cap for 204 stocks: R² 0.922 across repeats, 0.925 for the mean of the 10 out of fold predictions.

Each point averages the stock's 10 out of fold predictions (ridge_md_ext, issuer grouped folds); the headline R² 0.922 is the mean of the per repeat R².

What the features add

Engineered features beat the 4 raw ones for most targets, and a few add ons moved the score beyond noise. A pretrained encoder did not.

Raw prices against engineered features

With a linear model the 39 engineered features beat the 4 raw ones for sector (macro F1 0.104 to 0.313), vol_1m (0.490 to 0.609), beta_1y (0.429 to 0.632) and liquidity_1m (0.933 to 0.950), but not for log_mcap (0.808 to 0.762).

Single test split. The log_mcap drop is within seed noise: over five ticker splits the linear gap averages +0.017 (sd 0.037).

What the tree model leans on

Top feature by gain share: Volatility 63d for vol_1m (23.7%), Beta vs SPI 252d for beta_1y (50.4%), Log traded value 63d for liquidity_1m (46.7%), Amihud illiquidity 63d for log_mcap (56.5%), Log close for sector (11.3%).

LightGBM (lgbm_fe) gain share on the engineered features, v1 benchmark.

What helped and what did not

Of 15 add on results, 5 helped (interval above zero), 5 are within noise and 5 are single split v4 arms without an interval. None hurt.

Change in the metric against the named reference, with 95% intervals. Source files are listed per row.

The same kind of kNN scores macro F1 0.766 on 850 European stocks against 0.579 on the Swiss ones, which fits the small number of Swiss stocks limiting sector accuracy.

Limits

Links