Skip to main content

Overview

AlphaOperator is the DSL base class that every alpha signal in ClyptQ inherits from. It provides a library of numba-accelerated time-series and cross-sectional helper functions that operate on 2D (time, n_symbols) numpy arrays, matching the pseudo-code operators used in academic alpha papers (Alpha101, Alpha191). Subclasses override a single method — compute_signal — to define the alpha formula. All boilerplate (mask handling, TaggedArray wrapping, NaN/Inf safety, errstate management) is handled automatically by the base class.

Creating a Custom Alpha

1. Inherit and override compute_signal

2. Return types

compute_signal can return either:

3. Inputs

The data argument is a list of TaggedArray objects in the same order as the inputs you declared in __init__. Access raw numpy values via data[i].value, which returns a (T, N) ndarray where T is time and N is the number of symbols.

DSL Helper Reference

All helpers accept and return 2D (T, N) numpy arrays unless noted otherwise. They are accessible as self._<name> inside compute_signal.

Derived Fields

Time-Series Operators (numba-accelerated)

Cross-Sectional Operators (numba-accelerated)

Utility Operators

Benchmark Helpers

Column 0 is treated as the benchmark (e.g., BTC in a crypto universe).

Lookback Validation

Call self._validate_lookback() at the end of your __init__ (after setting window attributes) to verify that all Input lookbacks are large enough for the windows your alpha uses. The method introspects any self._*_window attributes and checks that every input has lookback >= max(all_windows) + 2. If validation fails, a ValueError is raised with a clear message.

Examples

Simple: Momentum Rank

A cross-sectional momentum alpha that ranks symbols by their 20-period return.

Complex: Volume-Weighted Trend Residual

An alpha that combines volume correlation with trend regression, then neutralizes via cross-sectional ranking.

Migration Note

All Alpha101 (101 alphas) and Alpha191 (191 alphas) operators now inherit directly from AlphaOperator. Each alpha implements compute_signal(data) using the DSL helpers documented above. If you are migrating a standalone alpha to this base class:
  1. Change the parent class from BaseOperator to AlphaOperator
  2. Move your logic into compute_signal(data) instead of compute(data, ...)
  3. Replace any manual rolling/rank computations with the built-in DSL helpers
  4. Add self._validate_lookback() at the end of __init__