06 / QUICKSTART

Read one sample day correctly before writing a strategy.

A copyable path from ZIP to Parquet, from schema joins to a minimal fill simulator for both 5-minute and 15-minute markets.

START WITH REAL SAMPLES

Free samples, no sign-up, no paywall.

The site provides 2026-08-10 UTC samples for 5m and 15m markets. The complete historical archive is free on Telegram.

1. Extract and inventory

The 15m sample is one ZIP. The 5m sample is split into two parts; download both and extract them into the same directory.

sample_15m/
├── ticks_20260810_00.parquet
├── depth_20260810_00.parquet
└── btc_15m_market_outcomes.parquet

Inventory file sizes, Parquet schemas, time ranges, and event_slug counts before modeling.

2. Install and read Parquet

python -m pip install pandas pyarrow
from pathlib import Path
import pandas as pd

root = Path("sample_15m")
ticks = pd.concat(
    [pd.read_parquet(path) for path in sorted(root.glob("ticks_*.parquet"))],
    ignore_index=True,
)
depth = pd.concat(
    [pd.read_parquet(path) for path in sorted(root.glob("depth_*.parquet"))],
    ignore_index=True,
)
outcomes = pd.read_parquet(root / "btc_15m_market_outcomes.parquet")

ticks = ticks.sort_values(["event_slug", "ts"])
depth = depth.sort_values(["event_slug", "ts", "outcome", "side", "level"])
data = ticks.merge(outcomes, on="event_slug", how="left")

3. Join and bound the market

Join ticks, depth, market_outcomes, and seen_markets with event_slug. A 5m window is normally 300 seconds and a 15m window 900 seconds.

window_start_ts ≤ ts < window_end_ts

Use interval_min and the window timestamps from the data. Do not infer coverage from filenames alone.

4. Simulate a first fill

A buy consumes ASK levels from level 1 upward; a sell consumes BID levels from level 1 downward. Displayed size is not a fill guarantee.

def consume_book(snapshot, outcome, side, quantity):
    levels = snapshot[
        (snapshot["outcome"] == outcome) &
        (snapshot["side"] == side)
    ].sort_values("level")
    remaining, cost, filled = quantity, 0.0, 0.0
    for row in levels.itertuples():
        amount = min(remaining, row.size)
        cost += amount * row.price
        filled += amount
        remaining -= amount
        if remaining <= 0:
            break
    return filled, cost / filled if filled else None, remaining

# buy -> ASK; sell -> BID. Add latency, fees, slippage, and fill ratios.

State latency, partial-fill ratio, insufficient depth, fees, and slippage. Never use winner_side or target as a predictive feature.

Continue with