Skip to main content

Strategy Templates — Copy, Paste, Customize

TL;DR

Seven schema-correct Pine v5 + JSON pairs covering the most common TVH use cases: spot long-only, long+short reversal, multi-TP scaling, risk-based sizing, DCA grids, hedge mode, closed-source strategy wrappers. Every template is validated against the canonical trade-command schema. Paste into an LLM as a starting point and ask it to riff.

Each template includes:

  • Use case — one-sentence purpose.
  • Pine v5 — full strategy script with alert_message per order.
  • JSON (entry) and JSON (close) — the resolved payload TVH receives.
  • Customization hooks — comments marking where to edit.
  • LLM riff prompts — copy-paste suggestions to extend the template.

Set the TradingView alert Message field to {{strategy.order.alert_message}} for every template. Replace YOUR_TOKEN with your TVH user token and YOUR_KEY_NAME with your saved API key label.


Template A — Simple Long-Only EMA Crossover (Binance Spot)

Use case: the absolute minimum. Buy when 9 EMA crosses 21 EMA, close on reverse cross. No SL, no TP.

Best for: beginners testing the TVH wire-up · 4H or 1D · BTCUSDT / ETHUSDT.

//@version=5
strategy("TVH-A: EMA Cross Long", overlay=true,
default_qty_type=strategy.percent_of_equity, default_qty_value=5,
pyramiding=0, process_orders_on_close=true)

// === CUSTOMIZE THESE ===
fastLen = input.int(9, "Fast EMA")
slowLen = input.int(21, "Slow EMA")

fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)

cross_up = ta.crossover(fast, slow)
cross_down = ta.crossunder(fast, slow)

// === TVH PAYLOADS ===
buy_command = '{"exchange":"binance","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isBuy":true,"unitsType":"percent","unitsPercent":5,"isMarket":true,"alertTimestamp":"{{ticker}}-{{timenow}}","token":"YOUR_TOKEN"}'
close_command = '{"exchange":"binance","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isClose":true,"token":"YOUR_TOKEN"}'

if cross_up
strategy.entry("Long", strategy.long, alert_message=buy_command)
if cross_down and strategy.position_size > 0
strategy.close("Long", alert_message=close_command)

JSON (entry):

{
"exchange": "binance",
"pair": "BTCUSDT",
"apiKey": "YOUR_KEY_NAME",
"isBuy": true,
"unitsType": "percent",
"unitsPercent": 5,
"isMarket": true,
"alertTimestamp": "BTCUSDT-1715900400000",
"token": "YOUR_TOKEN"
}

JSON (close):

{
"exchange": "binance",
"pair": "BTCUSDT",
"apiKey": "YOUR_KEY_NAME",
"isClose": true,
"token": "YOUR_TOKEN"
}

LLM riff prompts:

  • "Add a 2% stop loss and a 4% take profit to Template A."
  • "Convert Template A from Binance Spot to Bybit Spot with the same logic."

Template B — Long + Short Reversal (Bybit Futures)

Use case: trade both sides. Reverse on every cross — flat then re-enter.

Best for: ranging-to-trending altcoins · Bybit perps · 1H–4H.

//@version=5
strategy("TVH-B: Reversal", overlay=true,
default_qty_type=strategy.percent_of_equity, default_qty_value=5,
pyramiding=0, process_orders_on_close=true)

fastLen = input.int(9, "Fast EMA")
slowLen = input.int(21, "Slow EMA")
lev = input.int(3, "Leverage")

fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)

long_signal = ta.crossover(fast, slow)
short_signal = ta.crossunder(fast, slow)

buy_command = '{"exchange":"bybit","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","leverage":3,"marginType":"cross","isBuy":true,"unitsType":"percent","unitsPercent":5,"isMarket":true,"stopLossType":"percent","stopLossPercent":2,"alertTimestamp":"{{ticker}}-{{timenow}}","token":"YOUR_TOKEN"}'
sell_command = '{"exchange":"bybit","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","leverage":3,"marginType":"cross","isSell":true,"unitsType":"percent","unitsPercent":5,"isMarket":true,"stopLossType":"percent","stopLossPercent":2,"alertTimestamp":"{{ticker}}-{{timenow}}","token":"YOUR_TOKEN"}'
close_command = '{"exchange":"bybit","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isClose":true,"token":"YOUR_TOKEN"}'

if long_signal
strategy.entry("Long", strategy.long, alert_message=buy_command)
if short_signal
strategy.entry("Short", strategy.short, alert_message=sell_command)

JSON (long entry):

{
"exchange": "bybit",
"pair": "ETHUSDT",
"apiKey": "YOUR_KEY_NAME",
"leverage": 3,
"marginType": "cross",
"isBuy": true,
"unitsType": "percent",
"unitsPercent": 5,
"isMarket": true,
"stopLossType": "percent",
"stopLossPercent": 2,
"alertTimestamp": "ETHUSDT-1715900400000",
"token": "YOUR_TOKEN"
}

JSON (short entry): same as long but "isSell":true.

LLM riff prompts:

  • "Make Template B asymmetric — 5x leverage on longs, 3x on shorts."
  • "Add a single take profit at 4% to Template B with targetAmountInPercent: true."

Template C — RSI Pullback with Multi-TP Ladder (Bybit Spot or Futures)

Use case: scale out at three TPs after an oversold pullback in an uptrend.

Best for: ranging altcoins inside uptrend · 1H–4H · Bybit (uses setTpToPosition for UTA).

//@version=5
strategy("TVH-C: RSI Pullback Multi-TP", overlay=true,
default_qty_type=strategy.percent_of_equity, default_qty_value=3,
pyramiding=0, process_orders_on_close=true)

rsiLen = input.int(14, "RSI Length")
overSold = input.int(30, "Oversold Level")
exitRsi = input.int(60, "Exit RSI")
trendLen = input.int(200, "Trend EMA")

r = ta.rsi(close, rsiLen)
trendOk = close > ta.ema(close, trendLen)

long_signal = ta.crossover(r, overSold) and trendOk
exit_signal = ta.crossunder(r, exitRsi)

// 30/30/40 ladder at 0.8% / 1.6% / 3% above entry.
buy_command = '{"exchange":"bybit","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isBuy":true,"unitsType":"percent","unitsPercent":3,"isMarket":true,"stopLossType":"percent","stopLossPercent":1.5,"targetType":"percent","targetAmountInPercent":true,"targets":[{"takeProfitPercent":0.8,"amount":30},{"takeProfitPercent":1.6,"amount":30},{"takeProfitPercent":3,"amount":40}],"setTpToPosition":true,"alertTimestamp":"{{ticker}}-{{timenow}}","token":"YOUR_TOKEN"}'
close_command = '{"exchange":"bybit","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isClose":true,"token":"YOUR_TOKEN"}'

if long_signal
strategy.entry("Long", strategy.long, alert_message=buy_command)
if exit_signal and strategy.position_size > 0
strategy.close("Long", alert_message=close_command)

JSON (entry):

{
"exchange": "bybit",
"pair": "ADAUSDT",
"apiKey": "YOUR_KEY_NAME",
"isBuy": true,
"unitsType": "percent",
"unitsPercent": 3,
"isMarket": true,
"stopLossType": "percent",
"stopLossPercent": 1.5,
"targetType": "percent",
"targetAmountInPercent": true,
"targets": [
{
"takeProfitPercent": 0.8,
"amount": 30
},
{
"takeProfitPercent": 1.6,
"amount": 30
},
{
"takeProfitPercent": 3,
"amount": 40
}
],
"setTpToPosition": true,
"alertTimestamp": "ADAUSDT-1715900400000",
"token": "YOUR_TOKEN"
}

LLM riff prompts:

  • "Add a trailing stop to Template C that arms at 1R (1.5% profit) and trails 0.7%."
  • "Mirror Template C for shorts — overbought=70, exit on crossover(r, 40)."

Template D — Risk-Based Sizing via fixedQuoteSize (Binance Futures)

Use case: risk a fixed dollar amount per trade. Compute the position size in Pine from account_equity × risk_pct / sl_distance_pct and ship as fixedQuoteSize.

Best for: disciplined risk management · any futures pair · any timeframe.

//@version=5
strategy("TVH-D: Risk-Based Sizing", overlay=true,
default_qty_type=strategy.percent_of_equity, default_qty_value=1,
pyramiding=0, process_orders_on_close=true)

emaLen = input.int(50, "EMA Length")
atrLen = input.int(14, "ATR Length")
atrMult = input.float(1.5, "ATR Multiplier")
equity = input.float(1000, "Account equity (USDT)")
riskPct = input.float(1, "Risk % per trade")
lev = input.int(3, "Leverage")

ema = ta.ema(close, emaLen)
atr = ta.atr(atrLen) * atrMult
sl_long_distance = atr / close * 100 // percent distance
position_quote = (equity * riskPct / 100) / (sl_long_distance / 100)

go_long = ta.crossover(close, ema)
go_short = ta.crossunder(close, ema)

// fixedQuoteSize ships a literal USD amount; useFixedSize=true makes TVH ignore units/unitsType.
// buy_command and sell_command are pre-resolved by Pine via str.format() — Pine writes the literal JSON.
// close_command uses TV alert placeholders ({{ticker}}, {{close}}) — resolved by TradingView at alert fire.
buy_command = str.format('{{"exchange":"binance-futures","pair":"{0}","apiKey":"YOUR_KEY_NAME","leverage":{1},"marginType":"cross","isBuy":true,"useFixedSize":true,"fixedQuoteSize":{2},"isMarket":true,"stopLossType":"absolute","stopLoss":{3},"alertTimestamp":"{0}-{4}","token":"YOUR_TOKEN"}}', syminfo.ticker, lev, position_quote, close - atr, time)
sell_command = str.format('{{"exchange":"binance-futures","pair":"{0}","apiKey":"YOUR_KEY_NAME","leverage":{1},"marginType":"cross","isSell":true,"useFixedSize":true,"fixedQuoteSize":{2},"isMarket":true,"stopLossType":"absolute","stopLoss":{3},"alertTimestamp":"{0}-{4}","token":"YOUR_TOKEN"}}', syminfo.ticker, lev, position_quote, close + atr, time)
close_command = '{"exchange":"binance-futures","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isClose":true,"token":"YOUR_TOKEN"}'

if go_long
strategy.entry("Long", strategy.long, alert_message=buy_command)
if go_short
strategy.entry("Short", strategy.short, alert_message=sell_command)

JSON (long entry, example):

{
"exchange": "binance-futures",
"pair": "BTCUSDT",
"apiKey": "YOUR_KEY_NAME",
"leverage": 3,
"marginType": "cross",
"isBuy": true,
"useFixedSize": true,
"fixedQuoteSize": 666.67,
"isMarket": true,
"stopLossType": "absolute",
"stopLoss": 64012.5,
"alertTimestamp": "BTCUSDT-1715900400000",
"token": "YOUR_TOKEN"
}

Why fixedQuoteSize and not unitsType: "risk"? Both work. unitsType: "risk" makes TVH back-solve the size from stopLossPercent and the account's risk percentage (configured in your dashboard). fixedQuoteSize is more explicit — you compute the dollar amount in Pine where you can see the ATR and equity at the bar. Use risk when you don't want Pine to see your equity; use fixedQuoteSize when you want full control.

LLM riff prompts:

  • "Refactor Template D to use unitsType: 'risk' instead of fixedQuoteSize."
  • "Add useTrailingStopLoss to Template D that arms at 2R profit with a 0.5% trail."

Template E — DCA Grid Entry (Binance Spot)

Use case: average into oversold dips with five legs. One market entry + four limit averages, 1.5% apart.

Best for: mean-reversion plays · high-quality majors · 1H–4H.

//@version=5
strategy("TVH-E: DCA Grid", overlay=true,
default_qty_type=strategy.percent_of_equity, default_qty_value=20,
pyramiding=4, process_orders_on_close=true)

rsiLen = input.int(14, "RSI Length")
rsiBuy = input.int(35, "RSI Trigger")

r = ta.rsi(close, rsiLen)
long_signal = ta.crossover(r, rsiBuy)

// useDca is the master switch. dcaPercent: total spread. dcaOrderCount: number of follow-up limits.
// 1 market + 4 limits = 5 legs total. 25% of cash per leg consumes 100% across the grid.
buy_command = '{"exchange":"binance","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isBuy":true,"unitsType":"percent","unitsPercent":25,"isLimit":true,"postOnly":false,"limitPriceType":"fixedPrice","price":"{{close}}","useDca":true,"dcaPercent":1.5,"dcaOrderCount":4,"targetType":"percent","targetAmountInPercent":true,"targets":[{"takeProfitPercent":3,"amount":100}],"stopLossType":"percent","stopLossPercent":7,"alertTimestamp":"{{ticker}}-{{timenow}}","token":"YOUR_TOKEN"}'
close_command = '{"exchange":"binance","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isClose":true,"cancelAllDcaOrders":true,"token":"YOUR_TOKEN"}'

if long_signal and strategy.position_size == 0
strategy.entry("DCA", strategy.long, alert_message=buy_command)

JSON (entry):

{
"exchange": "binance",
"pair": "BTCUSDT",
"apiKey": "YOUR_KEY_NAME",
"isBuy": true,
"unitsType": "percent",
"unitsPercent": 25,
"isLimit": true,
"postOnly": false,
"limitPriceType": "fixedPrice",
"price": "65000",
"useDca": true,
"dcaPercent": 1.5,
"dcaOrderCount": 4,
"targetType": "percent",
"targetAmountInPercent": true,
"targets": [
{
"takeProfitPercent": 3,
"amount": 100
}
],
"stopLossType": "percent",
"stopLossPercent": 7,
"alertTimestamp": "BTCUSDT-1715900400000",
"token": "YOUR_TOKEN"
}

JSON (close, with DCA cleanup):

{
"exchange": "binance",
"pair": "BTCUSDT",
"apiKey": "YOUR_KEY_NAME",
"isClose": true,
"cancelAllDcaOrders": true,
"token": "YOUR_TOKEN"
}

LLM riff prompts:

  • "Switch Template E to a scaledOrderStyle: 'bigSmall' weighted ladder."
  • "Add a wider Bonus E that uses dcaOrderCount: 7 and dcaPercent: 3 for deeper averages."

Template F — Hedge Mode (Binance Futures)

Use case: Binance Futures dual-position mode. Long and short open simultaneously on the same pair, closed independently via closeLong / closeShort.

Best for: scalper hedges, news straddles · Binance Futures USD-M (hedge mode toggled in your Binance account beforehand).

//@version=5
strategy("TVH-F: Hedge Mode", overlay=true,
default_qty_type=strategy.percent_of_equity, default_qty_value=5,
pyramiding=1, process_orders_on_close=true)

fastLen = input.int(9, "Fast EMA")
slowLen = input.int(21, "Slow EMA")

fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)

go_long = ta.crossover(fast, slow)
go_short = ta.crossunder(fast, slow)
close_longs = ta.crossunder(fast, slow)
close_shorts = ta.crossover(fast, slow)

// hedgeMode: true is the master switch. Without it Binance defaults to one-way mode.
buy_command = '{"exchange":"binance-futures","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","leverage":3,"marginType":"cross","isBuy":true,"unitsType":"percent","unitsPercent":5,"isMarket":true,"hedgeMode":true,"stopLossType":"percent","stopLossPercent":2,"alertTimestamp":"{{ticker}}-LONG-{{timenow}}","token":"YOUR_TOKEN"}'
sell_command = '{"exchange":"binance-futures","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","leverage":3,"marginType":"cross","isSell":true,"unitsType":"percent","unitsPercent":5,"isMarket":true,"hedgeMode":true,"stopLossType":"percent","stopLossPercent":2,"alertTimestamp":"{{ticker}}-SHORT-{{timenow}}","token":"YOUR_TOKEN"}'
close_long_command = '{"exchange":"binance-futures","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isClose":true,"hedgeMode":true,"closeLong":true,"alertTimestamp":"{{ticker}}-CLOSELONG-{{timenow}}","token":"YOUR_TOKEN"}'
close_short_command = '{"exchange":"binance-futures","pair":"{{ticker}}","apiKey":"YOUR_KEY_NAME","isClose":true,"hedgeMode":true,"closeShort":true,"alertTimestamp":"{{ticker}}-CLOSESHORT-{{timenow}}","token":"YOUR_TOKEN"}'

if go_long
strategy.entry("L", strategy.long, alert_message=buy_command)
if go_short
strategy.entry("S", strategy.short, alert_message=sell_command)
if close_longs
strategy.close("L", alert_message=close_long_command)
if close_shorts
strategy.close("S", alert_message=close_short_command)

JSON (long entry):

{
"exchange": "binance-futures",
"pair": "BTCUSDT",
"apiKey": "YOUR_KEY_NAME",
"leverage": 3,
"marginType": "cross",
"isBuy": true,
"unitsType": "percent",
"unitsPercent": 5,
"isMarket": true,
"hedgeMode": true,
"stopLossType": "percent",
"stopLossPercent": 2,
"alertTimestamp": "BTCUSDT-LONG-1715900400000",
"token": "YOUR_TOKEN"
}

JSON (close long only):

{
"exchange": "binance-futures",
"pair": "BTCUSDT",
"apiKey": "YOUR_KEY_NAME",
"isClose": true,
"hedgeMode": true,
"closeLong": true,
"alertTimestamp": "BTCUSDT-CLOSELONG-1715900400000",
"token": "YOUR_TOKEN"
}

LLM riff prompts:

  • "Convert Template F to OKX hedge mode using positionSide: 'long' and 'short' instead of closeLong / closeShort."
  • "Add a TP ladder to both directions in Template F."

Template G — Closed-Source Strategy Wrapper

Use case: you bought a Pine indicator/strategy and can only edit the alert Message field. Use TradingView's {{strategy.order.action}} and {{strategy.order.comment}} placeholders to dispatch buys, sells, and exits with a single payload.

Best for: rented strategies · invite-only Pine · "I can't see the source" workflows.

The Pine source is the vendor's — you don't touch it. You only configure the alert with one Message. Here is the payload:

{
"exchange": "bitmex",
"pair": "XBTUSD",
"apiKey": "YOUR_KEY_NAME",
"orderType": "{{strategy.order.action}}",
"strategyComment": "{{strategy.order.comment}}",
"strategyCloseValue": "close|exit|flat",
"unitsType": "percentWallet",
"unitsPercent": 50,
"isMarket": true,
"alertTimestamp": "{{ticker}}-{{timenow}}",
"token": "YOUR_TOKEN"
}

How the auto-mapping works:

  1. {{strategy.order.action}} resolves to buy or sell based on the vendor's strategy.entry / strategy.close calls.
  2. {{strategy.order.comment}} resolves to the comment argument the vendor passed (often "Exit Long", "Exit Short", "", or custom labels).
  3. TVH's auto-mapping inspects strategyComment for any substring in strategyCloseValue. If matched, it auto-sets isClose: true and forces a market exit regardless of orderType.

JSON (resolved as entry, action=buy, no comment):

{
"exchange": "bitmex",
"pair": "XBTUSD",
"apiKey": "YOUR_KEY_NAME",
"isBuy": true,
"strategyComment": "",
"strategyCloseValue": "close|exit|flat",
"unitsType": "percentWallet",
"unitsPercent": 50,
"isMarket": true,
"alertTimestamp": "XBTUSD-1715900400000",
"token": "YOUR_TOKEN"
}

JSON (resolved as exit, action=sell, comment="Exit Long"):

{
"exchange": "bitmex",
"pair": "XBTUSD",
"apiKey": "YOUR_KEY_NAME",
"isSell": true,
"strategyComment": "Exit Long",
"strategyCloseValue": "close|exit|flat",
"unitsType": "percentWallet",
"unitsPercent": 50,
"isMarket": true,
"alertTimestamp": "XBTUSD-1715900400000",
"token": "YOUR_TOKEN"
}

The receiver sees "Exit Long" matches the substring exit in strategyCloseValue → auto-sets isClose: true. The position is closed regardless of the sell action. See Strategy Alerts → closed-source automation for the full recipe.

LLM riff prompts:

  • "Adapt Template G for Bybit Spot using unitsType: 'percentBalance'."
  • "Add a stop loss to Template G that only applies on entries (not on exits)."

Customization checklist

Before going live with any template:

  • Replace YOUR_TOKEN with your actual TVH user token from Account & API Keys.
  • Replace YOUR_KEY_NAME with the label you set for your saved exchange credentials (case-sensitive).
  • Adjust exchange to match your active account (binance-futures-testnet for paper testing!).
  • Verify the pair format for your exchange — see Exchange Quirks.
  • Tune sizing (unitsType, unitsPercent, fixedQuoteSize, etc.) for your account size.
  • Set leverage and marginType deliberately — TVH won't change them once a position is open.
  • Confirm alertTimestamp uses "{{ticker}}-{{timenow}}" for idempotency.
  • Set the TradingView alert Message to {{strategy.order.alert_message}} and the Condition to "Order fills only".
  • Use the correct webhook URL — https://binance.tv-hub.org for Binance, https://alerts.tv-hub.org otherwise.

Combining templates

The LLM can merge two templates if you ask. Examples:

  • Template C + E (DCA grid with multi-TP scale-out): "Combine Template C's three-target ladder with Template E's useDca grid. Keep the 1.5% leg spacing but reduce targets to three percent levels at 1.5/3/5."
  • Template B + F (reversal in hedge mode): "Apply Template B's reversal logic with Template F's hedge mode so the previous direction stays open during a re-entry."
  • Template D + F (risk-based sizing in hedge mode): "Use Template D's fixedQuoteSize calculation with Template F's hedgeMode: true and separate close commands."

Paste both templates into the LLM, name them by letter, and describe the merger you want. The model handles the field-name reconciliation if it has llms-full.txt in context.