Skip to main content

Trade Command Anatomy & Auto-Mapping

The JSON you send is not the JSON the exchange receives. TVH runs a fixed auto-mapping step that adjusts the payload before it reaches the exchange. This page documents exactly what it changes, so an unexpected entry or close never catches you off guard. For the map of every field, start at Advanced Trade Options.

TL;DR
  • Normal webhook/manual payloads should set isBuy, isSell, or isClose directly. orderType is for TradingView strategy-alert templates such as {{strategy.order.action}}.
  • strategyComment containing close, exit, or flat (case-insensitive) auto-triggers a position close, even with an entry-shaped payload.
  • stopLossExpression and takeProfitExpression are evaluated server-side with sign-flipping based on orderType.
  • TradingView Pine placeholders ({{ticker}}, {{close}}, {{strategy.order.price}}, etc.) are substituted by TradingView before the webhook fires — TVH never sees the curly braces.

Lifecycle from Pine to position

A couple of receiver-side details that occasionally surprise:

  • The webhook body is URL-decoded and then has every = stripped before JSON parsing. This compensates for TradingView's application/x-www-form-urlencoded quirk. You don't need to encode anything specially — but JSON values that contain literal = characters will lose them.
  • Property matching is case-insensitive. Exchange and exchange both work. Stick with camelCase for clarity.

Auto-mapping: what the server changes

Right after it parses your JSON, the server runs the auto-mapping step on every payload. It performs four adjustments. Each one is documented below with the exact rule and an example of when it bites.

1. Strategy-alert orderType → boolean flags

For TradingView strategy alerts, TVH can derive isBuy, isSell, isClose (and sometimes isMarket, chaseLimitOrder) from the orderType string field. For normal webhook/manual commands, set the boolean direction fields directly.

orderType (case-insensitive)Flags set
"buy"isBuy = true, isSell = false, isClose = false
"sell"isBuy = false, isSell = true, isClose = false
"close"isBuy = false, isSell = false, isClose = true, isMarket = true; also chaseLimitOrder = false unless useLimitClose is true

Use orderType when your alert maps {{strategy.order.action}}. Otherwise set the booleans directly. The applied recipe is in Strategy Alerts → closed-source automation.

2. strategyComment → auto-close

If strategyComment contains any of the substrings close, exit, or flat (case-insensitive), TVH overrides the direction flags into a close:

isBuy = false
isSell = false
isClose = true
isMarket = true
chaseLimitOrder = false // unless useLimitClose=true

This wins even if you set orderType: "buy". So any comment containing close (e.g. "Closed above EMA") flips an entry into an exit.

  • Custom keywords: set strategyCloseValue to a token or pipe-separated list ("TP|SL|Ex Short") to register additional close triggers. It does not replace the built-in close|exit|flat scan — that always runs first, so those three words still force a close regardless of strategyCloseValue.
  • Hedge mode: when the close triggers, closeLong / closeShort are reconciled with orderType so only the matching side is closed.

Worked examples for both (closed-source automation, custom tokens, hedge reversals) are in Strategy Alerts → closed-source automation.

3. stopLossExpression → arithmetic evaluation

When stopLossType="absolute" and stopLossExpression contains any of + - * /, TVH evaluates the expression server-side and writes the result to stopLoss.

{
"stopLossType": "absolute",
"stopLossExpression": "3660-0.02*3660"
}

After parsing: stopLoss = 3592.8.

Smart sign-flip: TVH adjusts operators so the SL ends up on the correct side of entry, based on orderType:

orderTypeOperator in expressionAuto-flipped to
"sell"-+
"buy"+-

That way the same Pine template works for longs and shorts:

stopLossExpression = "{{strategy.order.price}}-0.02*{{strategy.order.price}}"
  • On a long (orderType="buy"): SL = entry − 2% = below entry. Correct.
  • On a short (orderType="sell"): sign flips to +, SL = entry + 2% = above entry. Also correct.

Same machinery for take-profit: takeProfitExpression updates targets[0].price when targetType="absolute". The sign-flip is inverted (TPs sit on the opposite side of entry vs SL).

Errors are silently swallowed. If the expression can't be evaluated (e.g. you used ^ for power, which isn't supported), TVH does nothing. stopLoss stays at its prior value (often 0, which means no stop is placed). Test your expressions before you go live.

Full operator list and patterns in Math Expressions.

4. useLimitClose gate on close-chase

When the payload is forced into close mode (by orderType="close", a comment match, or a custom strategyCloseValue match), TVH also sets chaseLimitOrder = falseunless useLimitClose is true. This protects against accidental limit-chase loops on exit signals where the user expected a market close.

Default values to be aware of

These are the built-in defaults. Sending the field is optional; omitting it gives you the default behaviour shown below.

PropertyDefaultImplication if you forget
postOnlytrueLimit orders are maker-only. A marketable limit price is rejected silently. Flip to false for taker fills.
unitsType"absolute"units is interpreted as base-asset quantity. Switch to "percent" for balance-relative sizing.
targetType"percent"Use targets[].takeProfitPercent for percent-distance targets. Set "absolute" to use fixed targets[].price levels.
limitPriceType"fixedPrice"TVH uses your price verbatim. Other values pin to top-of-book.
retries1One re-send on a Binance overload (server-busy) response. Capped at 10; not a general cross-exchange retry.
updateLimitOrderTimeInterval20 (seconds)20 s between chase attempts. With the fixed 180-attempt budget, that's a ~1 hour chase by default.
positionSide"net"OKX one-way mode. Set "long" / "short" for OKX hedge mode.
workingType"mark"Binance Futures: SL/TP triggers off mark price (safer). "contract" uses last trade price.
stopLossSizeType"currentPosition"SL sized to whatever the entry actually fills. Preferred over "absolute".
partialCloseType"percent"partialCloseValue is a percent of position.
partialCloseAsset"quote"When partialCloseType="absolute", the value is in quote currency.

These defaults match what the live webhook applies, so the table above always reflects current behaviour.

Dynamic values via TradingView placeholders

Placeholders like {{ticker}} or {{strategy.order.price}} are replaced by TradingView with live values before the webhook is posted. By the time the auto-mapping step runs, the curly braces are gone and the fields already hold real values, which is why TVH never sees a literal {{...}}. Booleans can't be placeholder-driven; strings, decimals, and integers can (the tv_placeholder_compatible column in the Parameter Reference marks which).

Next

You now know what the server does on top of your JSON. Hop to the Parameter Reference for the full sortable table, or jump straight to a category like Core or Stop Loss.