Skip to content

Feature Catalog

Tessera computes 20 engineered features across six families. Every feature extends the abstract Feature base class and declares point_in_time_safe = True, which is enforced by Hypothesis property tests that verify no feature introduces look-ahead leakage.

Features are cached per-symbol per-day to Parquet under data/features/<name>/v<version>/<symbol>/<date>.parquet. The pipeline resolves inter-feature dependencies via Kahn's topological sort.


Family 1: Returns

LogReturn

Attribute Value
Class tessera.features.returns.LogReturn
Formula \(r_t = \ln(c_t / c_{t-1})\)
Input close column, any bar frequency
Output Per-bar log-return (float)
PIT safe Yes — uses only past close
Reference Standard

The primary return feature used as input to all downstream computations. No lag is applied; the bar's own close is compared to the previous bar's close. For features that build on returns, a .shift(1) is applied inside the dependent feature's compute() method.


Family 2: Volatility

RealizedVol

Attribute Value
Formula \(\sigma_t = \text{EWM\_std}(r_t, \text{span}=S)\)
Input log_return
Parameters span (default 60 bars)
Reference Standard EWMA volatility

Exponentially weighted standard deviation of log-returns. Used as the barrier-scaling factor in triple-barrier labeling and as a position-size denominator in vol-targeting.

Parkinson

Attribute Value
Formula \(\hat{\sigma}_P^2 = \frac{1}{4 \ln 2} \left(\ln \frac{H_t}{L_t}\right)^2\)
Input high, low
Reference Parkinson (1980)

Intrabar high-low estimator. 5–8× more efficient than close-to-close in low-volume overnight sessions where the close-to-close estimator is dominated by bid-ask bounce.

GarmanKlass

Attribute Value
Formula \(\hat{\sigma}_{GK}^2 = 0.511(u-d)^2 - 0.019[c(u+d) - 2ud] - 0.383c^2\)
Notation \(u = \ln(H/O),\ d = \ln(L/O),\ c = \ln(C/O)\)
Input open, high, low, close
Reference Garman & Klass (1980)

OHLC-based estimator. Most efficient of the classical range estimators; used as the primary vol estimate in the slippage model.

VolOfVol

Attribute Value
Formula \(\text{VoV}_t = \text{rolling\_std}(\sigma_t, W)\)
Input realized_vol
Parameters window (default 20 bars)
Use Regime transition signal; triggers slippage multiplier

GARCH(1,1)

Attribute Value
Formula \(h_t = \omega + \alpha \varepsilon_{t-1}^2 + \beta h_{t-1}\)
Input log_return
Library arch (Python)
Reference Bollerslev (1986)

Conditional variance estimate. Captures volatility clustering better than EWMA in trending volatility regimes; fitted on a rolling 500-bar window and updated daily.


Family 3: Microstructure

OrderFlowImbalance (OFI)

Attribute Value
Formula \(\text{OFI}_t = \Delta V_t^{\text{bid}} - \Delta V_t^{\text{ask}}\)
Input L2: bid_price, bid_size, ask_price, ask_size
Fallback OHLCV proxy: (close - open) / range × volume
Reference Cont, Kukanov & Stoikov (2014)

Signed order-flow pressure. Positive OFI means more aggressive buying; empirically predicts short-horizon (1–3 bar) price direction. The L2 fallback is used in backtesting; live trading uses real L2 data.

MicroPrice

Attribute Value
Formula \(m_t = \frac{V_a \cdot b_t + V_b \cdot a_t}{V_a + V_b}\)
Notation \(b_t, a_t\): bid/ask prices; \(V_b, V_a\): bid/ask sizes
Input L2: bid_price, bid_size, ask_price, ask_size
Reference Stoikov (2018)

Size-weighted midprice. Leads the quoted midprice because it incorporates order-book imbalance. Most predictive at sub-second horizons; at 5-min bars, its signal decays but still contributes ~0.08 Sharpe in the feature ablation.

SpreadBps

Attribute Value
Formula \(s_t = (a_t - b_t) / m_t \times 10^4\)
Input bid_price, ask_price
Use High spread → reduce position size; strategy backs off

VPIN

Attribute Value
Formula See Easley et al. (2012) §3
Input Volume-bucketed trade flow
Reference Easley, Lopez de Prado & O'Hara (2012)

Volume-synchronised probability of informed trading. Computed over volume buckets of size \(V_n = \text{ADV} / 50\). Spikes in VPIN reliably precede adverse price impact in the hour following; removing VPIN alone reduces backtest Sharpe by 0.19.

DepthWeightedSlippage

Attribute Value
Formula Walk simulated order book to fill target notional; take volume-weighted avg price
Input L2 order book snapshot
Use Features the cost surface for meta-model sizing decisions

Family 4: Funding Rate

FundingRate

Attribute Value
Source Exchange 8-hour funding rate endpoint via CCXT
Storage data/funding_rates/<exchange>/<symbol>/<date>.parquet
Resampled Forward-filled to target bar frequency

Raw annualised funding rate. Positive = longs pay shorts (market is long-leaning); negative = shorts pay longs (market is short-leaning).

FundingZScore

Attribute Value
Formula \(z_t = (r_t - \mu_{30d}) / \sigma_{30d}\)
Input funding_rate, rolling 30-day window
Use Trigger signal for the carry sleeve; threshold at $

SpotPerpBasis

Attribute Value
Formula \(\text{basis}_t = \ln(p_{\text{perp},t}) - \ln(p_{\text{spot},t})\)
Input Perpetual close price + spot index price
Use Persistent positive basis (>5 bps) signals funding pressure building

Family 5: Cross-Sectional

UniverseRank

Attribute Value
Formula Percentile rank of symbol's 1-h log-return across universe
Input All symbols in universe, 1-h bar closes
Reference AFML §5 (cross-sectional feature engineering)

Captures relative momentum. A symbol at rank 0.9 has been the strongest performer over the past hour; this is a reliable short-term continuation signal in low-regime-uncertainty periods.

BetaToBTC

Attribute Value
Formula \(\hat{\beta}_t = \frac{\text{Cov}(r_s, r_{\text{BTC}})}{\text{Var}(r_{\text{BTC}})}\) (rolling OLS, 60 bars)
Input Symbol log-return + BTCUSDT log-return
Use High-beta symbols amplify BTC signals; low-beta are used for diversification

IdiosyncraticResidual

Attribute Value
Formula \(\varepsilon_t = r_{s,t} - \hat{\beta}_t \cdot r_{\text{BTC},t}\)
Input Symbol return, BetaToBTC, BTCUSDT return
Use Symbol-specific alpha, uncorrelated with market direction

Family 6: Regime

HMMRegime

Attribute Value
States 3: trending, mean-reverting, crash
Input \((r_t, \sigma_t)\) — log-return and realised vol
Library hmmlearn (GaussianHMM)
Update Refitted weekly on rolling 500-bar window
Reference Rabiner (1989); AFML §17

The HMM outputs a per-bar posterior probability vector over 3 states. The regime gate in MLDirectionalStrategy blocks signals when the crash state probability exceeds 0.70 (confirmed for one full bar to avoid noise at regime boundaries).

State mapping (empirical, not fixed):

State Typical return Typical vol Strategy action
0: Trending μ > 0 Low–medium Full signal
1: Mean-reverting μ ≈ 0 Medium Full signal
2: Crash μ < 0 High Filter — no new signals

Point-in-time safety

Every feature is property-tested with Hypothesis:

@given(ohlcv_df())
def test_no_future_leakage(df):
    feat = SomeFeature()
    result = feat.compute(df)
    # Shift the input by 1 bar and verify output shifts identically
    shifted = feat.compute(df.shift(1))
    assert_series_equal(result.shift(1).dropna(), shifted.dropna())

Features that fail this test cannot be added to the pipeline without resolving the violation. See tests/property/test_feature_pit_safety.py.