Concept · Limit Orders
A limit order is an instruction to buy or sell at a specific price or better — the order only fills if the market reaches that price, unlike a market order which fills immediately at whatever price is available.
There are two basic order types:
Market order: "Buy now, at whatever price the exchange can give me." Fills immediately. You pay a taker fee. The price you get may be slightly different from what you saw (slippage — the gap between expected and actual fill price).
Limit order: "Buy only if the price reaches $X or lower (for a long entry)." The order rests on the order book until either the market hits your price (you fill as a maker — see maker taker fees) or you cancel it (you miss the trade).
The current engine uses market orders exclusively: every entry and exit fills at candle.close with no limit price. Adding limit orders would allow:
A candle gives four prices: open (first trade), high (peak), low (trough), close (last trade). The engine can check whether a limit price was reached during a candle's range:
Long limit entry at price P:
if (candle.low <= P) → order filled at P (maker), apply makerFeeBps
else → order still pending (missed this candle)
Short limit entry at price P:
if (candle.high >= P) → order filled at P (maker), apply makerFeeBps
else → order still pending
This is exactly the logic already used for TP/SL (take-profit/stop-loss — pre-set exit prices) exits in fill-resolver.ts:26 via overrideFillPrice. That machinery generalizes to entries.
The critical difference from market orders: a limit order that is never reached produces no trade. If you set a buy limit 0.3% below the current close, and the market never dips, you miss the entry. Over a full backtest, this can eliminate 10–25% of would-have-been trades, changing win rate, profit factor, and Sharpe meaningfully — not just the fee.
This is why maker/taker simulation is a Phase-level upgrade, not a fee-config change.
OHLC data tells you whether a candle hit your limit price, but not when. For a 1h candle with low ≤ your limit, the fill could have happened at the candle's open, its midpoint, or one second before close. This is a fundamental limitation of candle-based backtesting.
Common assumption: the order fills at exactly your limit price, at an unspecified point in the candle. This is optimistic — it ignores:
More sophisticated simulators use tick data (trade-by-trade records) instead of candles to resolve this precisely — but that requires orders-of-magnitude more data storage and compute.
wiki/qa-sessions/2026-06-29-session.md#q2 (first asked here)apps/backend/src/evaluation/position/fill-resolver.ts:26 (overrideFillPrice — existing OHLC-range fill path for TP/SL exits)Related concepts
See it in a real result →Put it to the test
Spawn your variant, run it on the same engine, and read the edge-significance verdict — before you risk real money.