Class Factors
AlphaFactor producing raw cross-sectional scores where
higher = more attractive long (see the interface contract).
Sign conventions are chosen so every factor is usable long/short as-is:
- Trend (MA crossover, MACD, momentum) score positively when the trend is up;
- Mean reversion (RSI, Bollinger, mean reversion) score positively when the price is depressed — the contrarian orientation, since these signals bet on the snap-back;
- Defensive/fundamental (value, quality, low volatility) score positively for cheap, profitable, calm names — the Fama-French/AQR orientation of each anomaly.
All computations read only bars <= index (the no-look-ahead
contract) and cost O(window) per symbol per call. They are stateless,
so they can be evaluated at arbitrary dates, at the price of recomputing
windows the streaming indicators would carry. EMAs are truncated at 4×
their period and seeded with the first price of that window; the dropped
tail weight is (1−2/(p+1))^{4p} < 0.04%.
EMA definitions differ from indicators.Indicators.
Indicators.ema seeds with the SMA of the first period
bars of the whole series and runs from bar 0; the factors here seed with
the first price of a 4×slow window ending at the scored bar. The
two converge as the seed's weight decays, but macd(int, int, int) and
Indicators.macd are not the same number on short histories, in
the same way rsi(int) (Cutler) is not Wilder's RSI.
Cross-sectional preparation. Raw technical scores are
dominated by market and sector moves in trending regimes, and their rank
IC then measures beta timing. winsorized(AlphaFactor, double), standardized(AlphaFactor)
and sectorNeutralized(AlphaFactor, Map) are per-date decorators; prepared(AlphaFactor, double, Map)
applies them in the order that is correct for fat-tailed raw scores:
winsorise the raw score, then z-score, then demean within sector.
Fundamentals are read through
AlphaContext.fundamentalsAsOf(int, int): point-in-time with a
FundamentalsHistory; with only a static snapshot they can be
scored at the last bar and throw for every earlier bar.
-
Method Summary
Modifier and TypeMethodDescriptionstatic AlphaFactorbollinger(int period, double stdDevs) Bollinger mean reversion:−(close − SMA) / (k·σ)— the negative band position, +1 at the lower band, −1 at the upper.static AlphaFactorlowVolatility(int lookback) Low-volatility anomaly:−σ(returns)over the lookback, calm names scoring high.static AlphaFactormacd(int fast, int slow, int signal) MACD histogram normalized by price:(macdLine − signalLine) / close.static AlphaFactormeanReversion(int lookback) Plain mean reversion:−(close / SMA − 1)— how far the price sits below its own average, as a fraction.static AlphaFactormomentum(int lookback, int skip) Cross-sectional momentum:close[i−skip] / close[i−lookback] − 1.static AlphaFactormovingAverageCrossover(int fast, int slow) Moving-average crossover:(SMA_fast − SMA_slow) / SMA_slow.static AlphaFactorprepared(AlphaFactor factor, double p, Map<String, String> sectorBySymbol) The standard preparation chain:winsorized(AlphaFactor, double)atp, thenstandardized(AlphaFactor), thensectorNeutralized(AlphaFactor, Map)(skipped whensectorBySymbolis null).static AlphaFactorquality()Quality composite: profitability minus leverage —ROE − 0.1 × debt/equity.static AlphaFactorrsi(int period) Contrarian RSI:(50 − RSI) / 50, in [−1, +1].static AlphaFactorsectorNeutralized(AlphaFactor factor, Map<String, String> sectorBySymbol) Demeans scores within each sector per date, so the factor ranks names against their sector peers.static AlphaFactorstandardized(AlphaFactor factor) Cross-sectional z-score per date:(s − mean)/sdover the scored names (population sd); all-zero when the scores have no dispersion.static AlphaFactorvalue()Value composite: the average of earnings yield and book yield (1/PB).static AlphaFactorwinsorized(AlphaFactor factor, double p) Clips each date's scores to the cross-sectionalpand1 − pquantiles (linear interpolation between order statistics), NaN entries untouched.
-
Method Details
-
movingAverageCrossover
Moving-average crossover:(SMA_fast − SMA_slow) / SMA_slow. Positive when the fast average rides above the slow — the % spread makes scores comparable across price levels. -
macd
MACD histogram normalized by price:(macdLine − signalLine) / close. Positive while bullish momentum is accelerating; the price normalization keeps a $10 and a $1000 stock on one scale. -
momentum
Cross-sectional momentum:close[i−skip] / close[i−lookback] − 1. The academic 12-1 form when called asmomentum(252, 21)— skipping the last month sidesteps short-term reversal (Jegadeesh-Titman 1993). -
rsi
Contrarian RSI:(50 − RSI) / 50, in [−1, +1]. Oversold names (RSI 30 → +0.4) score positively.Definition note: this is Cutler's RSI (arithmetic average of gains/losses over the window), chosen because it is stateless and exactly recomputable at any bar. It is not the same number as
indicators.Indicators#rsi, which uses Wilder smoothing — after a trend the two can disagree near the 30/70 thresholds. The factor name says so to keep reports unambiguous. -
bollinger
Bollinger mean reversion:−(close − SMA) / (k·σ)— the negative band position, +1 at the lower band, −1 at the upper. -
meanReversion
Plain mean reversion:−(close / SMA − 1)— how far the price sits below its own average, as a fraction. -
value
Value composite: the average of earnings yield and book yield (1/PB). Yields rather than ratios, so "cheap" is high and negative-earnings names contribute a negative yield rather than a meaningless negative P/E rank. The earnings yield iseps / close(t)whenepsis known, so the price side is current; otherwise1/PEas recorded. NaN without fundamentals. -
quality
Quality composite: profitability minus leverage —ROE − 0.1 × debt/equity. The 0.1 haircut puts one turn of leverage on the same scale as 10 points of ROE, the usual quality-minus-junk shape (profitable and conservatively financed). -
lowVolatility
Low-volatility anomaly:−σ(returns)over the lookback, calm names scoring high. Ranking only needs the negative sign, not annualisation. Synthetic bars are excluded; NaN with fewer than two real bars in the window. -
winsorized
Clips each date's scores to the cross-sectionalpand1 − pquantiles (linear interpolation between order statistics), NaN entries untouched.- Parameters:
p- tail fraction in [0, 0.5), for example 0.01
-
standardized
Cross-sectional z-score per date:(s − mean)/sdover the scored names (population sd); all-zero when the scores have no dispersion. -
sectorNeutralized
Demeans scores within each sector per date, so the factor ranks names against their sector peers. Symbols missing from the map form their own singleton sector and score 0. -
prepared
The standard preparation chain:winsorized(AlphaFactor, double)atp, thenstandardized(AlphaFactor), thensectorNeutralized(AlphaFactor, Map)(skipped whensectorBySymbolis null).
-