Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
hkuds avatar

Multi Factor

  • 2 installs
  • 29.6k repo stars
  • Updated August 4, 2026
  • hkuds/vibe-trading

Rank stocks cross-sectionally by standardizing and combining multiple factors into a composite score and selecting a TopN long portfolio.

About

Ranks stocks cross-sectionally by combining standardized factors into a composite score and selecting a TopN portfolio. A developer uses it to build multi-factor, multi-instrument portfolio strategies.

  • Z-score standardize factors then combine into a composite score
  • Rank and go long TopN with equal weights

Multi Factor by the numbers

  • 2 all-time installs (skills.sh)
  • Ranked #870 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hkuds/vibe-trading --skill multi-factor

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs2
repo stars29.6k
Last updatedAugust 4, 2026
Repositoryhkuds/vibe-trading

What it does

Rank stocks cross-sectionally by standardizing and combining multiple factors into a composite score and selecting a TopN long portfolio.

Files

SKILL.mdMarkdownGitHub ↗

Multi-Factor Cross-Sectional Stock Ranking

Purpose

On the same time cross-section, compute multiple factor values for many stocks, standardize them, combine them into a composite score, and select the top-ranked stocks to build a portfolio.

Signal Logic

1. Factor calculation: calculate N factors for each stock (such as momentum, value, and quality) 2. Cross-sectional standardization: standardize each factor on the cross-section with Z-score normalization (subtract mean, divide by standard deviation) 3. Composite scoring: sum the factors with equal weights (or custom weights) to obtain a composite score 4. Rank and select: go long the TopN names, with weight = 1/N for each

Built-In Factors

Factor NameCalculation MethodDirection
momentumReturn over the past N daysPositive (higher is better)
reversalReturn over the past 5 daysNegative (lower is better)
volatilityStandard deviation of returns over the past N daysNegative (lower is better)
volume_ratioToday's volume / N-day average volumePositive

If extra_fields are available (China A-shares), you can also add:

  • pe_factor: 1/PE (the larger, the cheaper)
  • pb_factor: 1/PB
  • roe_factor: ROE (the larger, the better)

Parameters

ParameterDefaultDescription
momentum_window20Momentum lookback window
vol_window20Volatility lookback window
top_n3Number of selected stocks
rebalance_freq20Rebalancing frequency (trading days)

Common Pitfalls

  • Cross-sectional standardization requires at least 3 stocks, otherwise Z-scores are meaningless
  • Keep the previous signal unchanged between rebalance dates (do not rerank every day)
  • Factors have different directions: momentum is positively sorted, volatility is negatively sorted, so directions must be aligned before standardization
  • Portfolio weights must be normalized: each TopN stock gets 1/N, all others get 0

Dependencies

pip install pandas numpy

Signal Convention

  • 1/N = selected into TopN (equal-weight long), 0 = not selected

Zoo Signal Engine (new in 0.1.8)

When the user wants to compose 1-N alphas drawn from the Alpha Zoo (450+ pre-built factors) into a multi-factor strategy, use ZooSignalEngine.from_zoo(...) from zoo_signal_engine.py instead of the old per-symbol example_signal_engine.py. The new engine operates on wide-panel dict[str, pd.DataFrame] inputs (the same shape the registry's Alpha.compute(panel) contract uses), redistributes weights when any alpha fails or is skipped, and supports long-only (top_n), short-only (bottom_n), and long-short (top_n + bottom_n) signal modes. It also exposes a generate(data_map) adapter so it drops straight into the existing run_backtest pipelines.

from src.factors.registry import Registry
from zoo_signal_engine import ZooSignalEngine

registry = Registry()
# Browse candidates with registry.list(theme="momentum") -- see the alpha-zoo skill.
alpha_ids = ["alpha101_001", "alpha101_012", "guotai_191_003"]
engine = ZooSignalEngine.from_zoo(alpha_ids, top_n=10, bottom_n=10, standardize=True)
# Feed into a panel-aware backtest, or via .generate(data_map) into the bundled engines.
signal_panel = engine.compute_signal(panel)  # DataFrame, same shape as panel["close"]

Cross-references:

  • See the alpha-zoo skill for browsing the alpha catalogue, filtering by theme/universe, and inspecting __alpha_meta__ records.
  • example_signal_engine.py is kept for legacy per-symbol workflows that compute factors directly from raw OHLCV; new code should prefer `zoo_signal_engine.py` so it benefits from the 450+ zoo alphas, registry-level NaN/inf guardrails, and per-alpha skip isolation.

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.