Trailing stop
Two ways to trail, and the first one is almost always the one you want.
Use the venue's own trailing stop
trail 20%
One command. The stop lives on the EXCHANGE, so it keeps trailing after you
close the CLI, and it survives your laptop going to sleep. Distance is measured
from the current price. See trail.
To arm it only once the trade is working — the classic "runner after TP3":
when (price >= 0.053169) (trail 20%)
when arms and returns, so you keep trading
while it waits. Not every venue offers trailing stops; trail refuses by name
on one that does not, and that is when you reach for the pattern below.
Build one yourself
Roll your own using track, a reactive sets, and a blocking wait. This
runs in the CLI rather than on the exchange, which is the trade-off: it can
trail on anything (PnL, a custom expression) and on any venue, but it stops
the moment the CLI does.
Minimum viable
track max @hi $last
sets @stop @hi-1
wait price < @stop
close
Three reactive pieces plus one terminator:
track max @hi $last— ratchets@hiupward as$lastticks higher, never down.sets @stop @hi-1— reactive definition: every time@stopis read, it re-evaluates against the current@hi. Write it as a single math token: a live-var source must resolve to ONE value, so@hi -1%is rejected with "expected single value, got 2 tokens".wait price < @stop— blocks at 100 ms polling until last price drops under the trailing stop. (@lastis not a bound variable; the condition keyword isprice.)close— flat the position.
Variations
track min @lo $last
sets @stop @lo+1
wait price > @stop
close
Short-side mirror. track min ratchets downward; the stop sits 1% above
the running low.
track max @hi $last
sets @stop @hi-1
wait price < @stop for=3s
close
Adds for=3s anti-fakeout. The condition has to hold continuously
for 3 seconds before wait releases. Filters single-tick wicks.
track max @hi $pnl
sets @stop @hi-50
wait pnl < @stop
close
Trail PnL instead of price. @hi ratchets on uPnL; stop is $50
under the high-water mark. Useful for close at + green workflows.
track max @hi $last
sets @stop @hi-1
wait either (price < @stop) or (price > 60000)
close
Combinator — exit on either the trail OR a hard take-profit ceiling. See Workflow → combinators.
alias mytrail "track max @hi $last; sets @stop @hi-1; wait price < @stop; close"
trail
Once you settle on a flavor, alias it so you can fire with one keystroke.
Gotchas
trackratchets only on read. Await @stop > 0resolves it through the tracker and updates@hiat poll time, which is fine. But if nothing reads@hibetween sessions, the high-water mark doesn't advance. The pattern above is self-driving becausewait price < @stopreads@stop→ reads@hi→ ratchets, every 100 ms.sets(notset) is required for the stop.set @stop @hi-1snapshots a single number at definition time and never updates.setskeeps the source literal and re-evaluates on every read.echo @hiratchets a tracker on read;print @hidoes not. When you debug a trail manually withprint, you're guaranteed not to advance the state —echowill. See Aliases & vars →track.waitgives up after 30 s by default and CANNOT be told to wait hours.timeout=is capped at 10 minutes and anything larger is rejected outright (wait: timeout must be in (0, 10m]), so a trail built this way needs arepeatloop around it to run for a session — or usetrail, which has no such limit because the venue holds the order.- Tracked + reactive vars are session-scoped. They don't persist across
CLI restarts. Re-run the
track/setslines on startup, or alias the whole bundle. - If the position is already underwater when you start the trail,
@hiinitializes at the first read of$last— meaning a flash-crash entry followed by recovery will set the high at the recovery's peak, not at the entry. Useset @hi $entryfirst if you want the trail anchored to entry instead.
Related
- Aliases & vars →
track/sets - Workflow →
wait— conditions +for= - Variables —
$last,$pnl,$entry - Recipe: Bracket order — static stop alternative
- Recipe: Chaser — for re-pegging entries, not exits
- Workflow →
when— arm the trail on a condition