Full Limit Order Book Snapshots at 30-Minute Intervals¶
This notebook demonstrates how to capture complete limit order book depth at regular intervals from ITCH 5.0 data.
Full LOB snapshots capture all orders for multiple price levels on both bid and ask sides, providing complete market depth information.
This example uses the S081321-v50-AAPL-SPY.itch50.gz
file generated in the Extracting Symbols example.
In [1]:
Copied!
from pathlib import Path
import datetime
import pandas as pd
from meatpy.itch50 import ITCH50MessageReader, ITCH50MarketProcessor
from meatpy.event_handlers.lob_recorder import LOBRecorder
from meatpy.writers.parquet_writer import ParquetWriter
# Define paths and parameters
data_dir = Path("data")
file_path = data_dir / "S081321-v50-AAPL-SPY.itch50.gz"
outfile_path = data_dir / "spy_lob.parquet"
book_date = datetime.datetime(2021, 8, 13)
with ITCH50MessageReader(file_path) as reader, ParquetWriter(outfile_path) as writer:
processor = ITCH50MarketProcessor("SPY", book_date)
# We only care about the top of book
lob_recorder = LOBRecorder(writer=writer, collapse_orders=False)
# Generate a list of timedeltas from 9:30 to 16:00 (inclusive) in 30-minute increments
market_open = book_date + datetime.timedelta(hours=9, minutes=30)
market_close = book_date + datetime.timedelta(hours=16, minutes=0)
record_timestamps = [
market_open + datetime.timedelta(minutes=i)
for i in range(
int((market_close - market_open).total_seconds() // (30 * 60)) + 1
)
]
lob_recorder.record_timestamps = record_timestamps
# Attach the recorders to the processor
processor.handlers.append(lob_recorder)
for message in reader:
processor.process_message(message)
from pathlib import Path
import datetime
import pandas as pd
from meatpy.itch50 import ITCH50MessageReader, ITCH50MarketProcessor
from meatpy.event_handlers.lob_recorder import LOBRecorder
from meatpy.writers.parquet_writer import ParquetWriter
# Define paths and parameters
data_dir = Path("data")
file_path = data_dir / "S081321-v50-AAPL-SPY.itch50.gz"
outfile_path = data_dir / "spy_lob.parquet"
book_date = datetime.datetime(2021, 8, 13)
with ITCH50MessageReader(file_path) as reader, ParquetWriter(outfile_path) as writer:
processor = ITCH50MarketProcessor("SPY", book_date)
# We only care about the top of book
lob_recorder = LOBRecorder(writer=writer, collapse_orders=False)
# Generate a list of timedeltas from 9:30 to 16:00 (inclusive) in 30-minute increments
market_open = book_date + datetime.timedelta(hours=9, minutes=30)
market_close = book_date + datetime.timedelta(hours=16, minutes=0)
record_timestamps = [
market_open + datetime.timedelta(minutes=i)
for i in range(
int((market_close - market_open).total_seconds() // (30 * 60)) + 1
)
]
lob_recorder.record_timestamps = record_timestamps
# Attach the recorders to the processor
processor.handlers.append(lob_recorder)
for message in reader:
processor.process_message(message)
In [2]:
Copied!
pd.read_parquet(outfile_path).head(10)
pd.read_parquet(outfile_path).head(10)
Out[2]:
Timestamp | Type | Level | Price | Order ID | Volume | Order Timestamp | |
---|---|---|---|---|---|---|---|
0 | 2021-08-13 09:30:00 | Ask | 1 | 445.22 | 1215132 | 100 | 2021-08-13 04:17:00.009898 |
1 | 2021-08-13 09:30:00 | Ask | 1 | 445.22 | 1215268 | 100 | 2021-08-13 04:17:00.019219 |
2 | 2021-08-13 09:30:00 | Ask | 1 | 445.22 | 1242280 | 100 | 2021-08-13 04:18:00.288942 |
3 | 2021-08-13 09:30:00 | Ask | 2 | 445.23 | 848264 | 100 | 2021-08-13 04:10:00.850094 |
4 | 2021-08-13 09:30:00 | Ask | 2 | 445.23 | 848300 | 500 | 2021-08-13 04:10:00.850318 |
5 | 2021-08-13 09:30:00 | Ask | 2 | 445.23 | 1215112 | 500 | 2021-08-13 04:17:00.009681 |
6 | 2021-08-13 09:30:00 | Ask | 2 | 445.23 | 1242272 | 500 | 2021-08-13 04:18:00.288764 |
7 | 2021-08-13 09:30:00 | Ask | 2 | 445.23 | 1242636 | 500 | 2021-08-13 04:18:00.489233 |
8 | 2021-08-13 09:30:00 | Ask | 2 | 445.23 | 1243048 | 500 | 2021-08-13 04:18:00.855560 |
9 | 2021-08-13 09:30:00 | Ask | 2 | 445.23 | 1244196 | 500 | 2021-08-13 04:18:00.931458 |