Trailing Stops
Trailing stop and trailing stop-limit semantics, anchor updates and model boundaries.
Trailing stops move behind favorable price action and trigger when price reverses by a configured amount or percent. The engine supports standalone
STOP_TRAIL, STOP_TRAIL_LIMIT and trailing stop-loss legs inside brackets.
Source
backtester/execution/order_types.py + backtester/execution/fill_engine.pyLayerOrder execution / dynamic protective exit
ModeOrder mode
Input
trail_amount or trail_percent, OHLC bar, optional limit offsetOutputfill when price crosses the computed trailing stop
Primary API
Order(..., order_type=OrderType.STOP_TRAIL, trail_percent=...)Main caveatThe trailing anchor updates from bar high/low, not tick-by-tick path.
Execution Semantics
For a long position, a trailing sell stop uses the highest observed favorable high as its anchor. The stop level is:
text
anchor - trail_amount
anchor * (1 - trail_percent)For a short position, a trailing buy stop uses the lowest observed favorable low.
Anchor Update Rule
- Sell trailing stop: anchor ratchets up with
bar.high. - Buy trailing stop: anchor ratchets down with
bar.low. - If no stop is triggered on the bar, the anchor can update.
- If the stop triggers, fill uses open-aware gap-through logic.
Standalone Trailing Stop
Four percent trailing stop
python
self.fill_engine.submit(Order(
instrument=inst,
side=OrderSide.SELL,
quantity=pos,
order_type=OrderType.STOP_TRAIL,
trail_percent=0.04,
))Trailing Stop-Limit
A trailing stop-limit activates when the trailing stop is crossed, then behaves like a limit order. It can remain pending if price gaps through the limit.
Trailing stop-limit with offset
python
self.fill_engine.submit(Order(
instrument=inst,
side=OrderSide.SELL,
quantity=pos,
order_type=OrderType.STOP_TRAIL_LIMIT,
trail_amount=5.0,
limit_offset=0.50,
))Bracket With Trailing Stop-Loss Leg
Fixed take-profit plus trailing stop-loss
python
self.fill_engine.submit(Order(
instrument=inst,
side=OrderSide.BUY,
quantity=shares,
order_type=OrderType.BRACKET,
bracket=BracketSpec(
take_profit_price=round(bar.close * 1.10, 2),
stop_loss_type=OrderType.STOP_TRAIL,
trail_percent=0.04,
),
))Failure Modes
- Submitting a new trailing stop every bar instead of tracking whether one is live.
- Forgetting to cancel a trailing stop after a signal-based market exit.
- Treating daily trailing behavior as tick-accurate.
- Confusing trailing stop-limit with guaranteed stop execution.