Appearance
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
| Parameter | Description |
|---|---|
bucket_secs | Duration of each bucket (e.g., 86400 for daily) |
ring_len | Number of buckets in the ring buffer (e.g., 365 for one year of daily buckets) |
min_buckets | Minimum 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:
- Future: The expiry must be after the current time
- Aligned: The expiry must fall exactly on a bucket boundary
- Within window: The expiry must be between
window_start + min_durationandwindow_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.