Skip to content
sigc
Research

Cross-sectional factor research

Write momentum, value, and quality factors as typed .sig signals, combine them with explicit arithmetic, and get a reproducible ranked long-short backtest.

The problem

Factor research lives in notebooks that accumulate silent bugs: a mislagged return leaks lookahead, a calendar mismatch drops names, and a rerun three weeks later produces different numbers because a dependency moved. The signal logic is sound; the plumbing around it is not reproducible.

How sigc approaches it

  1. 01

    Declare each factor as a named signal block — momentum from ret + zscore, value from a fundamentals column, quality from a stability measure — so the compiler checks shapes and calendars before any row is read.

  2. 02

    Combine factors with explicit arithmetic (0.4 * momentum + 0.3 * value + 0.3 * quality) rather than hidden pandas joins.

  3. 03

    Rank cross-sectionally and construct a long-short book with rank(...).long_short(top, bottom, cap), then attribute against a benchmark.

  4. 04

    Every compile and run keys into the blake3 + sled content-addressed cache, so an identical .sig file and inputs reproduce the same numbers byte for byte.

multifactor.sig
signal momentum:
  emit zscore(ret(prices, 60))

signal value:
  emit zscore(-book_to_price)

signal combo:
  emit 0.5 * momentum + 0.5 * value

portfolio main:
  weights = rank(combo).long_short(top=0.2, bottom=0.2, cap=0.02)
  backtest from 2020-01-01 to 2024-12-31 benchmark "SPY"

What you get

  • Shape and calendar errors surface at compile time, not three hours into a backtest.
  • The same .sig source reproduces identical Total Return, Sharpe, Max Drawdown, and Turnover on any machine.
  • Factor libraries can be shared across a team as versioned .sig signals rather than copy-pasted notebook cells.

More use cases