Open the app
Backtesting & strategy

Backtesting & simulation

vectorbt for breadth, an event-driven simulator for realism, and four levels of simulation before real capital.

Two engines, two jobs: vectorbt explores many strategy variants fast, while an event-driven simulator models the messy reality vectorized backtests miss.

The two engines

EngineRole
vectorbtRapid parameter exploration, vectorized simulations, large experiment grids, portfolio-level analysis.
Event-driven simulator (Backtrader / custom)Order-book execution, partial fills, latency, slippage, low liquidity, outages, failed orders.

For new listings a custom simulator may eventually be required — generic engines do not model launch conditions accurately.

Four levels of simulation

LevelWhat it does
Historical backtestPreviously recorded market data
Shadow modeObserves the live market, submits no orders
Paper tradingSimulated orders on live prices with modeled execution
Small-capital productionReal orders with restricted position sizes

Execution realism (modeled in every backtest)

  • fees
  • spread
  • slippage
  • latency
  • partial fills
  • missing liquidity
  • rejected orders
  • order limits
  • API delays
  • gas costs
  • price impact

No look-ahead bias

A decision at time t may only use data available at or before t. The signal is generated after the candle closes and executed at the next open (or via an explicit fill model) — never at the same close it was computed from.

execution timing
Wrong:   decide on candle t close, assume fill before that close
Right:   decide after candle t closes, execute at candle t+1 open

Fill simulation models

ModelHow a fill is priced
Next-openExecutionPrice = Open(t+1) — simple, optimistic on volatile tokens
Spread-adjustedRef × (1 + HalfSpread + Slippage) for a buy
Order-book replayWalk historical asks/bids, compute fillable VWAP and partial fills
LatencyExecTimestamp = Signal + ProcessingLatency + NetworkLatency

Walk-forward, grids & robustness

Parameters are never fit on the full dataset. Walk-forward rolls train → validate → test windows forward to measure stability and expose overfitting; a grid enumerates candidates; sensitivity perturbs the winner.

research/parameter_grid.py
breakout_periods = [10, 20, 30, 50]
volume_thresholds = [1.5, 2.0, 2.5, 3.0]
atr_multipliers   = [1.0, 1.5, 2.0, 2.5]
grid = [
    {"breakout_period": b, "volume_threshold": v, "atr_multiplier": a}
    for b in breakout_periods for v in volume_thresholds for a in atr_multipliers
]
sensitivity_v1
Sensitivity sweep

A robust parameter stays acceptable when nudged. A sharp, isolated performance peak is a sign of overfitting, not edge.

Monte Carlo reshuffles or resamples trades to estimate the drawdown distribution, the worst losing streak and the probability of exceeding a loss threshold — it quantifies uncertainty, it does not create certainty.

A frictionless backtest is a story, not a measurement
Without simulated frictions, results are too good and false. Realism is mandatory at every level — it is what makes the shadow → simulation → production progression honest.
Early tokens require event replay
OHLCV candles are insufficient for a token minutes old. The simulator replays the actual events — pool creation, individual trades, liquidity changes, holder snapshots, creator-wallet transactions, sellability results, social events — and models delayed detection/analysis, order-submission latency, front-running, priority fees and liquidity disappearance. A strategy is never judged successful on theoretical candle prices alone.