Stop Loss & Trailing Stop
Risk attached to the entry — absolute, percent, or trailing — plus a small set of fields for SL-only follow-up payloads. Eleven fields total. Most setups use three of them.
- Pick one of three SL modes: absolute price (
stopLossType: "absolute"), percent distance ("percent"), or math expression (also"absolute"withstopLossExpression). - For a trailing stop, set
useTrailingStopLoss: trueplustrailingStopLossPercent. Optionally arm it later withtrailingStopLossActivationPercent. stopLossToBreakEven: trueis a trailing-stop companion (Binance Futures and Bybit): the trailing stop locks at break-even once the threshold is reached. There is no automatic "move to break-even after TP1".- A standalone SL update — no entry, just change the SL — uses
isStopLoss: true. See Core → isStopLoss.
stopLoss, stopLossPercent, trailingStopLossPercent and the expression fields accept Pine placeholders. See Anatomy → Dynamic values via TradingView placeholders.
Quick reference table
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
stopLoss | decimal | conditional | 0 | Absolute stop-loss price. Required when stopLossType="absolute". Used as the reference for break-even and trailing offsets. |
stopLossPercent | decimal | conditional | 0 | Stop-loss distance in percent from entry. Required when stopLossType="percent". |
stopLossType | string | no | — | How to interpret stop-loss input. absolute = price level (or stopLossExpression), percent = distance from entry. |
stopLossExpression | string | no | — | Arithmetic expression evaluated by TVH to produce an absolute stop price (e.g. "3660-0.02*3660"). Supports Pine placeholders like {{strategy.order.price}}. Operator sign is auto-flipped based on orderType so the SL lands on the correct side. |
useTrailingStopLoss | bool | no | false | Convert the stop-loss into a trailing stop. TVH manages the trail off-exchange where the exchange has no native primitive. |
stopLossToBreakEven | bool | no | false | Trailing-stop companion: when trailing SL is on, the stop locks at break-even (entry) once the trailing threshold is reached, instead of trailing further. Requires useTrailingStopLoss. Binance Futures and Bybit only. |
trailingStopLossPercent | decimal | conditional | 0 | Trail distance in percent. The stop follows price by this offset once activated. |
trailingStopLossActivationPercent | decimal | no | 0 | Profit threshold (percent from entry) before the trailing stop arms. Below this threshold the SL stays at its initial level. |
stopLossSizeType | string | no | currentPosition | Quantity model for the SL order. currentPosition = size matches whatever fills (preferred), absolute = explicit quantity supplied via units. |
cancelSlOrders | bool | no | false | Cancel all existing stop-loss orders for the pair before placing the new entry/SL. Prevents duplicate SLs when re-entering. |
updateStopLossToBreakEven | bool | no | false | Standalone command that moves an open position's existing SL to its average entry price (break-even). No new entry placed. Only fires when the position is in profit and already has an SL; not supported on every exchange. |
Three SL modes
Mode A — percent from entry (default for new payloads via UI)
{
"stopLossType": "percent",
"stopLossPercent": 1.5
}
SL placed 1.5% below entry on a long, 1.5% above entry on a short. Simple, scale-invariant, works on every exchange.
Mode B — absolute price
{
"stopLossType": "absolute",
"stopLoss": 63800
}
SL placed at exactly 63800. Your problem to make sure it sits on the correct side of entry; TVH does not validate.
Mode C — math expression (special case of absolute)
{
"stopLossType": "absolute",
"stopLossExpression": "{{strategy.order.price}}-0.02*{{strategy.order.price}}"
}
The server evaluates the expression after Pine substitutes the placeholder. Operator signs auto-flip based on orderType so the same template works for longs and shorts.
Allowed operators: + - * / and parentheses. Decimal literals only. Errors are silently swallowed — if the expression throws, stopLoss stays at its previous value (often 0 = no SL). Test before going live.
Full operator and sign-flip reference: Math Expressions.
Trailing stop
A trailing stop follows price by a fixed offset once activated. TVH manages the trail off-exchange where the exchange has no native primitive (most spot exchanges).
Two-field setup
{
"useTrailingStopLoss": true,
"trailingStopLossPercent": 0.7
}
The trail arms immediately on fill and follows price by 0.7%.
Three-field setup with activation threshold
{
"useTrailingStopLoss": true,
"trailingStopLossPercent": 0.7,
"trailingStopLossActivationPercent": 0.5
}
The trail stays dormant until price moves 0.5% in your favour from entry, then arms at a 0.7% offset. Useful when you want a small initial cushion of risk before the stop walks up.
Watch out:
- Activation is one-way. Once armed, the trail does not de-arm if price retraces below the activation threshold.
- The offset is computed off the best price seen since activation, not the bar close. Wicks count.
- Where the exchange supports a native trailing stop (Binance Futures, Bybit, BitMEX), TVH uses that and the offset/activation parameters map onto the exchange's own callback fields.
- Binance Futures caps the trail at 5%.
trailingStopLossPercent > 5is hard-capped to 5 — sending8produces a 5% trail. Other exchanges have their own caps; confirm in Exchange Quirks.
Trailing break-even
stopLossToBreakEven is a companion to the trailing stop, not a take-profit trigger. With trailing enabled, the stop locks at the entry price (break-even) once the trailing threshold is reached, instead of trailing any further. It requires useTrailingStopLoss: true and works on Binance Futures and Bybit only.
{
"stopLossType": "percent",
"stopLossPercent": 1.5,
"useTrailingStopLoss": true,
"trailingStopLossActivationPercent": 2,
"stopLossToBreakEven": true,
"targetType": "percent",
"targets": [{ "takeProfitPercent": 2.0, "amount": 100 }],
"targetAmountInPercent": true
}
There is no automatic "move to break-even after TP1 fills". To get that effect, match the trailing activation threshold to your TP level: with trailingStopLossActivationPercent: 2, the stop snaps to break-even when price reaches +2%, the same point TP1 sits at.
Watch out:
stopLossToBreakEvendoes nothing on its own. WithoutuseTrailingStopLoss: trueit is ignored.- Binance Futures and Bybit only.
SL-only payloads
Two ways to update an existing SL without re-entering:
Replace SL at a specific level
{
"exchange": "binance-futures",
"pair": "BTCUSDT",
"apiKey": "binance-futures-main",
"isStopLoss": true,
"cancelSlOrders": true,
"stopLossType": "absolute",
"stopLoss": 64200,
"stopLossSizeType": "currentPosition",
"token": "<token>"
}
This payload contains no entry and no targets. TVH treats it as a pure SL-management instruction: cancelSlOrders: true removes the existing SL on the pair first, then places a new one at 64200. Without it you would just stack a second stop on top of the old one. stopLossSizeType: "currentPosition" sizes the stop to whatever the position currently holds. Use "absolute" instead to set a fixed quantity via units.
Use case: a TradingView indicator alert fires "SL tightened to swing low" and you want to nudge the stop without touching the position.
Move existing SL to break-even
{
"exchange": "binance-futures",
"pair": "BTCUSDT",
"apiKey": "binance-futures-main",
"updateStopLossToBreakEven": true,
"token": "<token>"
}
Standalone command, no new entry. TVH moves the position's existing SL to its average entry price. This is the same action as the Telegram bot's Set to break-even button.
It only acts when the position is in profit and already has an SL, and it is not wired on every exchange (supported on Bybit, Binance Futures, KuCoin Futures, Coinbase Futures, Hyperliquid, and Coinbase/KuCoin Spot; not on BitMEX, OKX, Binance Spot, Bybit Spot, or Binance Coin-M). The SL lands exactly on entry with no fee offset, so a stop-out there closes slightly negative after fees.
Move SL to any level (manual break-even / trailing)
Where updateStopLossToBreakEven is not supported, or when you want the stop above entry rather than exactly on it, reuse the replace command from above and pass the new level yourself:
{
"exchange": "binance-futures",
"pair": "BTCUSDT",
"apiKey": "binance-futures-main",
"isStopLoss": true,
"cancelSlOrders": true,
"stopLossType": "absolute",
"stopLoss": 64500,
"stopLossSizeType": "currentPosition",
"token": "<token>"
}
Because you choose the price, you can set the SL in profit (here above the 64200 entry). Firing this from your TradingView strategy on each bar — with stopLoss driven by a Pine placeholder or stopLossExpression — lets you build your own trailing logic inside the strategy, on any exchange.
Detail per property
stopLoss
| Attribute | Value |
|---|---|
| Type | decimal |
| Required | conditional (when stopLossType="absolute") |
| Default | 0 |
| TV placeholder compatible | yes |
Absolute stop-loss price. Used as the reference for break-even and trailing offsets.
stopLossPercent
| Attribute | Value |
|---|---|
| Type | decimal |
| Required | conditional (when stopLossType="percent") |
| Default | 0 |
| TV placeholder compatible | yes |
Stop-loss distance in percent from entry. 1.5 = 1.5%.
stopLossType
| Attribute | Value |
|---|---|
| Type | string |
| Required | no |
| Allowed values | "absolute", "percent" |
| Default | "percent" (the Trade Command Builder's default; with no value set, stopLossExpression is only evaluated when you explicitly send "absolute") |
How to interpret stop-loss input. "absolute" enables stopLossExpression evaluation.
stopLossExpression
| Attribute | Value |
|---|---|
| Type | string |
| Required | no |
| Default | "" |
| Auto-mapped | yes — sign-flipped by orderType, evaluated server-side |
| TV placeholder compatible | yes |
Arithmetic expression that resolves to an absolute price. Only evaluated when stopLossType="absolute" and the expression contains at least one of + - * /. See Math Expressions for the full rules.
useTrailingStopLoss
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Convert the stop-loss into a trailing stop.
trailingStopLossPercent
| Attribute | Value |
|---|---|
| Type | decimal |
| Required | conditional (when useTrailingStopLoss=true) |
| Default | 0 |
| TV placeholder compatible | yes |
Trail distance in percent. The stop follows price by this offset once activated.
trailingStopLossActivationPercent
| Attribute | Value |
|---|---|
| Type | decimal |
| Required | no |
| Default | 0 |
| TV placeholder compatible | yes |
Profit threshold (percent from entry) before the trailing stop arms. Below this threshold the SL stays at its initial level. Set to 0 for "arm immediately on fill".
stopLossToBreakEven
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Trailing-stop companion. With useTrailingStopLoss: true, the trailing stop locks at break-even (entry) once the trailing threshold is reached, instead of trailing further. Ignored without trailing. Binance Futures and Bybit only. See Trailing break-even.
updateStopLossToBreakEven
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Standalone command. No new entry placed; TVH moves an open position's existing SL to its average entry price. Acts only when the position is in profit and already has an SL, and is not supported on every exchange. See Move existing SL to break-even.
stopLossSizeType
| Attribute | Value |
|---|---|
| Type | string |
| Required | no |
| Allowed values | "currentPosition", "absolute" |
| Default | "currentPosition" |
Quantity model for the SL order. "currentPosition" (default) keeps the SL matched to whatever the entry actually fills — preferred. "absolute" uses an explicit quantity from units and can desync from the live position on partial fills.
cancelSlOrders
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Cancel all existing stop-loss orders for the pair before placing the new entry/SL. Prevents duplicate SLs when re-entering after a partial fill or when retry logic leaves orphaned stops.
Per-exchange notes
At a glance — the Move SL to BE column is the standalone updateStopLossToBreakEven action; the trailing-companion stopLossToBreakEven is Binance Futures and Bybit only regardless of this column:
| Exchange | Trailing SL | Move SL to BE | SL Expression | Cancel SL on entry |
|---|---|---|---|---|
| Binance Futures | Yes | Yes | Yes | Yes |
| Bybit (UTA) | Yes | Yes | Yes | Yes |
| OKX | Yes | No | Yes | Yes |
| KuCoin | Yes | Yes (Futures) | Yes | Yes |
| BitMex | Limited | No | Yes | Yes |
| Binance Spot | Limited (broker-side OCO) | No | Yes | Yes |
- Binance Futures — native conditional trailing stop.
workingTypecontrols whether triggers fire off mark or last price; default is mark. See Futures → workingType. - Bybit UTA — TP/SL attached to the position via
setTpToPositionis preferred over standalone reduce-only orders. See Take Profit → setTpToPosition. - OKX — native algo SL/TP. Hedge-mode requires
positionSideto disambiguate which side the SL belongs to. - Coinbase Spot — no exchange-side SL on spot. TVH emulates by polling the position and submitting a market exit when the trigger price is crossed.
Common mistakes
- Setting
stopLossExpressionwithstopLossType="percent". The expression is ignored — TVH only evaluates expressions in absolute mode. Switch to"absolute"or usestopLossPercentdirectly. - Trailing without an activation threshold on choppy intraday alerts. A 0.7% trail armed immediately on fill gets hit by a single bar's wick. Pair with a 0.3–0.5% activation buffer.
stopLossSizeType: "absolute"on a percent-balance entry. The SL quantity is then fixed regardless of how much the entry actually filled. Prefer"currentPosition"unless you know why.- Two payloads racing. Entry payload with SL attached + a follow-up
isStopLoss: truepayload arriving milliseconds apart can leave duplicate SLs. AddcancelSlOrders: trueon the follow-up or rely onalertTimestampfor idempotency.
Next
Take Profit — multi-target ladders, percent vs absolute, Bybit-specific TP-on-position quirks.