Historical tick-by-tick L2 orderbook reconstruction and backtesting primitives for Polymarket. Spread, impact, imbalance, and every trade, delivered as a DataFrame.
Project description
MarketLens Python SDK
Historical and real-time prediction market data — full L2 orderbook reconstruction, microstructure analytics, and backtesting primitives for Polymarket.
pip install marketlens
from marketlens import MarketLens
client = MarketLens(api_key="mk_...") # or set MARKETLENS_API_KEY env var
L2 Orderbook Replay
Reconstruct tick-by-tick book state from the raw snapshot + delta stream. Every event yields a full OrderBook with computed spread, midpoint, depth, and imbalance — ready for microstructure research.
from marketlens import MarketLens, OrderBookReplay
history = client.orderbook.history(market_id, after=start, before=end, include_trades=True)
replay = OrderBookReplay(history, market_id=market_id)
# Iterate event-by-event with full book state
for event, book in replay:
print(f"t={event.t} mid={book.midpoint} spread={book.spread_bps():.0f}bps imb={book.imbalance():.3f}")
# Or get everything as a DataFrame in one call
df = replay.to_dataframe()
# Columns: midpoint, spread, spread_bps, imbalance, weighted_midpoint,
# bid_depth, ask_depth, bid_levels, ask_levels,
# trade_price, trade_size, trade_side (on trade rows)
OrderBook Analytics
Every OrderBook object — whether from a live snapshot or replayed from history — carries the same set of analytical methods:
book = client.orderbook.get(market_id)
book.microprice() # size-weighted mid from best level
book.weighted_midpoint(n=3) # n-level weighted mid
book.spread_bps() # spread in basis points
book.imbalance() # full-book bid/ask imbalance [-1, 1]
book.imbalance(levels=3) # top-of-book imbalance (better short-term signal)
book.impact("BUY", "1000") # VWAP execution price for $1k market buy
book.slippage("BUY", "1000") # slippage from mid for $1k order
book.depth_within("0.02") # (bid_depth, ask_depth) within 2c of mid
Series Walk — Backtesting Primitive
Walk through every market in a rolling series chronologically. Each MarketSlot has lazy loaders for candles, trades, orderbook, and full history — you only fetch what you use.
from datetime import datetime, timezone
for slot in client.series.walk("btc-up-or-down-5m", status="resolved",
after=datetime(2026, 3, 2, 12, 0, tzinfo=timezone.utc),
before=datetime(2026, 3, 2, 14, 0, tzinfo=timezone.utc)):
candles = slot.candles("1m").to_dataframe() # OHLCV DataFrame
book = slot.orderbook() # book at close_time
replay_df = OrderBookReplay( # full L2 replay
slot.history(include_trades=True), market_id=slot.market.id,
).to_dataframe()
print(slot.market.question, slot.market.winning_outcome)
print(f" overlap={slot.overlap_with_prev}ms gap={slot.gap_from_prev}ms")
Resources
| Namespace | Methods |
|---|---|
client.markets |
list() get() trades() candles() |
client.events |
list() get() markets() |
client.series |
list() get() markets() walk() |
client.orderbook |
get() history() metrics() |
All list methods return auto-paginating iterators. Chain .to_list() to collect or .to_dataframe() for a typed pandas DataFrame (decimal strings → float64, epoch ms → datetime64[ns, UTC]).
# Candles as DataFrame
df = client.markets.candles(market_id, resolution="1h").to_dataframe()
# Trades with time filter
trades = client.markets.trades(market_id, after=start, before=end).to_list()
# Markets sorted by liquidity
top = client.markets.list(status="active", sort="-liquidity", limit=5).first_page()
Async
Full async support — every resource, iterator, and replay helper has an async counterpart.
from marketlens import AsyncMarketLens, AsyncOrderBookReplay
async with AsyncMarketLens() as client:
async for slot in client.series.walk("btc-up-or-down-5m", status="resolved"):
book = await slot.orderbook()
print(book.microprice(), book.imbalance(levels=3))
Examples
| Example | What it does |
|---|---|
microstructure.py |
Replays one market's full L2 book — midpoint drift, microprice, imbalance, spread, trade flow |
execution_cost.py |
Live book analytics — depth, spread, impact/slippage table across order sizes |
series_backtest.py |
Momentum backtest over a rolling series with per-trade P&L |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file marketlens-0.1.0.tar.gz.
File metadata
- Download URL: marketlens-0.1.0.tar.gz
- Upload date:
- Size: 23.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a26741540a5cfb35a50cf445ca07225520587c6fe6554bf4f69e764e8defa1d
|
|
| MD5 |
5c777d4120a0471ee83ee0d5654c0e5a
|
|
| BLAKE2b-256 |
99c9d2c368df38cbf75554aa414025328fc6923e4f81f64fad182ebe48bdcae2
|
File details
Details for the file marketlens-0.1.0-py3-none-any.whl.
File metadata
- Download URL: marketlens-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cae8826da6a291f65dfd3caf3361e833cb0257e3e370d6a9893742e299fb449e
|
|
| MD5 |
993607a81b34e789ca9d6d46d2e813ae
|
|
| BLAKE2b-256 |
020499934b60e299e8f69fe96f50397dca897fdab67b43b75f7cf8d5b35e8bfa
|