Factor combination — score aditivo vs rank-based¶
Decisión técnica: cómo combinar los 3 factors (momentum ensemble + quality + value) en un single composite score. Resuelve PP-05. Recomendación: z-score aditivo con winsorizing.
El problema¶
Cada factor vive en su propio dominio:
momentum_12_1= 0.25 (25% past 12m return) — ~ -0.5 a +2.0.ROE= 0.18 (18% ROE) — ~ -0.1 a +0.4.P/B= 3.5 (price/book) — ~ 0.5 a 20.
Sumar directo pesa desproporcionadamente al de mayor magnitud. Necesitamos normalizar.
Opción A: Z-score aditivo (recomendado)¶
Para cada factor, para cada stock en el universe:
Luego:
Ventajas¶
- Cada factor contribuye proporcionalmente a su spread relativo.
- Interpretable: z=2 significa "2 stdev mejor que el mean".
- Recombina factors con distinta distribución fácilmente.
Desventajas¶
- Sensible a outliers: un stock con P/E de 500 infla el stdev → comprime el resto.
- Fix: winsorizing (truncar al p1/p99) antes de z-score.
Opción B: Rank-based¶
Para cada factor, rankear el universe 1 a N:
rank_factor = percentile_rank(raw_value) # entre 0 y 1
composite = w1 × rank_momentum + w2 × rank_quality + w3 × rank_value
Ventajas¶
- Robusto a outliers (por construcción).
- Todos los factors en [0, 1] — escala uniforme.
- Más usado por AQR y large quant shops.
Desventajas¶
- Pierde información: un stock con momentum z=3 (muy excepcional) tiene misma contribución que z=0.5 si ambos están en top 10%.
- Menos granularidad en los extremos.
Opción C: Rank con no-linearity (enhanced)¶
Donde f(rank) = 2*rank - 1 (linear, mean 0) o f(rank) = Φ^-1(rank) (inverse normal, recupera algo de granularidad).
Hybrid de A y B.
Evidence empírica¶
- AQR usa rank-based en la mayoría de papers ("Value and Momentum Everywhere") — prioriza robustez.
- Academic papers de factor research (Fama-French etc.) usan z-score típicamente, porque evaluan factor premiums directamente.
- Investopedia / blogs retail: inconsistente, mix de ambos.
Recomendación¶
Z-score aditivo con winsorizing p1/p99.
Razones¶
- Granularidad: distingue "excepcional" de "solo bueno".
- Evidence mixta entre opciones → elegir la más directa + interpretable.
- Debug-friendly: un score de 2.5 es inmediatamente "~2.5 stdev por encima del mean" — fácil de razonar si la strategy tiene sentido.
Formula exacta para la strategy¶
def composite_score(stock, universe):
# Winsorize cada input al p1/p99 del universe
mom_ensemble = winsorize(0.5 * (ret_12m - ret_1m) + 0.5 * (ret_6m - ret_1m), 0.01, 0.99)
roe = winsorize(stock.roe, 0.01, 0.99)
op_margin = winsorize(stock.op_margin, 0.01, 0.99)
debt_eq = winsorize(stock.debt_equity, 0.01, 0.99)
pe_inv = winsorize(1 / stock.pe, 0.01, 0.99)
pb_inv = winsorize(1 / stock.pb, 0.01, 0.99)
# Z-score sobre universe (winsorized)
z_mom = zscore(mom_ensemble, universe)
z_quality = zscore(roe) + zscore(op_margin) - zscore(debt_eq) # quality composite
z_value = zscore(pe_inv) + zscore(pb_inv) # value composite
return 0.5 * z_mom + 0.3 * z_quality + 0.2 * z_value
Edge cases¶
- Missing data: si un stock no tiene P/E (ej. loss-making), z_value = 0 (neutral). No excluir del universe si los otros factors están.
- Extreme outliers post-winsorizing: log-transform para factors fat-tailed (P/E especialmente).
- Sector bias: quality y value pueden correlacionar con sector (ej. tech low debt-equity típicamente). Opcional: z-score sector-neutral.
Gaps¶
- Sector-neutral z-scoring — reduce factor exposure concentrada en sectores.
- Weights óptimos: los 0.5/0.3/0.2 son heurísticos. Optimización requiere backtesting + cross-validation (riesgo overfitting).
- Time-varying weights: en diferentes regimes, distintos factors dominan.
Relaciones¶
- Resuelve: PP-05.
- Implementación del composite en: concepts/agent-prompts (Strategy Agent).
- Usado por: analysis/recommended-strategy-for-user.
- Complementa: concepts/momentum-window-selection, concepts/evidence-based-strategies.