Choose Your Engine Path
Decision guide for choosing weight mode, order mode and daily-bar execution assumptions.
Use this page when you know the strategy idea but not the right engine surface. The fastest path is usually to start with the object you already have: a signal matrix, target weights, order rules, or an execution caveat.
Source
backtester/core.py + backtester/execution/LayerDecision guide
ModeWeights, orders, or both
Inputstrategy object, timing assumption and execution requirement
Outputrecommended engine path and first guide to read
Primary API
execution_mode="weights" or execution_mode="orders"Main caveatOrder mode is not more correct by default. It is correct when order state changes the result.
Decision Table
| I have... | Use | Start with |
|---|---|---|
| Ranking signals across many names | Weight mode | Weights |
| Target portfolio weights | Weight mode | Rebalancing |
| Cash, gross, net or leverage constraints | Weight mode | Weights + Risk Models |
| Take-profit, stop-loss or trailing stop behavior | Order mode | Stop Loss + Brackets |
| Limit entries with expiry | Order mode | Limit Orders |
| Bracket or OCO behavior like Backtrader | Order mode | Order Lifecycle |
| A Zipline-style sizing workflow | Order mode helpers | Order Lifecycle |
| Daily bars and TP/SL on the same candle | Order mode plus boundary review | Execution Assumptions |
Recipes
| Example | Engine path | Why |
|---|---|---|
| A. Top-10 monthly momentum | Weight mode | Ranking and scheduled rebalance are portfolio-weight problems. |
| B. Long/short dollar-neutral factor | Weight mode | Gross/net exposure belongs in the weight matrix. |
| C. SMA crossover with market exit | Order mode | Current position state and market exits matter. |
| D. Limit entry with 3-bar expiry | Order mode | Pending order age and cancellation are part of the result. |
| E. Bracket TP/SL | Order mode | Entry creates managed OCO child exits after fill. |
| F. Gap-through stop-loss | Order mode caveat | Stop price is a trigger, not guaranteed execution. |
| G. TP and SL touched on one daily candle | Daily-bar boundary | OHLC proves both touched, not the intraday sequence. |
| H. Signal exit cancels protective orders | Order mode hygiene | A market exit must cancel stale stop/limit/bracket/OCO children. |
Example A: Top-10 Monthly Momentum
Weight mode: ranking becomes target weights
python
class TopTenMomentum(Backtester):
def _compute_signals(self):
close = self.instruments_data.get_feature("adj_close")
return close.pct_change(252).rank(axis=1, ascending=False)
def _compute_weights(self):
ranks = self.instruments_data.get_feature(
"strategies", self.strategy_name, "signals"
)
selected = ranks <= 10
return selected.div(selected.sum(axis=1), axis=0).fillna(0.0)
strategy = TopTenMomentum(
instruments=universe,
backtest_period={"start": "2015-01-01", "end": "2025-01-01"},
execution_mode="weights",
rebalance_policy=RebalancePolicy(frequency="BME"),
)Example D: Limit Entry With Three-Bar Expiry
Order mode: pending order state matters
python
self.fill_engine.submit(Order(
instrument="AAPL",
side=OrderSide.BUY,
quantity=100,
order_type=OrderType.LIMIT,
limit_price=round(bars["AAPL"].close * 0.98, 2),
expires_after_bars=3,
))Example E: Bracket TP/SL From Actual Fill Price
Order mode: entry activates managed exits
python
self.bracket_percent("AAPL", weight=0.20, tp=0.10, sl=0.05)Daily-Bar Boundary Test
If your thesis depends on whether the high or low happened first inside one daily candle, the model boundary is the dominant assumption. Use intraday bars or report the same-bar convention explicitly.