QuantJourney Backtester

QuantJourney Backtester

Share product feedback

✓

Thank you.

Your note is now in the QuantJourney inbox.

docs/engine/trailing-stops.mdx

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.

Sourcebacktester/execution/order_types.py + backtester/execution/fill_engine.py
LayerOrder execution / dynamic protective exit
ModeOrder mode
Inputtrail_amount or trail_percent, OHLC bar, optional limit offset
Outputfill when price crosses the computed trailing stop
Primary APIOrder(..., 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.