1Copy the scriptPress Copy script above, or the copy button on the code below.
2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.
Source Code
135 lines of Pine Script v6 from template.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.
template.pine
//@version=6
// ─────────────────────────────────────────────────────────────────────────────
// Hyperliquid-Ready Webhook Strategy Template [PopsPineDev]
// License: Open-source (Mozilla Public License 2.0 — TradingView default)
//
// WHAT THIS IS
// A clean EMA-cross + RSI-filter strategy whose real value is the ALERT
// PAYLOAD: a production-grade JSON webhook message with the fields most
// templates forget — an idempotency id, a timestamp for staleness checks,
// and a secret placeholder for HMAC validation.
//
// The strategy logic is intentionally simple so you can replace it with
// your own. The webhook plumbing is the part you keep.
//
// HOW TO USE
// 1. Add to chart (crypto perps recommended: BTC/ETH/SOL, 15m–1H)
// 2. Create alert → Condition: this strategy → "alert() function calls only"
// is NOT used here; select "Order fills events". In the message box put:
// {{strategy.order.alert_message}}
// 3. Point the alert's Webhook URL at your execution backend / bridge.
// This template works with any TradingView→exchange webhook bridge.
//
// WHY EACH PAYLOAD FIELD EXISTS (the part nobody explains)
// • id → unique per signal (ticker+timeframe+bar time). Your backend
// should treat this as an IDEMPOTENCY KEY: if the same id
// arrives twice (TradingView retries on slow responses!),
// execute once and drop the duplicate. One Redis SET NX and
// you'll never double-fill an order.
// • ts → fire-time timestamp ({{timenow}}). Reject alerts older than
// N seconds so a delayed/replayed webhook can't trade on a
// stale price.
// • secret → replace with a long random token, then VERIFY it server-side
// (or better: HMAC the body). Anyone who finds your webhook URL
// can POST to it — this field is your lock.
// • reduce_only → true on exits, so a close can never accidentally flip
// you into a new position if state desyncs.
//
// Built by PopsPineDev — I build custom TradingView→Hyperliquid execution
// pipelines. Links in signature.
// ─────────────────────────────────────────────────────────────────────────────
strategy("Hyperliquid-Ready Webhook Strategy Template [PopsPineDev]",
shorttitle = "HL Webhook Template",
overlay = true,
initial_capital = 10000,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 5,
commission_type = strategy.commission.percent,
commission_value = 0.045, // ≈ Hyperliquid taker fee, adjust to your tier
slippage = 2,
process_orders_on_close = true, // signals fire on confirmed bars only
calc_on_every_tick = false)
// ── INPUTS ───────────────────────────────────────────────────────────────────
grpStrat = "Strategy"
fastLen = input.int(21, "Fast EMA", minval = 1, group = grpStrat)
slowLen = input.int(55, "Slow EMA", minval = 2, group = grpStrat)
rsiLen = input.int(14, "RSI Length", minval = 2, group = grpStrat)
rsiLongMin = input.int(50, "RSI ≥ for Longs", minval = 0, maxval = 100, group = grpStrat)
rsiShortMax = input.int(50, "RSI ≤ for Shorts", minval = 0, maxval = 100, group = grpStrat)
allowLongs = input.bool(true, "Enable Longs", group = grpStrat)
allowShorts = input.bool(true, "Enable Shorts", group = grpStrat)
grpRisk = "Risk (ATR-based)"
atrLen = input.int(14, "ATR Length", minval = 1, group = grpRisk)
slMult = input.float(1.5, "Stop-Loss × ATR", minval = 0.1, step = 0.1, group = grpRisk)
tpMult = input.float(3.0, "Take-Profit × ATR", minval = 0.1, step = 0.1, group = grpRisk)
grpHook = "Webhook Payload"
qtyPct = input.float(5.0, "Position Size (% of equity)", minval = 0.1, maxval = 100, step = 0.5, group = grpHook)
levX = input.int(3, "Leverage (sent to backend)", minval = 1, maxval = 50, group = grpHook,
tooltip = "Informational field for your backend. Cap leverage SERVER-SIDE too — never trust the client alone.")
hookSecret = input.string("REPLACE_WITH_LONG_RANDOM_TOKEN", "Webhook Secret", group = grpHook,
tooltip = "Your backend must verify this (or HMAC the body). Never publish a chart screenshot showing your real token.")
// ── LOGIC ────────────────────────────────────────────────────────────────────
emaFast = ta.ema(close, fastLen)
emaSlow = ta.ema(close, slowLen)
rsiVal = ta.rsi(close, rsiLen)
atrVal = ta.atr(atrLen)
longSignal = allowLongs and ta.crossover(emaFast, emaSlow) and rsiVal >= rsiLongMin
shortSignal = allowShorts and ta.crossunder(emaFast, emaSlow) and rsiVal <= rsiShortMax
// SL/TP levels captured at entry time
longSL = close - atrVal * slMult
longTP = close + atrVal * tpMult
shortSL = close + atrVal * slMult
shortTP = close - atrVal * tpMult
// ── PAYLOAD BUILDER ──────────────────────────────────────────────────────────
// One JSON shape for every event. {{timenow}} is substituted by TradingView
// when the alert actually fires (not at bar close) — that's what you want
// for staleness checks.
f_payload(_action, _sl, _tp, _reduceOnly) =>
_id = syminfo.ticker + "-" + timeframe.period + "-" + str.tostring(time)
'{'
+ '"id":"' + _id + '",'
+ '"ts":"{{timenow}}",'
+ '"action":"' + _action + '",'
+ '"symbol":"' + syminfo.ticker + '",'
+ '"exchange":"HYPERLIQUID",'
+ '"qty_pct":' + str.tostring(qtyPct) + ','
+ '"leverage":' + str.tostring(levX) + ','
+ '"price":"{{close}}",'
+ '"sl":' + str.tostring(_sl, format.mintick) + ','
+ '"tp":' + str.tostring(_tp, format.mintick) + ','
+ '"reduce_only":'+ (_reduceOnly ? "true" : "false") + ','
+ '"secret":"' + hookSecret + '"'
+ '}'
// ── ORDERS ───────────────────────────────────────────────────────────────────
if longSignal
strategy.entry("Long", strategy.long,
alert_message = f_payload("buy", longSL, longTP, false))
strategy.exit("Long-X", from_entry = "Long", stop = longSL, limit = longTP,
alert_message = f_payload("close_long", longSL, longTP, true))
if shortSignal
strategy.entry("Short", strategy.short,
alert_message = f_payload("sell", shortSL, shortTP, false))
strategy.exit("Short-X", from_entry = "Short", stop = shortSL, limit = shortTP,
alert_message = f_payload("close_short", shortSL, shortTP, true))
// ── VISUALS ──────────────────────────────────────────────────────────────────
plot(emaFast, "Fast EMA", color = color.new(color.teal, 0), linewidth = 2)
plot(emaSlow, "Slow EMA", color = color.new(color.orange, 0), linewidth = 2)
plotshape(longSignal, title = "Long", style = shape.triangleup, location = location.belowbar, color = color.teal, size = size.small, text = "LONG")
plotshape(shortSignal, title = "Short", style = shape.triangledown, location = location.abovebar, color = color.orange, size = size.small, text = "SHORT")
// Payload preview table — verify your JSON before wiring real money
var table t = table.new(position.bottom_right, 1, 2, border_width = 1)
if barstate.islast
table.cell(t, 0, 0, "Webhook payload preview (next long):", text_color = color.gray, text_size = size.tiny)
table.cell(t, 0, 1, f_payload("buy", longSL, longTP, false), text_color = color.silver, text_size = size.tiny)
Overview
Hyperliquid-Ready Webhook Strategy Template enters positions based on EMA crossover conditions filtered by RSI thresholds and exits using stop-loss and take-profit levels scaled by ATR multiples. The main settings allow adjustment of EMA lengths, RSI levels, position sizing as a percentage of equity, leverage, and stop-loss and take-profit multipliers. Alerts send structured JSON payloads containing idempotency IDs, timestamps, and reduce-only flags for webhook integration with Hyperliquid. It draws signals and order lines directly on the price chart.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Fast EMA
int
21
fastLen
Slow EMA
int
55
slowLen
RSI Length
int
14
rsiLen
RSI ≥ for Longs
int
50
rsiLongMin
RSI ≤ for Shorts
int
50
rsiShortMax
Enable Longs
bool
true
allowLongs
Enable Shorts
bool
true
allowShorts
ATR Length
int
14
atrLen
Stop-Loss × ATR
float
1.5
slMult
Take-Profit × ATR
float
3.0
tpMult
Position Size (% of equity)
float
5.0
qtyPct
Leverage (sent to backend)
int
3
levX
Show all 13 settings
Setting
Type
Default
Variable
Webhook Secret
string
REPLACE_WITH_LONG_RANDOM_TOKEN
hookSecret
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.
2 EMA/SMA + RSI Strategy [Alorse] combines three configurable moving averages with a short-period Relative Strength Index filter. It plots fast, slow, and trend moving averages on the price chart. Long entries trigger when the fast moving average is above the
This strategy plots on the price chart and opens long or short positions when a weighted score from MACD, Stochastic RSI, RSI, Supertrend and a moving-average crossover exceeds a user-set trigger. Each component has its own weight and candle delay. Entries can
This strategy combines Arnaud Legoux Moving Average percentage price change calculations with an adaptive Gaussian Moving Average to generate trend-following signals. Long and short entries are triggered when the ALMA change calculation crosses above or below
This strategy generates trading signals based on a selectable momentum engine, supporting MACD, RSI, Stochastic, or Rate of Change. Entries trigger on signal crosses, zero-line crosses, or threshold crosses, with an optional moving average trend filter. Risk m
255 EMA Strategy combines an exponential moving average with Average True Range bands and standard MACD crossovers to generate entry signals. Drawn directly on the price chart, it plots the central 255 EMA along with upper and lower volatility envelopes. Trade
This strategy evaluates simple moving averages and the Relative Strength Index to generate trading signals. It calculates a 10-period SMA, a 30-period SMA, and a 14-period RSI. Long positions are entered when the fast SMA crosses above the slow SMA while RSI i