Skip to content

Markets & Rolling Windows

Each market is a rolling-perpetual swap instrument - there is no fixed maturity date. Instead, positions expire into discrete time buckets within a continuously advancing window. As time passes, the window rolls forward and expired buckets are recycled, making the market perpetual while still supporting fixed-tenor positions (e.g., 7-day, 30-day, or 1-year swaps).

Rolling Window Structure

The Window

At any point in time, the market defines a valid expiry range:

  • Window start: The next bucket boundary at or after the current time
  • Window end: Window start plus the maximum duration (determined by the number of buckets × bucket size)

New positions must choose an expiry timestamp that falls within this window and aligns to a bucket boundary. As time advances, the window slides forward - older buckets expire and new ones become available at the far end.

Buckets

The window is divided into fixed-size time slots called buckets. For example, a market with daily buckets (bucket_secs = 86400) and 365 buckets supports positions up to one year out, with each position expiring at a specific daily boundary.

Buckets are stored in a ring buffer - a fixed-size circular array where each slot is reused as the window advances. When a bucket expires (falls behind the window start), its exposure data is cleared and the slot becomes available for future expiries. This means the market never grows in size regardless of how long it runs.

Bucket Parameters

ParameterDescription
bucket_secsDuration of each bucket (e.g., 86400 for daily)
ring_lenNumber of buckets in the ring buffer (e.g., 365 for one year of daily buckets)
min_bucketsMinimum position tenor in buckets (prevents very short-lived positions)

The maximum duration is ring_len × bucket_secs. The minimum duration is min_buckets × bucket_secs.

Position Expiry Rules

When a trader opens a new position or modifies an existing one, the chosen expiry (end_time) must satisfy:

  1. Future: The expiry must be after the current time
  2. Aligned: The expiry must fall exactly on a bucket boundary
  3. Within window: The expiry must be between window_start + min_duration and window_end

These rules ensure every position maps cleanly to exactly one bucket in the ring buffer, and that positions have a minimum tenor to prevent extremely short-duration trades that would distort pricing.

Window Advancement (Tick)

As time passes, the window start moves forward. Buckets that fall behind the new window start are ticked - their accumulated exposure (OI, DV01, pool net notional) is subtracted from the market's aggregate totals and the bucket slots are cleared for reuse.

Ticking happens automatically before any trade execution to ensure the market state reflects the current time. Multiple buckets can be ticked in a single operation if enough time has elapsed.

Why Rolling Windows?

Traditional derivatives markets use fixed maturities - a March contract, a June contract, etc. This creates fragmented liquidity across expiry dates and requires periodic contract rolls. The rolling window design avoids these problems:

  • Single market, any tenor: Traders choose their exact duration within the supported range, all sharing the same unified liquidity pool and 8-knot curve engine
  • No expiry fragmentation: All positions trade against a unified liquidity pool, with rates interpolated from the curve engine's term structure
  • Automatic perpetuation: The market never expires - it just keeps rolling forward
  • Clean bookkeeping: The ring buffer has constant memory footprint regardless of market lifetime

The trade-off is that positions must align to bucket boundaries, which introduces discrete granularity (e.g., daily instead of arbitrary timestamps). The bucket size is a market parameter chosen at creation to balance granularity against transaction overhead and state-update cadence.