Ticker Docs

The predicate DSL

The JSON filter language behind every Screen and View.

Both screen_events and create_view take a predicate, a recursive JSON boolean expression over analytics columns. It is a pure filter, not an ordering (use screen_events's sort parameter to rank).

Shape

A predicate is either a leaf or a composite.

// leaf: one comparison
{ "col": "ea.price_self_z_7d", "op": ">=", "val": 2 }

// composite: AND / OR of sub-predicates
{ "all": [ /* ...predicates... */ ] }   // every child must match
{ "any": [ /* ...predicates... */ ] }   // at least one child matches

Composites nest, so you can express arbitrary boolean logic.

Columns are namespaced

Every column is prefixed by its source table:

PrefixTableExample
ea.event_analyticsea.median_price_current
e.eventse.event_name
pa.performer_analyticspa.x_social_z

Call list_screen_columns first

list_screen_columns returns the exact allowlist the SQL compiler accepts, with a description of each column's semantics, units, and when it's NULL. Anything not in that list fails to compile.

Operators

OperatorMeaningval shape
= !=equals / not equalsscalar
> >= < <=comparisonscalar
betweeninclusive range[lo, hi]
inmembership[a, b, c]

Example

Events whose 7-day price move is a strong cross-sectional outlier, landing 7–60 days out:

{
  "all": [
    { "col": "ea.price_self_z_7d_xs_z_subcat_tte", "op": ">=", "val": 2 },
    { "col": "ea.days_to_event", "op": "between", "val": [7, 60] }
  ]
}

The economic floor (on by default)

To keep thin, low-value books from dominating the rankings with sampling noise, the server AND-s an economic floor into every match by default:

{ "all": [
  { "col": "ea.listings_current",      "op": ">=", "val": 25 },
  { "col": "ea.median_price_current",  "op": ">=", "val": 40 }
]}

You don't add this yourself. Turn it off only to screen the raw universe: set apply_floor=false on screen_events (or apply_economic_floor=false on a View).

Freshness

Analytics rows aren't all recomputed every day, so a days-old snapshot can pass for a live dislocation. screen_events drops events last priced more than 3 days behind the newest price date in the market by default (exclude_stale=true). For a tighter window, add a relative date leg, so a saved View stays correct over time:

{ "col": "ea.last_price_snapshot_date", "op": ">=", "val": { "days_ago": 1 } }

{ "days_ago": N } compiles to CURRENT_DATE - N and is re-evaluated every tick, valid on any date or timestamp column. A literal date string also works but silently rots.

Authoritative validation runs in SQL. An invalid predicate returns a clear Invalid predicate: … error rather than failing silently.

On this page