Strategy Templates — Copy, Paste, Customize
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_messageper 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 offixedQuoteSize." - "Add
useTrailingStopLossto 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: 7anddcaPercent: 3for 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 ofcloseLong/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:
{{strategy.order.action}}resolves tobuyorsellbased on the vendor'sstrategy.entry/strategy.closecalls.{{strategy.order.comment}}resolves to thecommentargument the vendor passed (often"Exit Long","Exit Short","", or custom labels).- TVH's auto-mapping inspects
strategyCommentfor any substring instrategyCloseValue. If matched, it auto-setsisClose: trueand forces a market exit regardless oforderType.
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_TOKENwith your actual TVH user token from Account & API Keys. - Replace
YOUR_KEY_NAMEwith the label you set for your saved exchange credentials (case-sensitive). - Adjust
exchangeto match your active account (binance-futures-testnetfor paper testing!). - Verify the
pairformat for your exchange — see Exchange Quirks. - Tune sizing (
unitsType,unitsPercent,fixedQuoteSize, etc.) for your account size. - Set
leverageandmarginTypedeliberately — TVH won't change them once a position is open. - Confirm
alertTimestampuses"{{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.orgfor Binance,https://alerts.tv-hub.orgotherwise.
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
useDcagrid. Keep the 1.5% leg spacing but reducetargetsto 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
fixedQuoteSizecalculation with Template F'shedgeMode: trueand 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.
Related references
- Pine Strategy Cookbook — Eight production strategies with full Pine source.
- Trade Command Examples — Twelve schema-correct payload patterns.
- Boilerplate Strategy — Input-driven GitHub template.
- Common LLM Hallucinations — Fifteen pitfalls and fixes for AI-generated payloads.
- How to Prompt an LLM — Golden Prompt Template plus five concrete examples.