Backtesting
Execution
Replay historical L2 order books tick by tick. Orders fill against real book depth with queue priority, latency, and slippage. To research whether a signal is profitable over long periods, use Alpha. The SDK and backtest engine are open source on GitHub. What the engine replays and why fills are realistic is on Polymarket backtesting.
Quick Start
Orders fill against real historical liquidity with configurable latency, slippage, and platform-accurate fees.
Subtypes, results, saving, and the dashboard are shared across modes; see Runs.
from datetime import datetime, timedelta, timezone
from marketlens import MarketLens, Strategy
class ValueBuyer(Strategy):
def on_market_start(self, ctx, market, book):
self._entered = False
def on_trade(self, ctx, market, book, trade):
if self._entered:
return
if book.midpoint < 0.35:
ctx.buy_yes(size=100)
self._entered = True
client = MarketLens()
end = datetime.now(timezone.utc) - timedelta(days=1)
result = client.backtest(
strategy=ValueBuyer(),
id="btc-up-or-down-5m",
initial_cash=10_000,
after=end - timedelta(minutes=15),
before=end,
)
print(result.summary())Strategies
Subclass Strategy and implement one or more hooks. The engine calls them on each replay tick.
class MyStrategy(Strategy):
def on_trade(self, ctx, market, book, trade):
if trade.size > 1000:
ctx.buy_yes(size=100)
def on_book(self, ctx, market, book):
if book.imbalance(5) > 0.4:
ctx.buy_yes(size=200)
def on_fill(self, ctx, market, fill):
ctx.cancel_all()Context
Passed to every hook. Place orders, read positions, and query market state.
# entry: market order or patient limit
if book.spread < 0.03:
ctx.buy_yes(size=500)
else:
ctx.buy_yes(
size=500,
limit_price=book.best_ask,
cancel_after=ctx.time + 30000,
)# exit: take profit and clean up
pos = ctx.position()
if pos.shares > 0 and pos.unrealized_pnl > 100:
ctx.sell_yes(size=pos.shares)
ctx.cancel_all()Order Book
L2 book state at the current replay tick. Properties: best_bid, best_ask, spread, midpoint, bid_depth, ask_depth.
cost = book.impact("BUY", 500)
if book.imbalance(5) > 0.3 and cost and cost < 0.65:
ctx.buy_yes(size=500)