Quant Python

Rank a Factor Cross-Sectionally

Difficulty

Asked at XTX Markets, Squarepoint Capital

Theory: Quant Python That Survives Review

Read the problem, hints and solution here. The editor needs a bigger screen: open this page on a laptop to write and run your code.

Implement rank_cross_section(rows), which ranks the symbols within each date by their factor value.

Equity factors are used as ranks rather than levels. A raw value of 30 might be the best in the universe one day and the worst another, so research code ranks each day's cross section and trades the rank.

Each row is a (symbol, date, value) tuple. symbol is a string, date an integer, and value is an integer or None when the factor could not be computed for that symbol that day. Rows arrive in no particular order.

For each date, rank the symbols that have a value:

  • rank descending, so the largest value is rank 1;
  • use dense ranking, so tied symbols share a rank and the next distinct value takes the immediately following rank rather than skipping;
  • symbols whose value is None are excluded entirely, not ranked last.

Return a list of (date, symbol, rank), sorted by date ascending and by symbol ascending within a date.

Examples

rank_cross_section([("AAA", 1, 10), ("BBB", 1, 30), ("CCC", 1, 20)])
# [(1, 'AAA', 3), (1, 'BBB', 1), (1, 'CCC', 2)]

rank_cross_section([("A", 1, 5), ("B", 1, 5), ("C", 1, 1)])
# [(1, 'A', 1), (1, 'B', 1), (1, 'C', 2)]

The second example is the dense rule: A and B tie at rank 1, and C takes rank 2 rather than rank 3.

Constraints

  • 0 <= len(rows) <= 10^5, dates and values fit comfortably in int.
  • A date on which every symbol is None contributes nothing to the output.
  • Ranking must happen strictly within a date. Ranking the whole panel at once and then splitting is the mistake this problem is built around: it leaks every other day's distribution into today's signal.
  • The hidden performance test uses 200 dates by 500 symbols. Sorting the whole panel once per date is \( O(d \cdot n \log n) \) and wasteful; bucket by date first. pandas and numpy are preloaded.
Terms used in this problem (1)
symbol:
The short code that names an instrument, such as a share or a future.
Rate this problem
Language: Python 3.12rank_cross_section