Trading Dev AcademyFree quant education

Free lesson · Point-in-time data

An as-of join that never selects the future

Open interactive lessonPractice calculationsExplore labs

Start with the idea

At a decision time, choose the most recent eligible information rather than the nearest observation.

Symbols, units & horizon
  • a_j: usable timestamp for record j of one fixed entity and series
  • t: decision timestamp on the same clock
  • j*: index of latest eligible record
  • no eligible j: missing result, not zero

When and why to use this

Join fundamentals, macro releases and alternative data into a causal feature table.

At a decision time, choose the most recent eligible information rather than the nearest observation.

Nearest-time matching can reach forward. A causal as-of rule first filters by usable time, then picks the latest eligible record. Entity identity, observation period and version key must also match; one global latest record is insufficient for a multi-company dataset.

Reject or explicitly aggregate duplicate eligible timestamps. If no record is available, preserve missingness instead of filling it from the future. A maximum staleness rule can be added after the causal join.

j∗=arg⁡maxj:aj≤t⁡aj
Causal as-of selection rule

An as-of join that never selects the future

  1. Keep only records with a_j≤t.
  2. Sort remaining records by usable time and take the last.
  3. Return missing if the eligible set is empty; test the exact release boundary.
Work it by hand

Values 10 and 12 become usable at times 5 and 9. At decision time 8, select 10; at time 9 select 12. At time 4 return missing.

Apply it in a strategy

  • Freeze inputs at the stated decision time and record their units.
  • Join fundamentals, macro releases and alternative data into a causal feature table.
  • Recompute the example, then change the material assumption and explain the difference.

Research deliverable

An as-of join that never selects the future: produce the worked calculation, a timestamped input record and a written decision addressing this limitation: Filtering by availability does not fix incorrect entity mapping or revisions that overwrote their earlier version.

These are synthetic mechanics examples, not historical performance or paper replications. Module evidence and research boundaries record the 12 September 2026 review.

Python implementation

Self-contained teaching example. Python 3.10+; dependencies and input conventions are shown in the code and notation. Run in your own Python environment.

# Python 3.10+; standard library and NumPy only.
# Synthetic teaching inputs; conventions and units are defined in the notation above.
def asof(records,decision):
    # records are (usable_timestamp,value) for one entity and series.
    eligible=[row for row in records if row[0]<=decision]
    if not eligible: return None
    latest=max(row[0] for row in eligible)
    matches=[row for row in eligible if row[0]==latest]
    if len(matches)!=1: raise ValueError('Resolve duplicate version timestamps first')
    return matches[0][1]

assert asof([(5,10),(9,12)],8)==10
assert asof([(5,10),(9,12)],4) is None
print(asof([(5,10),(9,12)],9))

Continue learning

Data: Availability, Revisions & Reproducible Research — all lessons
  1. Four clocks for one observation
  2. An as-of join that never selects the future
  3. First prints and revisions can reverse a signal
  4. Reconcile splits and cash distributions
  5. Universe membership and disappearing assets
  6. Coverage, missingness and stale values
  7. Purging labels that cross a test boundary
  8. Reproducible snapshots and discrepancy ledgers

Quantitative finance and development glossary · Python resources and libraries · Research sources and limitations