Conditional Logic
Pre-execution guards that decide whether the trade should even fire, and post-fill modifiers that close only part of the position or only when in profit. Ten fields total, all optional.
preventPyramiding: true— hard reject any new entry if a position is already open on the pair.conditionalPyramiding+pyramidingValue+conditionalAsset— soft cap: stack only until the position reaches a maximum size, then trim or reject.closeInProfit: truewithcloseInProfitValue: 0.2— close the position only if it's at least 0.2% in profit. Below threshold, the close is skipped.usePartialClose: truewithpartialCloseValue— close only N% (or N units) of the position.
closeInProfitValue and partialCloseValue accept Pine placeholders. The boolean flags do not.
Quick reference table
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
preventPyramiding | bool | no | false | Hard guard: if a position is already open on the pair, reject the new entry. Prevents stacking on noisy alerts. |
usePartialClose | bool | no | false | Close only a portion of the current position instead of the whole thing. Size of the cut comes from partialCloseValue + partialCloseType. |
partialCloseValue | decimal | conditional | 0 | Amount to close. Interpretation set by partialCloseType (percent of position vs absolute units). |
conditionalPyramiding | bool | no | false | Soft guard: cap the position size on the pair. Stacking is allowed until the open position reaches pyramidingValue, then the new order is trimmed to the remaining capacity or rejected. Only inspects position size — no DCA-leg or order-count check. |
pyramidingValue | decimal | conditional | 0 | Maximum position size allowed on the pair for conditionalPyramiding. A base-asset quantity when conditionalAsset="base", otherwise a quote-currency value. Once reached, further entries are trimmed or rejected. |
conditionalAsset | string | no | — | Selects how pyramidingValue is read: base compares against the position's base-asset quantity, quote (or empty) against its quote-currency value. Always inspects the same pair's position, not a different asset. |
closeInProfit | bool | no | false | Close the existing position only if it is currently in profit by at least closeInProfitValue (percent). Useful for break-even-protective exits. |
partialCloseType | string | no | percent | Interpret partialCloseValue as a percent of the position or as an absolute quantity. |
partialCloseAsset | string | no | quote | When partialCloseType="absolute", choose whether the value is denominated in the base or quote asset. |
closeInProfitValue | decimal | conditional | 0 | Minimum profit (percent) required before closeInProfit triggers the exit. Below the threshold the close is skipped. |
Anti-pyramiding patterns
When your Pine strategy fires repeatedly without exiting first, you can end up stacking positions on top of each other ("pyramiding"). Two flags let you control whether stacking is allowed.
Hard guard — preventPyramiding
{
"preventPyramiding": true,
"isBuy": true,
"isMarket": true,
"units": 0.05
}
If a position is already open on the pair (any direction), the entry is rejected. The Activity Log shows "skipped due to pyramiding guard". No order is sent to the exchange.
Use this as the default for strategies where every alert is a fresh entry decision and stacking is never intended.
Soft guard — conditionalPyramiding
conditionalPyramiding is a maximum-position-size cap. Stacking is allowed until the open position on the pair reaches pyramidingValue; after that the incoming order is trimmed or rejected.
{
"conditionalPyramiding": true,
"pyramidingValue": 0.05,
"conditionalAsset": "base",
"isBuy": true,
"isMarket": true,
"units": 0.02
}
TVH inspects the current position on the same pair and compares it against pyramidingValue:
conditionalAsset: "base"— compare against the position's base-asset quantity (here: cap at 0.05 BTC).conditionalAsset: "quote"(or empty) — compare against the position's value in quote currency (notional; on futures, margin / notional-per-leverage).- If the position already meets or exceeds the cap, the entry is rejected.
- If there is headroom but the order would overshoot the cap, the order size is trimmed to the remaining capacity rather than rejected. If the trimmed size rounds to zero, it is rejected.
It only looks at position size. There is no check on the number of DCA legs or open orders.
Profit-only close
{
"isClose": true,
"closeInProfit": true,
"closeInProfitValue": 0.2
}
The exit only fires if the current position is at least 0.2% in profit. Below the threshold, the close is skipped and the position stays open.
Use this for break-even-protective exits: a trailing strategy's "exit on RSI reversal" alert that you want to ignore when the position is still underwater.
closeInProfitValue is in percent, not absolute price. Works for both longs and shorts — TVH computes unrealised PnL against the position's average entry.
Combine with partial close
{
"isClose": true,
"closeInProfit": true,
"closeInProfitValue": 0.5,
"usePartialClose": true,
"partialCloseValue": 50,
"partialCloseType": "percent"
}
Close half the position, but only if at least 0.5% in profit. A common pattern for "scale out into strength while letting losers ride to SL".
Partial close mechanics
Closing exactly N% of a position, or N units of base/quote.
By percent
{
"usePartialClose": true,
"partialCloseValue": 50,
"partialCloseType": "percent"
}
Close 50% of the current position. Direction inferred from orderType or from the open position when orderType: "close".
By absolute base asset
{
"usePartialClose": true,
"partialCloseValue": 0.01,
"partialCloseType": "absolute",
"partialCloseAsset": "base"
}
Close exactly 0.01 BTC (base asset on BTCUSDT). Useful when you want a consistent quantity-per-exit regardless of remaining position size.
By absolute quote currency
{
"usePartialClose": true,
"partialCloseValue": 200,
"partialCloseType": "absolute",
"partialCloseAsset": "quote"
}
Close $200 worth of the position. TVH converts to base units at the current mark price before submitting.
Default behaviour
When you omit partialCloseType and partialCloseAsset:
partialCloseTypedefaults to"percent"— the value is read as a percent.partialCloseAssetdefaults to"quote"— only relevant whenpartialCloseTypeis"absolute".
So the simplest form is just:
{
"usePartialClose": true,
"partialCloseValue": 25
}
That closes 25% of the position. Equivalent to specifying partialCloseType: "percent" explicitly.
Detail per property
preventPyramiding
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Hard guard. If a position is already open, reject the new entry.
conditionalPyramiding
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Soft guard. Cap the position size on the pair: stack only until the open position reaches pyramidingValue, then trim or reject the new order.
pyramidingValue
| Attribute | Value |
|---|---|
| Type | decimal |
| Required | conditional (when conditionalPyramiding=true) |
| Default | 0 |
The maximum position size allowed on the pair. Read as a base-asset quantity when conditionalAsset: "base", otherwise as a quote-currency value. Once the position reaches it, further entries are trimmed to the remaining capacity or rejected.
conditionalAsset
| Attribute | Value |
|---|---|
| Type | string |
| Required | no |
| Allowed values | "base", "quote" |
| Default | "" (treated as "quote") |
Selects how pyramidingValue is interpreted: "base" compares against the position's base-asset quantity, "quote" (or empty) against its quote-currency value. It does not point at a different pair — the same pair's position is always the one inspected.
closeInProfit
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Only execute the close if the current position is in profit by at least closeInProfitValue percent.
closeInProfitValue
| Attribute | Value |
|---|---|
| Type | decimal |
| Required | conditional (when closeInProfit=true) |
| Default | 0 |
| TV placeholder compatible | yes |
Minimum profit (percent) required before the close fires.
margin
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Flag used by spot-margin adapters (KuCoin margin) to mark the trade as margin rather than plain spot. See the canonical Futures → margin entry for the full description — this anchor exists for cross-linking from the conditional-logic table only.
usePartialClose
| Attribute | Value |
|---|---|
| Type | bool |
| Required | no |
| Default | false |
Close only part of the position. Pair with partialCloseValue.
partialCloseValue
| Attribute | Value |
|---|---|
| Type | decimal |
| Required | conditional (when usePartialClose=true) |
| Default | 0 |
| TV placeholder compatible | yes |
The amount to close. Interpretation depends on partialCloseType.
partialCloseType
| Attribute | Value |
|---|---|
| Type | string |
| Required | no |
| Allowed values | "percent", "absolute" |
| Default | "percent" |
Interpret partialCloseValue as a percent of the position or as an absolute quantity.
partialCloseAsset
| Attribute | Value |
|---|---|
| Type | string |
| Required | no |
| Allowed values | "base", "quote" |
| Default | "quote" |
When partialCloseType="absolute", choose whether the value is denominated in the base or quote asset.
Common mistakes
preventPyramidingon a DCA strategy. Pyramiding-prevent and DCA mesh are incompatible — every DCA leg looks like a new entry. UseconditionalPyramidingor disable the guard for DCA setups.closeInProfitwithcloseInProfitValueset to a price, not percent. The field is percent.closeInProfitValue: 65000is "65000%" — never triggers.usePartialClosewithoutpartialCloseValue. The flag does nothing;partialCloseValue=0means "close zero amount". Set the value explicitly.partialCloseType: "absolute"withpartialCloseAsset: "quote"on a leveraged position. The quote conversion uses notional, not margin. 200 USDT of notional on 10x is 20 USDT of margin. Confirm which you mean.
Next
Close & Cancel — flat-the-position commands and bulk-cancel cascades.