带和通道
P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R//@version=6
indicator("P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R", overlay=true, max_lines_count=500, max_labels_count=500)
// ====== General =====
side = input.string("Long", "Position Side", options= )
usd_dp = input.int(2, "USD decimals", minval=0, maxval=6)
// ====== HUD Settings ======
hud_font = input.string("large", "HUD font size", options= )
hud_bg = input.color(color.new(color.black, 0), "HUD background color")
hud_txtc = input.color(color.white, "HUD text color")
hud_side = input.string("Right of price", "HUD side", options= )
hud_off_bars = input.int(3, "Horizontal offset (bars)", minval=0, maxval=50)
hud_off_atr = input.float(0.2, "Vertical offset from price (ATR)", step=0.1)
atr_len = input.int(14, "ATR length for vertical offset", minval=1)
lock_to_last_bar = input.bool(true, "Lock HUD to the last bar")
// Show HUD even when there are no entries (test text)
force_show_hud = input.bool(true, "🔍 Show HUD even with no entries")
// ====== Shared SL & Targets ======
stop_inp = input.float(0.0, "Stop Loss (shared, optional)", step=0.0001)
use_tp1 = input.bool(false, "Enable Target 1")
tp1 = input.float(0.0, "Target 1 price", step=0.0001)
use_tp2 = input.bool(false, "Enable Target 2")
tp2 = input.float(0.0, "Target 2 price", step=0.0001)
use_tp3 = input.bool(false, "Enable Target 3")
tp3 = input.float(0.0, "Target 3 price", step=0.0001)
use_tp4 = input.bool(false, "Enable Target 4")
tp4 = input.float(0.0, "Target 4 price", step=0.0001)
use_tp5 = input.bool(false, "Enable Target 5")
tp5 = input.float(0.0, "Target 5 price", step=0.0001)
// ====== Four Independent Entries ======
group1 = "Entry 1"
en1 = input.bool(true, "Enable Entry 1", inline=group1)
lev1 = input.int(10, "Leverage", minval=1, maxval=200, inline=group1)
entry1 = input.float(0.0, "Entry 1 price", step=0.0001)
set_now1 = input.bool(false, "⚡ Set Entry1 = Current Price")
mode1 = input.string("USD (USDT)", "Size unit 1", options= )
sem1 = input.string("Margin (apply leverage)", "Size meaning 1", options= )
size1 = input.float(0.0, "Position size 1", step=0.0001)
baseLev1 = input.bool(false, "Apply leverage to 'Coin Quantity' (1)")
group2 = "Entry 2"
en2 = input.bool(false, "Enable Entry 2", inline=group2)
lev2 = input.int(10, "Leverage", minval=1, maxval=200, inline=group2)
entry2 = input.float(0.0, "Entry 2 price", step=0.0001)
set_now2 = input.bool(false, "⚡ Set Entry2 = Current Price")
mode2 = input.string("USD (USDT)", "Size unit 2", options= )
sem2 = input.string("Margin (apply leverage)", "Size meaning 2", options= )
size2 = input.float(0.0, "Position size 2", step=0.0001)
baseLev2 = input.bool(false, "Apply leverage to 'Coin Quantity' (2)")
group3 = "Entry 3"
en3 = input.bool(false, "Enable Entry 3", inline=group3)
lev3 = input.int(10, "Leverage", minval=1, maxval=200, inline=group3)
entry3 = input.float(0.0, "Entry 3 price", step=0.0001)
set_now3 = input.bool(false, "⚡ Set Entry3 = Current Price")
mode3 = input.string("USD (USDT)", "Size unit 3", options= )
sem3 = input.string("Margin (apply leverage)", "Size meaning 3", options= )
size3 = input.float(0.0, "Position size 3", step=0.0001)
baseLev3 = input.bool(false, "Apply leverage to 'Coin Quantity' (3)")
group4 = "Entry 4"
en4 = input.bool(false, "Enable Entry 4", inline=group4)
lev4 = input.int(10, "Leverage", minval=1, maxval=200, inline=group4)
entry4 = input.float(0.0, "Entry 4 price", step=0.0001)
set_now4 = input.bool(false, "⚡ Set Entry4 = Current Price")
mode4 = input.string("USD (USDT)", "Size unit 4", options= )
sem4 = input.string("Margin (apply leverage)", "Size meaning 4", options= )
size4 = input.float(0.0, "Position size 4", step=0.0001)
baseLev4 = input.bool(false, "Apply leverage to 'Coin Quantity' (4)")
// Quick set entries = current price
entry1 := (en1 and set_now1) ? close : entry1
entry2 := (en2 and set_now2) ? close : entry2
entry3 := (en3 and set_now3) ? close : entry3
entry4 := (en4 and set_now4) ? close : entry4
// ====== Helpers ======
to_size(s) =>
s == "tiny" ? size.tiny : s == "small" ? size.small : s == "normal" ? size.normal : s == "large" ? size.large : size.huge
f_usd_str(_val, _decimals) =>
na(_val) ? "—" : str.tostring(math.round(_val * math.pow(10, _decimals)) / math.pow(10, _decimals))
f_qty_base(mode, sem, size, entry, baseLev, lev) =>
float _qty = na
if mode == "USD (USDT)"
_qty := (size > 0 and entry > 0) ? ((sem == "Margin (apply leverage)" ? size * lev : size) / entry) : na
else
_qty := size > 0 ? (baseLev ? size * lev : size) : na
_qty
f_notional_quote(mode, sem, size, entry, lev, baseLev) =>
if mode == "USD (USDT)"
sem == "Margin (apply leverage)" ? size * lev : size
else
(baseLev ? size * lev : size) * entry
f_pnl_quote(side, entry, qty) =>
na(qty) or na(entry) ? na : (side=="Long" ? (close - entry) : (entry - close)) * qty
f_pct(side, entry) =>
na(entry) ? na : ((close - entry) / entry * 100.0) * (side=="Long" ? 1 : -1)
f_roi_pct(side, entry, lev) =>
na(entry) ? na : f_pct(side, entry) * lev
// NOTE: _lineIn must be a line, not a float
f_stickyHLine(_price, _lineIn, _color, _width) =>
var line _out = na
_out := _lineIn
if na(_out)
_out := line.new(bar_index-1, _price, bar_index+1, _price, xloc=xloc.bar_index, extend=extend.both, width=_width, style=line.style_dashed, color=_color)
else
line.set_xy1(_out, bar_index-1, _price)
line.set_xy2(_out, bar_index+1, _price)
line.set_color(_out, _color)
line.set_width(_out, _width)
_out
// ====== 4 Entries Calculations ======
var color entryCols = array.from(color.new(color.yellow, 0), color.new(color.orange, 0), color.new(color.teal, 0), color.new(color.fuchsia, 0))
bool ens = array.from(en1, en2, en3, en4)
float entries = array.from(entry1, entry2, entry3, entry4)
int levs = array.from(lev1, lev2, lev3, lev4)
string modes = array.from(mode1, mode2, mode3, mode4)
string sems = array.from(sem1, sem2, sem3, sem4)
float sizes = array.from(size1, size2, size3, size4)
bool baseLevs = array.from(baseLev1, baseLev2, baseLev3, baseLev4)
float qtys = array.new_float(4, na)
float pnls = array.new_float(4, na)
float pcts = array.new_float(4, na)
float rois = array.new_float(4, na)
float notionals = array.new_float(4, na)
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
ent = array.get(entries, i)
levX = array.get(levs, i)
modeX= array.get(modes, i)
semX = array.get(sems, i)
sizeX= array.get(sizes, i)
bLev = array.get(baseLevs, i)
qty = f_qty_base(modeX, semX, sizeX, ent, bLev, levX)
array.set(qtys, i, qty)
pnlq = f_pnl_quote(side, ent, qty)
array.set(pnls, i, pnlq)
pct = f_pct(side, ent)
array.set(pcts, i, pct)
roi = f_roi_pct(side, ent, levX)
array.set(rois, i, roi)
notq = f_notional_quote(modeX, semX, sizeX, ent, levX, bLev)
array.set(notionals, i, notq)
// ====== Totals & Weighted Avg Entry ======
float totalPnlUSD = 0.0
float totalNotional = 0.0
float totalQty = 0.0
float wAvgEntry = na
for i = 0 to 3
if not na(array.get(pnls, i))
totalPnlUSD += array.get(pnls, i)
if not na(array.get(notionals, i))
totalNotional += array.get(notionals, i)
if not na(array.get(qtys, i)) and array.get(entries, i) > 0
totalQty += array.get(qtys, i)
if totalQty > 0
num = 0.0
for i = 0 to 3
qi = array.get(qtys, i)
ei = array.get(entries, i)
if not na(qi) and ei > 0
num += qi * ei
wAvgEntry := num / totalQty
totalROIweighted = totalNotional > 0 ? (totalPnlUSD / totalNotional) * 100.0 : na
// ====== Nearest TP & R:R ======
float nearestTP = na
float nearestDistPrice = na
float nearestDistPct = na
float risk_pct = na
float reward_pct = na
float rr = na
var float tps = array.new_float()
array.clear(tps)
if use_tp1 and tp1 > 0
array.push(tps, tp1)
if use_tp2 and tp2 > 0
array.push(tps, tp2)
if use_tp3 and tp3 > 0
array.push(tps, tp3)
if use_tp4 and tp4 > 0
array.push(tps, tp4)
if use_tp5 and tp5 > 0
array.push(tps, tp5)
// nearest target in the trade direction (from current price)
if array.size(tps) > 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
cond = side=="Long" ? (_tp > close) : (_tp < close)
if cond
distP = math.abs(_tp - close)
if na(nearestDistPrice) or distP < nearestDistPrice
nearestDistPrice := distP
nearestTP := _tp
if not na(nearestDistPrice) and close != 0
nearestDistPct := (nearestDistPrice / close) * 100.0
float stop = stop_inp > 0 ? stop_inp : na
if not na(wAvgEntry) and not na(stop)
rawRisk = (side=="Long" ? (stop - wAvgEntry) : (wAvgEntry - stop)) / wAvgEntry * 100.0
risk_pct := math.abs(rawRisk)
if not na(wAvgEntry) and not na(nearestTP)
reward_pct := math.abs((side=="Long" ? (nearestTP - wAvgEntry) : (wAvgEntry - nearestTP)) / wAvgEntry * 100.0)
rr := (not na(risk_pct) and not na(reward_pct) and risk_pct != 0) ? reward_pct / risk_pct : na
// ====== Average R:R across all valid targets ======
float rr_avg = na
if not na(wAvgEntry) and not na(stop) and array.size(tps) > 0 and not na(risk_pct) and risk_pct != 0
float sum_rr = 0.0
int cnt_rr = 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
bool validDir = side=="Long" ? (_tp > wAvgEntry) : (_tp < wAvgEntry)
if validDir
_reward = math.abs((side=="Long" ? (_tp - wAvgEntry) : (wAvgEntry - _tp)) / wAvgEntry * 100.0)
_rr = _reward / risk_pct
sum_rr += _rr
cnt_rr += 1
rr_avg := cnt_rr > 0 ? (sum_rr / cnt_rr) : na
// ====== Entry/SL/TP Lines ======
var line entryLines = array.new_line(4, na)
for i = 0 to 3
ln = array.get(entryLines, i)
if array.get(ens, i) and array.get(entries, i) > 0
col = array.get(entryCols, i)
ent = array.get(entries, i)
ln := f_stickyHLine(ent, ln, col, 2)
array.set(entryLines, i, ln)
else
if not na(ln)
line.delete(ln)
array.set(entryLines, i, na)
var line slLine = na
if not na(stop)
slLine := f_stickyHLine(stop, slLine, color.new(color.red, 0), 1)
else
if not na(slLine)
line.delete(slLine)
slLine := na
var line tpLine1 = na
var line tpLine2 = na
var line tpLine3 = na
var line tpLine4 = na
var line tpLine5 = na
if use_tp1 and tp1 > 0
tpLine1 := f_stickyHLine(tp1, tpLine1, color.new(color.teal, 0), 1)
else
if not na(tpLine1)
line.delete(tpLine1)
tpLine1 := na
if use_tp2 and tp2 > 0
tpLine2 := f_stickyHLine(tp2, tpLine2, color.new(color.teal, 0), 1)
else
if not na(tpLine2)
line.delete(tpLine2)
tpLine2 := na
if use_tp3 and tp3 > 0
tpLine3 := f_stickyHLine(tp3, tpLine3, color.new(color.teal, 0), 1)
else
if not na(tpLine3)
line.delete(tpLine3)
tpLine3 := na
if use_tp4 and tp4 > 0
tpLine4 := f_stickyHLine(tp4, tpLine4, color.new(color.teal, 0), 1)
else
if not na(tpLine4)
line.delete(tpLine4)
tpLine4 := na
if use_tp5 and tp5 > 0
tpLine5 := f_stickyHLine(tp5, tpLine5, color.new(color.teal, 0), 1)
else
if not na(tpLine5)
line.delete(tpLine5)
tpLine5 := na
// ====== Build HUD Text ======
string txt = ""
// Per-entry rows
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
idx = i + 1
ent = array.get(entries, i)
pct = array.get(pcts, i)
pnlq = array.get(pnls, i)
roi = array.get(rois, i)
levX = array.get(levs, i)
txt += (txt=="" ? "" : " ") + "📌 Entry " + str.tostring(idx) + ": " + str.tostring(ent, format.mintick)
txt += " 📊 Live: " + (na(pct) ? "—" : str.tostring(pct, format.mintick) + "%") + " | 💵 " + (na(pnlq) ? "—" : "$" + f_usd_str(pnlq, usd_dp))
txt += " 🧮 ROI(x" + str.tostring(levX) + "): " + (na(roi) ? "—" : str.tostring(roi, format.mintick) + "%")
// Summary or test HUD
if txt != ""
if totalQty > 0
txt += " — — —"
txt += " ⚖️ Weighted Avg Entry: " + str.tostring(wAvgEntry, format.mintick)
if not na(stop)
txt += " ❌ SL: " + str.tostring(stop, format.mintick)
// Nearest target (from current price)
string tpInfo = "—"
if not na(nearestTP)
tpInfo := str.tostring(nearestTP, format.mintick) + (na(nearestDistPct) ? "" : " (Δ " + str.tostring(nearestDistPct, format.mintick) + "%)")
txt += " 🎯 Nearest: " + tpInfo
// R:R (nearest)
if not na(rr)
txt += " 📐 R:R (nearest): " + str.tostring(rr, format.mintick)
// Avg R:R across all valid TPs (by direction from weighted entry)
if not na(rr_avg)
txt += " 📐 Avg R:R (all valid TPs): " + str.tostring(rr_avg, format.mintick)
// Totals
txt += " 🧾 Total P/L: " + "$" + f_usd_str(totalPnlUSD, usd_dp)
txt += " 🧮 Weighted ROI (by Notional): " + (na(totalROIweighted) ? "—" : str.tostring(totalROIweighted, format.mintick) + "%")
else if force_show_hud
txt := "🧪 HUD is active. Fill Entry prices or tick ⚡. Enable TP/SL to see lines."
// ====== HUD Placement (near live price) ======
var label hud = na
atr_val = nz(ta.atr(atr_len), 0.0)
anchor_price = close
y_pos = na(anchor_price) ? na : anchor_price + (atr_val * hud_off_atr)
x_pos_base = bar_index
off = hud_side == "Right of price" ? hud_off_bars : -hud_off_bars
x_pos = lock_to_last_bar ? (barstate.islast ? (x_pos_base + off) : x_pos_base) : (x_pos_base + off)
// Pick label style by side:
// - Right of price → pointer on LEFT edge → style_label_left
// - Left of price → pointer on RIGHT edge → style_label_right
label_style = hud_side == "Right of price" ? label.style_label_left : label.style_label_right
if not na(y_pos) and txt != ""
if na(hud)
hud := label.new(x_pos, y_pos, txt, xloc=xloc.bar_index, style=label_style, textcolor=hud_txtc, color=hud_bg, size=to_size(hud_font))
else
label.set_x(hud, x_pos)
label.set_y(hud, y_pos)
label.set_text(hud, txt)
label.set_textcolor(hud, hud_txtc)
label.set_color(hud, hud_bg)
label.set_style(hud, label_style)
label.set_size(hud, to_size(hud_font))
else
if not na(hud)
label.delete(hud)
hud := na
P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R//@version=6
indicator("P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R", overlay=true, max_lines_count=500, max_labels_count=500)
// ====== General ======
side = input.string("Long", "Position Side", options= )
usd_dp = input.int(2, "USD decimals", minval=0, maxval=6)
// ====== HUD Settings ======
hud_font = input.string("large", "HUD font size", options= )
hud_bg = input.color(color.new(color.black, 0), "HUD background color")
hud_txtc = input.color(color.white, "HUD text color")
hud_side = input.string("Right of price", "HUD side", options= )
hud_off_bars = input.int(3, "Horizontal offset (bars)", minval=0, maxval=50)
hud_off_atr = input.float(0.2, "Vertical offset from price (ATR)", step=0.1)
atr_len = input.int(14, "ATR length for vertical offset", minval=1)
lock_to_last_bar = input.bool(true, "Lock HUD to the last bar")
// Show HUD even when there are no entries (test text)
force_show_hud = input.bool(true, "🔍 Show HUD even with no entries")
// ====== Shared SL & Targets ======
stop_inp = input.float(0.0, "Stop Loss (shared, optional)", step=0.0001)
use_tp1 = input.bool(false, "Enable Target 1")
tp1 = input.float(0.0, "Target 1 price", step=0.0001)
use_tp2 = input.bool(false, "Enable Target 2")
tp2 = input.float(0.0, "Target 2 price", step=0.0001)
use_tp3 = input.bool(false, "Enable Target 3")
tp3 = input.float(0.0, "Target 3 price", step=0.0001)
use_tp4 = input.bool(false, "Enable Target 4")
tp4 = input.float(0.0, "Target 4 price", step=0.0001)
use_tp5 = input.bool(false, "Enable Target 5")
tp5 = input.float(0.0, "Target 5 price", step=0.0001)
// ====== Four Independent Entries ======
group1 = "Entry 1"
en1 = input.bool(true, "Enable Entry 1", inline=group1)
lev1 = input.int(10, "Leverage", minval=1, maxval=200, inline=group1)
entry1 = input.float(0.0, "Entry 1 price", step=0.0001)
set_now1 = input.bool(false, "⚡ Set Entry1 = Current Price")
mode1 = input.string("USD (USDT)", "Size unit 1", options= )
sem1 = input.string("Margin (apply leverage)", "Size meaning 1", options= )
size1 = input.float(0.0, "Position size 1", step=0.0001)
baseLev1 = input.bool(false, "Apply leverage to 'Coin Quantity' (1)")
group2 = "Entry 2"
en2 = input.bool(false, "Enable Entry 2", inline=group2)
lev2 = input.int(10, "Leverage", minval=1, maxval=200, inline=group2)
entry2 = input.float(0.0, "Entry 2 price", step=0.0001)
set_now2 = input.bool(false, "⚡ Set Entry2 = Current Price")
mode2 = input.string("USD (USDT)", "Size unit 2", options= )
sem2 = input.string("Margin (apply leverage)", "Size meaning 2", options= )
size2 = input.float(0.0, "Position size 2", step=0.0001)
baseLev2 = input.bool(false, "Apply leverage to 'Coin Quantity' (2)")
group3 = "Entry 3"
en3 = input.bool(false, "Enable Entry 3", inline=group3)
lev3 = input.int(10, "Leverage", minval=1, maxval=200, inline=group3)
entry3 = input.float(0.0, "Entry 3 price", step=0.0001)
set_now3 = input.bool(false, "⚡ Set Entry3 = Current Price")
mode3 = input.string("USD (USDT)", "Size unit 3", options= )
sem3 = input.string("Margin (apply leverage)", "Size meaning 3", options= )
size3 = input.float(0.0, "Position size 3", step=0.0001)
baseLev3 = input.bool(false, "Apply leverage to 'Coin Quantity' (3)")
group4 = "Entry 4"
en4 = input.bool(false, "Enable Entry 4", inline=group4)
lev4 = input.int(10, "Leverage", minval=1, maxval=200, inline=group4)
entry4 = input.float(0.0, "Entry 4 price", step=0.0001)
set_now4 = input.bool(false, "⚡ Set Entry4 = Current Price")
mode4 = input.string("USD (USDT)", "Size unit 4", options= )
sem4 = input.string("Margin (apply leverage)", "Size meaning 4", options= )
size4 = input.float(0.0, "Position size 4", step=0.0001)
baseLev4 = input.bool(false, "Apply leverage to 'Coin Quantity' (4)")
// Quick set entries = current price
entry1 := (en1 and set_now1) ? close : entry1
entry2 := (en2 and set_now2) ? close : entry2
entry3 := (en3 and set_now3) ? close : entry3
entry4 := (en4 and set_now4) ? close : entry4
// ====== Helpers ======
to_size(s) =>
s == "tiny" ? size.tiny : s == "small" ? size.small : s == "normal" ? size.normal : s == "large" ? size.large : size.huge
f_usd_str(_val, _decimals) =>
na(_val) ? "—" : str.tostring(math.round(_val * math.pow(10, _decimals)) / math.pow(10, _decimals))
f_qty_base(mode, sem, size, entry, baseLev, lev) =>
float _qty = na
if mode == "USD (USDT)"
_qty := (size > 0 and entry > 0) ? ((sem == "Margin (apply leverage)" ? size * lev : size) / entry) : na
else
_qty := size > 0 ? (baseLev ? size * lev : size) : na
_qty
f_notional_quote(mode, sem, size, entry, lev, baseLev) =>
if mode == "USD (USDT)"
sem == "Margin (apply leverage)" ? size * lev : size
else
(baseLev ? size * lev : size) * entry
f_pnl_quote(side, entry, qty) =>
na(qty) or na(entry) ? na : (side=="Long" ? (close - entry) : (entry - close)) * qty
f_pct(side, entry) =>
na(entry) ? na : ((close - entry) / entry * 100.0) * (side=="Long" ? 1 : -1)
f_roi_pct(side, entry, lev) =>
na(entry) ? na : f_pct(side, entry) * lev
// NOTE: _lineIn must be a line, not a float
f_stickyHLine(_price, _lineIn, _color, _width) =>
var line _out = na
_out := _lineIn
if na(_out)
_out := line.new(bar_index-1, _price, bar_index+1, _price, xloc=xloc.bar_index, extend=extend.both, width=_width, style=line.style_dashed, color=_color)
else
line.set_xy1(_out, bar_index-1, _price)
line.set_xy2(_out, bar_index+1, _price)
line.set_color(_out, _color)
line.set_width(_out, _width)
_out
// ====== 4 Entries Calculations ======
var color entryCols = array.from(color.new(color.yellow, 0), color.new(color.orange, 0), color.new(color.teal, 0), color.new(color.fuchsia, 0))
bool ens = array.from(en1, en2, en3, en4)
float entries = array.from(entry1, entry2, entry3, entry4)
int levs = array.from(lev1, lev2, lev3, lev4)
string modes = array.from(mode1, mode2, mode3, mode4)
string sems = array.from(sem1, sem2, sem3, sem4)
float sizes = array.from(size1, size2, size3, size4)
bool baseLevs = array.from(baseLev1, baseLev2, baseLev3, baseLev4)
float qtys = array.new_float(4, na)
float pnls = array.new_float(4, na)
float pcts = array.new_float(4, na)
float rois = array.new_float(4, na)
float notionals = array.new_float(4, na)
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
ent = array.get(entries, i)
levX = array.get(levs, i)
modeX= array.get(modes, i)
semX = array.get(sems, i)
sizeX= array.get(sizes, i)
bLev = array.get(baseLevs, i)
qty = f_qty_base(modeX, semX, sizeX, ent, bLev, levX)
array.set(qtys, i, qty)
pnlq = f_pnl_quote(side, ent, qty)
array.set(pnls, i, pnlq)
pct = f_pct(side, ent)
array.set(pcts, i, pct)
roi = f_roi_pct(side, ent, levX)
array.set(rois, i, roi)
notq = f_notional_quote(modeX, semX, sizeX, ent, levX, bLev)
array.set(notionals, i, notq)
// ====== Totals & Weighted Avg Entry ======
float totalPnlUSD = 0.0
float totalNotional = 0.0
float totalQty = 0.0
float wAvgEntry = na
for i = 0 to 3
if not na(array.get(pnls, i))
totalPnlUSD += array.get(pnls, i)
if not na(array.get(notionals, i))
totalNotional += array.get(notionals, i)
if not na(array.get(qtys, i)) and array.get(entries, i) > 0
totalQty += array.get(qtys, i)
if totalQty > 0
num = 0.0
for i = 0 to 3
qi = array.get(qtys, i)
ei = array.get(entries, i)
if not na(qi) and ei > 0
num += qi * ei
wAvgEntry := num / totalQty
totalROIweighted = totalNotional > 0 ? (totalPnlUSD / totalNotional) * 100.0 : na
// ====== Nearest TP & R:R ======
float nearestTP = na
float nearestDistPrice = na
float nearestDistPct = na
float risk_pct = na
float reward_pct = na
float rr = na
var float tps = array.new_float()
array.clear(tps)
if use_tp1 and tp1 > 0
array.push(tps, tp1)
if use_tp2 and tp2 > 0
array.push(tps, tp2)
if use_tp3 and tp3 > 0
array.push(tps, tp3)
if use_tp4 and tp4 > 0
array.push(tps, tp4)
if use_tp5 and tp5 > 0
array.push(tps, tp5)
// nearest target in the trade direction (from current price)
if array.size(tps) > 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
cond = side=="Long" ? (_tp > close) : (_tp < close)
if cond
distP = math.abs(_tp - close)
if na(nearestDistPrice) or distP < nearestDistPrice
nearestDistPrice := distP
nearestTP := _tp
if not na(nearestDistPrice) and close != 0
nearestDistPct := (nearestDistPrice / close) * 100.0
float stop = stop_inp > 0 ? stop_inp : na
if not na(wAvgEntry) and not na(stop)
rawRisk = (side=="Long" ? (stop - wAvgEntry) : (wAvgEntry - stop)) / wAvgEntry * 100.0
risk_pct := math.abs(rawRisk)
if not na(wAvgEntry) and not na(nearestTP)
reward_pct := math.abs((side=="Long" ? (nearestTP - wAvgEntry) : (wAvgEntry - nearestTP)) / wAvgEntry * 100.0)
rr := (not na(risk_pct) and not na(reward_pct) and risk_pct != 0) ? reward_pct / risk_pct : na
// ====== Average R:R across all valid targets ======
float rr_avg = na
if not na(wAvgEntry) and not na(stop) and array.size(tps) > 0 and not na(risk_pct) and risk_pct != 0
float sum_rr = 0.0
int cnt_rr = 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
bool validDir = side=="Long" ? (_tp > wAvgEntry) : (_tp < wAvgEntry)
if validDir
_reward = math.abs((side=="Long" ? (_tp - wAvgEntry) : (wAvgEntry - _tp)) / wAvgEntry * 100.0)
_rr = _reward / risk_pct
sum_rr += _rr
cnt_rr += 1
rr_avg := cnt_rr > 0 ? (sum_rr / cnt_rr) : na
// ====== Entry/SL/TP Lines ======
var line entryLines = array.new_line(4, na)
for i = 0 to 3
ln = array.get(entryLines, i)
if array.get(ens, i) and array.get(entries, i) > 0
col = array.get(entryCols, i)
ent = array.get(entries, i)
ln := f_stickyHLine(ent, ln, col, 2)
array.set(entryLines, i, ln)
else
if not na(ln)
line.delete(ln)
array.set(entryLines, i, na)
var line slLine = na
if not na(stop)
slLine := f_stickyHLine(stop, slLine, color.new(color.red, 0), 1)
else
if not na(slLine)
line.delete(slLine)
slLine := na
var line tpLine1 = na
var line tpLine2 = na
var line tpLine3 = na
var line tpLine4 = na
var line tpLine5 = na
if use_tp1 and tp1 > 0
tpLine1 := f_stickyHLine(tp1, tpLine1, color.new(color.teal, 0), 1)
else
if not na(tpLine1)
line.delete(tpLine1)
tpLine1 := na
if use_tp2 and tp2 > 0
tpLine2 := f_stickyHLine(tp2, tpLine2, color.new(color.teal, 0), 1)
else
if not na(tpLine2)
line.delete(tpLine2)
tpLine2 := na
if use_tp3 and tp3 > 0
tpLine3 := f_stickyHLine(tp3, tpLine3, color.new(color.teal, 0), 1)
else
if not na(tpLine3)
line.delete(tpLine3)
tpLine3 := na
if use_tp4 and tp4 > 0
tpLine4 := f_stickyHLine(tp4, tpLine4, color.new(color.teal, 0), 1)
else
if not na(tpLine4)
line.delete(tpLine4)
tpLine4 := na
if use_tp5 and tp5 > 0
tpLine5 := f_stickyHLine(tp5, tpLine5, color.new(color.teal, 0), 1)
else
if not na(tpLine5)
line.delete(tpLine5)
tpLine5 := na
// ====== Build HUD Text ======
string txt = ""
// Per-entry rows
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
idx = i + 1
ent = array.get(entries, i)
pct = array.get(pcts, i)
pnlq = array.get(pnls, i)
roi = array.get(rois, i)
levX = array.get(levs, i)
txt += (txt=="" ? "" : " ") + "📌 Entry " + str.tostring(idx) + ": " + str.tostring(ent, format.mintick)
txt += " 📊 Live: " + (na(pct) ? "—" : str.tostring(pct, format.mintick) + "%") + " | 💵 " + (na(pnlq) ? "—" : "$" + f_usd_str(pnlq, usd_dp))
txt += " 🧮 ROI(x" + str.tostring(levX) + "): " + (na(roi) ? "—" : str.tostring(roi, format.mintick) + "%")
// Summary or test HUD
if txt != ""
if totalQty > 0
txt += " — — —"
txt += " ⚖️ Weighted Avg Entry: " + str.tostring(wAvgEntry, format.mintick)
if not na(stop)
txt += " ❌ SL: " + str.tostring(stop, format.mintick)
// Nearest target (from current price)
string tpInfo = "—"
if not na(nearestTP)
tpInfo := str.tostring(nearestTP, format.mintick) + (na(nearestDistPct) ? "" : " (Δ " + str.tostring(nearestDistPct, format.mintick) + "%)")
txt += " 🎯 Nearest: " + tpInfo
// R:R (nearest)
if not na(rr)
txt += " 📐 R:R (nearest): " + str.tostring(rr, format.mintick)
// Avg R:R across all valid TPs (by direction from weighted entry)
if not na(rr_avg)
txt += " 📐 Avg R:R (all valid TPs): " + str.tostring(rr_avg, format.mintick)
// Totals
txt += " 🧾 Total P/L: " + "$" + f_usd_str(totalPnlUSD, usd_dp)
txt += " 🧮 Weighted ROI (by Notional): " + (na(totalROIweighted) ? "—" : str.tostring(totalROIweighted, format.mintick) + "%")
else if force_show_hud
txt := "🧪 HUD is active. Fill Entry prices or tick ⚡. Enable TP/SL to see lines."
// ====== HUD Placement (near live price) ======
var label hud = na
atr_val = nz(ta.atr(atr_len), 0.0)
anchor_price = close
y_pos = na(anchor_price) ? na : anchor_price + (atr_val * hud_off_atr)
x_pos_base = bar_index
off = hud_side == "Right of price" ? hud_off_bars : -hud_off_bars
x_pos = lock_to_last_bar ? (barstate.islast ? (x_pos_base + off) : x_pos_base) : (x_pos_base + off)
// Pick label style by side:
// - Right of price → pointer on LEFT edge → style_label_left
// - Left of price → pointer on RIGHT edge → style_label_right
label_style = hud_side == "Right of price" ? label.style_label_left : label.style_label_right
if not na(y_pos) and txt != ""
if na(hud)
hud := label.new(x_pos, y_pos, txt, xloc=xloc.bar_index, style=label_style, textcolor=hud_txtc, color=hud_bg, size=to_size(hud_font))
else
label.set_x(hud, x_pos)
label.set_y(hud, y_pos)
label.set_text(hud, txt)
label.set_textcolor(hud, hud_txtc)
label.set_color(hud, hud_bg)
label.set_style(hud, label_style)
label.set_size(hud, to_size(hud_font))
else
if not na(hud)
label.delete(hud)
hud := na
پنل سود/زیان + چند تارگت R:R//@version=6
indicator("پنل سود/زیان + چند تارگت (۴ ورود مستقل) - پنل چپ نزدیک قیمت + میانگین R:R", overlay=true, max_lines_count=500, max_labels_count=500)
// ====== تنظیمات عمومی ======
side = input.string("لانگ", "نوع پوزیشن", options= )
usd_dp = input.int(2, "تعداد اعشار نمایش دلار", minval=0, maxval=6)
// ====== تنظیمات پنل ======
hud_font = input.string("large", "اندازۀ فونت پنل", options= )
hud_bg = input.color(color.new(color.black, 0), "رنگ پسزمینه پنل")
hud_txtc = input.color(color.white, "رنگ متن پنل")
// محل پنل: کمی «چپِ» آخرین کندل + کمی فاصله عمودی از قیمت
hud_off_bars = input.int(3, "فاصلۀ افقی از قیمت به سمت چپ (تعداد کندل، فقط روی آخرین کندل)", minval=0, maxval=50)
hud_off_atr = input.float(0.2, "فاصلۀ عمودی از قیمت (ATR)", step=0.1)
atr_len = input.int(14, "طول ATR برای فاصله عمودی", minval=1)
// نمایش اجباری پنل حتی بدون ورود
force_show_hud = input.bool(true, "🔍 نمایش اجباری پنل حتی بدون ورود")
// ====== حد ضرر و تارگتهای مشترک ======
stop_inp = input.float(0.0, "حد ضرر (مشترک، اختیاری)", step=0.0001)
use_tp1 = input.bool(false, "فعالسازی تارگت ۱")
tp1 = input.float(0.0, "قیمت تارگت ۱", step=0.0001)
use_tp2 = input.bool(false, "فعالسازی تارگت ۲")
tp2 = input.float(0.0, "قیمت تارگت ۲", step=0.0001)
use_tp3 = input.bool(false, "فعالسازی تارگت ۳")
tp3 = input.float(0.0, "قیمت تارگت ۳", step=0.0001)
use_tp4 = input.bool(false, "فعالسازی تارگت ۴")
tp4 = input.float(0.0, "قیمت تارگت ۴", step=0.0001)
use_tp5 = input.bool(false, "فعالسازی تارگت ۵")
tp5 = input.float(0.0, "قیمت تارگت ۵", step=0.0001)
// ====== ورودیهای ۴ ورود مستقل ======
group1 = "ورود ۱"
en1 = input.bool(true, "فعالسازی ورود ۱", inline=group1)
lev1 = input.int(10, "لوریج", minval=1, maxval=200, inline=group1)
entry1 = input.float(0.0, "قیمت ورود ۱", step=0.0001)
set_now1 = input.bool(false, "⚡ ثبت ورود۱ = قیمت فعلی")
mode1 = input.string("دلاری (USDT)", "واحد اندازه ۱", options= )
sem1 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۱", options= )
size1 = input.float(0.0, "اندازه پوزیشن ۱", step=0.0001)
baseLev1 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۱)")
group2 = "ورود ۲"
en2 = input.bool(false, "فعالسازی ورود ۲", inline=group2)
lev2 = input.int(10, "لوریج", minval=1, maxval=200, inline=group2)
entry2 = input.float(0.0, "قیمت ورود ۲", step=0.0001)
set_now2 = input.bool(false, "⚡ ثبت ورود۲ = قیمت فعلی")
mode2 = input.string("دلاری (USDT)", "واحد اندازه ۲", options= )
sem2 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۲", options= )
size2 = input.float(0.0, "اندازه پوزیشن ۲", step=0.0001)
baseLev2 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۲)")
group3 = "ورود ۳"
en3 = input.bool(false, "فعالسازی ورود ۳", inline=group3)
lev3 = input.int(10, "لوریج", minval=1, maxval=200, inline=group3)
entry3 = input.float(0.0, "قیمت ورود ۳", step=0.0001)
set_now3 = input.bool(false, "⚡ ثبت ورود۳ = قیمت فعلی")
mode3 = input.string("دلاری (USDT)", "واحد اندازه ۳", options= )
sem3 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۳", options= )
size3 = input.float(0.0, "اندازه پوزیشن ۳", step=0.0001)
baseLev3 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۳)")
group4 = "ورود ۴"
en4 = input.bool(false, "فعالسازی ورود ۴", inline=group4)
lev4 = input.int(10, "لوریج", minval=1, maxval=200, inline=group4)
entry4 = input.float(0.0, "قیمت ورود ۴", step=0.0001)
set_now4 = input.bool(false, "⚡ ثبت ورود۴ = قیمت فعلی")
mode4 = input.string("دلاری (USDT)", "واحد اندازه ۴", options= )
sem4 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۴", options= )
size4 = input.float(0.0, "اندازه پوزیشن ۴", step=0.0001)
baseLev4 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۴)")
// ثبت سریع ورود = قیمت فعلی
entry1 := (en1 and set_now1) ? close : entry1
entry2 := (en2 and set_now2) ? close : entry2
entry3 := (en3 and set_now3) ? close : entry3
entry4 := (en4 and set_now4) ? close : entry4
// ====== کمکتابعها ======
to_size(s) =>
s == "tiny" ? size.tiny : s == "small" ? size.small : s == "normal" ? size.normal : s == "large" ? size.large : size.huge
f_usd_str(_val, _decimals) =>
na(_val) ? "—" : str.tostring(math.round(_val * math.pow(10, _decimals)) / math.pow(10, _decimals))
f_qty_base(mode, sem, size, entry, baseLev, lev) =>
float _qty = na
if mode == "دلاری (USDT)"
_qty := (size > 0 and entry > 0) ? ((sem == "مارجین (اعمال لوریج)" ? size * lev : size) / entry) : na
else
_qty := size > 0 ? (baseLev ? size * lev : size) : na
_qty
f_notional_quote(mode, sem, size, entry, lev, baseLev) =>
if mode == "دلاری (USDT)"
sem == "مارجین (اعمال لوریج)" ? size * lev : size
else
(baseLev ? size * lev : size) * entry
f_pnl_quote(side, entry, qty) =>
na(qty) or na(entry) ? na : (side=="لانگ" ? (close - entry) : (entry - close)) * qty
f_pct(side, entry) =>
na(entry) ? na : ((close - entry) / entry * 100.0) * (side=="لانگ" ? 1 : -1)
f_roi_pct(side, entry, lev) =>
na(entry) ? na : f_pct(side, entry) * lev
f_stickyHLine(_price, _lineIn, _color, _width) =>
var line _out = na
_out := _lineIn
if na(_out)
_out := line.new(bar_index-1, _price, bar_index+1, _price, xloc=xloc.bar_index, extend=extend.both, width=_width, style=line.style_dashed, color=_color)
else
line.set_xy1(_out, bar_index-1, _price)
line.set_xy2(_out, bar_index+1, _price)
line.set_color(_out, _color)
line.set_width(_out, _width)
_out
// ====== محاسبات ۴ ورود ======
var color entryCols = array.from(color.new(color.yellow, 0), color.new(color.orange, 0), color.new(color.teal, 0), color.new(color.fuchsia, 0))
bool ens = array.from(en1, en2, en3, en4)
float entries = array.from(entry1, entry2, entry3, entry4)
int levs = array.from(lev1, lev2, lev3, lev4)
string modes = array.from(mode1, mode2, mode3, mode4)
string sems = array.from(sem1, sem2, sem3, sem4)
float sizes = array.from(size1, size2, size3, size4)
bool baseLevs = array.from(baseLev1, baseLev2, baseLev3, baseLev4)
float qtys = array.new_float(4, na)
float pnls = array.new_float(4, na)
float pcts = array.new_float(4, na)
float rois = array.new_float(4, na)
float notionals = array.new_float(4, na)
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
ent = array.get(entries, i)
levX = array.get(levs, i)
modeX= array.get(modes, i)
semX = array.get(sems, i)
sizeX= array.get(sizes, i)
bLev = array.get(baseLevs, i)
qty = f_qty_base(modeX, semX, sizeX, ent, bLev, levX)
array.set(qtys, i, qty)
pnlq = f_pnl_quote(side, ent, qty)
array.set(pnls, i, pnlq)
pct = f_pct(side, ent)
array.set(pcts, i, pct)
roi = f_roi_pct(side, ent, levX)
array.set(rois, i, roi)
notq = f_notional_quote(modeX, semX, sizeX, ent, levX, bLev)
array.set(notionals, i, notq)
// ====== مجموع و میانگین ورود وزنی ======
float totalPnlUSD = 0.0
float totalNotional = 0.0
float totalQty = 0.0
float wAvgEntry = na
for i = 0 to 3
if not na(array.get(pnls, i))
totalPnlUSD += array.get(pnls, i)
if not na(array.get(notionals, i))
totalNotional += array.get(notionals, i)
if not na(array.get(qtys, i)) and array.get(entries, i) > 0
totalQty += array.get(qtys, i)
if totalQty > 0
num = 0.0
for i = 0 to 3
qi = array.get(qtys, i)
ei = array.get(entries, i)
if not na(qi) and ei > 0
num += qi * ei
wAvgEntry := num / totalQty
totalROIweighted = totalNotional > 0 ? (totalPnlUSD / totalNotional) * 100.0 : na
// ====== نزدیکترین تارگت و R:R ======
float nearestTP = na
float nearestDistPrice = na
float nearestDistPct = na
float risk_pct = na
float reward_pct = na
float rr = na
var float tps = array.new_float()
array.clear(tps)
if use_tp1 and tp1 > 0
array.push(tps, tp1)
if use_tp2 and tp2 > 0
array.push(tps, tp2)
if use_tp3 and tp3 > 0
array.push(tps, tp3)
if use_tp4 and tp4 > 0
array.push(tps, tp4)
if use_tp5 and tp5 > 0
array.push(tps, tp5)
// نزدیکترین تارگت همسو با جهت
if array.size(tps) > 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
cond = side=="لانگ" ? (_tp > close) : (_tp < close)
if cond
distP = math.abs(_tp - close)
if na(nearestDistPrice) or distP < nearestDistPrice
nearestDistPrice := distP
nearestTP := _tp
if not na(nearestDistPrice) and close != 0
nearestDistPct := (nearestDistPrice / close) * 100.0
float stop = stop_inp > 0 ? stop_inp : na
if not na(wAvgEntry) and not na(stop)
rawRisk = (side=="لانگ" ? (stop - wAvgEntry) : (wAvgEntry - stop)) / wAvgEntry * 100.0
risk_pct := math.abs(rawRisk)
if not na(wAvgEntry) and not na(nearestTP)
reward_pct := math.abs((side=="لانگ" ? (nearestTP - wAvgEntry) : (wAvgEntry - nearestTP)) / wAvgEntry * 100.0)
rr := (not na(risk_pct) and not na(reward_pct) and risk_pct != 0) ? reward_pct / risk_pct : na
// ====== «میانگین R:R» روی همه تارگتهای معتبر ======
float rr_avg = na
if not na(wAvgEntry) and not na(stop) and array.size(tps) > 0 and not na(risk_pct) and risk_pct != 0
float sum_rr = 0.0
int cnt_rr = 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
bool validDir = side=="لانگ" ? (_tp > wAvgEntry) : (_tp < wAvgEntry)
if validDir
_reward = math.abs((side=="لانگ" ? (_tp - wAvgEntry) : (wAvgEntry - _tp)) / wAvgEntry * 100.0)
_rr = _reward / risk_pct
sum_rr += _rr
cnt_rr += 1
rr_avg := cnt_rr > 0 ? (sum_rr / cnt_rr) : na
// ====== خطوط ورود/SL/TP ======
var line entryLines = array.new_line(4, na)
for i = 0 to 3
ln = array.get(entryLines, i)
if array.get(ens, i) and array.get(entries, i) > 0
col = array.get(entryCols, i)
ent = array.get(entries, i)
ln := f_stickyHLine(ent, ln, col, 2)
array.set(entryLines, i, ln)
else
if not na(ln)
line.delete(ln)
array.set(entryLines, i, na)
var line slLine = na
if not na(stop)
slLine := f_stickyHLine(stop, slLine, color.new(color.red, 0), 1)
else
if not na(slLine)
line.delete(slLine)
slLine := na
var line tpLine1 = na
var line tpLine2 = na
var line tpLine3 = na
var line tpLine4 = na
var line tpLine5 = na
if use_tp1 and tp1 > 0
tpLine1 := f_stickyHLine(tp1, tpLine1, color.new(color.teal, 0), 1)
else
if not na(tpLine1)
line.delete(tpLine1)
tpLine1 := na
if use_tp2 and tp2 > 0
tpLine2 := f_stickyHLine(tp2, tpLine2, color.new(color.teal, 0), 1)
else
if not na(tpLine2)
line.delete(tpLine2)
tpLine2 := na
if use_tp3 and tp3 > 0
tpLine3 := f_stickyHLine(tp3, tpLine3, color.new(color.teal, 0), 1)
else
if not na(tpLine3)
line.delete(tpLine3)
tpLine3 := na
if use_tp4 and tp4 > 0
tpLine4 := f_stickyHLine(tp4, tpLine4, color.new(color.teal, 0), 1)
else
if not na(tpLine4)
line.delete(tpLine4)
tpLine4 := na
if use_tp5 and tp5 > 0
tpLine5 := f_stickyHLine(tp5, tpLine5, color.new(color.teal, 0), 1)
else
if not na(tpLine5)
line.delete(tpLine5)
tpLine5 := na
// ====== ساخت متن پنل ======
string txt = ""
// ردیفهای هر ورود
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
idx = i + 1
ent = array.get(entries, i)
pct = array.get(pcts, i)
pnlq = array.get(pnls, i)
roi = array.get(rois, i)
levX = array.get(levs, i)
txt += (txt=="" ? "" : " ") + "📌 ورود " + str.tostring(idx) + ": " + str.tostring(ent, format.mintick)
txt += " 📊 لحظهای: " + (na(pct) ? "—" : str.tostring(pct, format.mintick) + "%") + " | 💵 " + (na(pnlq) ? "—" : "$" + f_usd_str(pnlq, usd_dp))
txt += " 🧮 ROI(x" + str.tostring(levX) + "): " + (na(roi) ? "—" : str.tostring(roi, format.mintick) + "%")
// خلاصه پایانی یا پنل تست
if txt != ""
if totalQty > 0
txt += " — — —"
txt += " ⚖️ میانگین ورود وزنی: " + str.tostring(wAvgEntry, format.mintick)
if not na(stop)
txt += " ❌ SL: " + str.tostring(stop, format.mintick)
// نزدیکترین تارگت
string tpInfo = "—"
if not na(nearestTP)
tpInfo := str.tostring(nearestTP, format.mintick) + (na(nearestDistPct) ? "" : " (Δ " + str.tostring(nearestDistPct, format.mintick) + "%)")
txt += " 🎯 نزدیکترین: " + tpInfo
// R:R نزدیکترین
if not na(rr)
txt += " 📐 R:R نزدیکترین: " + str.tostring(rr, format.mintick)
// میانگین R:R روی همه تارگتهای معتبر
if not na(rr_avg)
txt += " 📐 میانگین R:R (همۀ تارگتهای معتبر): " + str.tostring(rr_avg, format.mintick)
// مجموعها
txt += " 🧾 مجموع سود/زیان: " + "$" + f_usd_str(totalPnlUSD, usd_dp)
txt += " 🧮 ROĪ وزنی (بر اساس ناتیونال): " + (na(totalROIweighted) ? "—" : str.tostring(totalROIweighted, format.mintick) + "%")
else if force_show_hud
txt := "🧪 پنل فعال است. از فیلدهای «قیمت ورود» استفاده کن یا تیکهای ⚡ را بزن. برای دیدن TP/SL خطوط، تیکهای مربوطه را فعال کن."
// ====== HUD (پنل سمت چپ، نوک اشاره نزدیک قیمت لحظهای) ======
// ====== HUD (پنل سمت راست، نوک اشاره نزدیک قیمت لحظهای) ======
var label hud = na
atr_val = ta.atr(atr_len)
// لنگر عمودی روی قیمت لحظهای با کمی فاصله عمودی
anchor_price = close
y_pos = na(anchor_price) ? na : anchor_price + (atr_val * hud_off_atr)
// فقط روی آخرین کندل، چند بار به «راست» میبریم تا نوک پنل نزدیک کندل باشد
x_pos_base = bar_index
x_pos = barstate.islast ? (x_pos_base + hud_off_bars) : x_pos_base
if not na(y_pos) and txt != ""
if na(hud)
// ⚠️ style_label_left = نوک پنل سمت چپ است ⇒ متن به راست باز میشود ⇒ کل پنل در «راستِ» قیمت قرار میگیرد
hud := label.new(x_pos, y_pos, txt,xloc=xloc.bar_index,style=label.style_label_left, textcolor=hud_txtc, color=hud_bg, size=to_size(hud_font))
else
label.set_x(hud, x_pos)
label.set_y(hud, y_pos)
label.set_text(hud, txt)
label.set_textcolor(hud, hud_txtc)
label.set_color(hud, hud_bg)
label.set_style(hud, label.style_label_left)
label.set_size(hud, to_size(hud_font))
else
if not na(hud)
label.delete(hud)
hud := na
Supertrend Trend Change Signals + Covered Points Only (v5)[NR]Supertrend with Buy/Sell Signals + Covered Points (v5)
Description
This indicator is a custom version of the Supertrend that provides:
Buy/Sell signals whenever the trend flips (Up → Buy, Down → Sell).
Covered points label at the end of each trend, showing the total price movement captured from entry to exit.
Optional colored candles based on trend direction.
Visual markers (triangle up/down) for quick identification of flips.
Built-in alert conditions for Buy and Sell flips.
Use case:
Designed for traders who want not only entry/exit alerts but also a quick view of how many points the previous run covered. Especially useful for index futures (e.g., NIFTY, BankNIFTY) or instruments where point movement matters.
⚠ Note: This is a study/indicator, not a strategy. It does not auto-trade and should be combined with your own analysis and risk management.
QuickScalp ProQuickScalp Pro – Scalping with Precision
QuickScalp Pro is designed for intraday traders who want fast, accurate scalping signals with very small stop-loss levels.
It combines Supertrend, VWMA zones, Kalman smoothing, and reversal detection to filter out noise and highlight only high-probability entries.
✅ Optimized for Nifty & BankNifty options (5-min chart recommended)
✅ Small SL + Quick Targets (50–100 points possible)
✅ No repainting when “Confirm on Close” is enabled
✅ Clean chart with minimal clutter – only clear Buy/Sell/TP/Reversal labels
✅ Alerts supported for Buy, Sell, Reversals, and Take Profit hits
This tool is best suited for scalpers and option traders who want quick entries, fast exits, and controlled risk.
Exhaustion Reversal# 📘 Exhaustion Reversal – Quick Start Guide
This tool highlights **reversal zones** where price is stretched too far and likely to snap back.
---
## 1. What to Look For
* **Green Box + Neon BUY Arrow** → Possible Buy Setup
* **Red Box + Neon SELL Arrow** → Possible Sell Setup
* Background color:
* Light **green tint** = Bias is LONG (favor buy setups)
* Light **red tint** = Bias is SHORT (favor sell setups)
---
## 2. How to Take a Trade
**BUY Setup**
1. Wait until you see a **green shaded box** and a **neon BUY arrow**.
2. Confirm the candle closed **green** (bullish).
3. **Entry (EP):** Enter at the closing price of the signal candle (labeled “BUY ENTRY”).
4. **Stop Loss (SL):** Set just under the low of the signal candle (labeled “SL”).
5. **Take Profit (TP):**
* Safer target → the blue **Center Line**.
* Aggressive target → **Band 1**.
**SELL Setup**
1. Wait until you see a **red shaded box** and a **neon SELL arrow**.
2. Confirm the candle closed **red** (bearish).
3. **Entry (EP):** Enter at the closing price of the signal candle (labeled “SELL ENTRY”).
4. **Stop Loss (SL):** Set just above the high of the signal candle (labeled “SL”).
5. **Take Profit (TP):**
* Safer target → the blue **Center Line**.
* Aggressive target → **Band 1**.
---
## 3. Quick Rules to Remember
* ✅ Trade WITH the background bias.
* Green background → focus on BUY setups.
* Red background → focus on SELL setups.
* ❌ Skip weak candles. Look for **strong bodies** (bigger candles).
* ❌ Don’t take every arrow. Wait until price stretched to the **outer Band 2**.
* ✅ Manage risk. Never risk more than **1–2% of your account** on a single trade.
---
## 4. Beginner Flow (step-by-step)
1. Watch for **background tint** (green = buy, red = sell).
2. Wait for price to **touch/pierce Band 2**.
3. Watch for a **reversal candle** (green after red, or red after green).
4. Enter at the “ENTRY” label, place SL and TP at the lines.
5. Let the trade play out – don’t move stops unless you scale out.
---
## 5. Example Trade
* NAS100 on 5m chart:
* Background turns red → bias is SHORT.
* Price spikes above **Upper Band 2**.
* Red reversal candle closes.
* Arrow + label appear → Enter SELL.
* SL at candle high, TP at Center Line.
---
💡 **Pro Tip for New Traders:**
Start by practicing this system in a demo account. Focus on spotting the *cleanest* setups where price clearly stretches to Band 2 and gives a strong reversal candle.
BOLL Omakase 2.0testing own {
"symbol": "{{ticker}}",
"price": {{close}},
"time": "{{time}}"
}{
"symbol": "{{ticker}}",
"price": {{close}},
"time": "{{time}}"
}{
"symbol": "{{ticker}}",
"price": {{close}},
"time": "{{time}}"
}{
"symbol": "{{ticker}}",
"price": {{close}},
"time": "{{time}}"
}
🚀⚠️ Aggressive + Confirmed Long Strategy (v2)//@version=5
strategy("🚀⚠️ Aggressive + Confirmed Long Strategy (v2)",
overlay=true,
pyramiding=0,
initial_capital=10000,
default_qty_type=strategy.percent_of_equity,
default_qty_value=10, // % of equity per trade
commission_type=strategy.commission.percent,
commission_value=0.05)
// ========= Inputs =========
lenRSI = input.int(14, "RSI Length")
lenSMA1 = input.int(20, "SMA 20")
lenSMA2 = input.int(50, "SMA 50")
lenBB = input.int(20, "Bollinger Length")
multBB = input.float(2, "Bollinger Multiplier", step=0.1)
volLen = input.int(20, "Volume MA Length")
smaBuffP = input.float(1.0, "Margin above SMA50 (%)", step=0.1)
confirmOnClose = input.bool(true, "Confirm signals only after candle close")
useEarly = input.bool(true, "Allow Early entries")
// Risk
atrLen = input.int(14, "ATR Length", minval=1)
slATR = input.float(2.0, "Stop = ATR *", step=0.1)
tpRR = input.float(2.0, "Take-Profit RR (TP = SL * RR)", step=0.1)
useTrail = input.bool(false, "Use Trailing Stop instead of fixed SL/TP")
trailATR = input.float(2.5, "Trailing Stop = ATR *", step=0.1)
moveToBE = input.bool(true, "Move SL to breakeven at 1R TP")
// ========= Indicators =========
// MAs
sma20 = ta.sma(close, lenSMA1)
sma50 = ta.sma(close, lenSMA2)
// RSI
rsi = ta.rsi(close, lenRSI)
rsiEarly = rsi > 45 and rsi < 55
rsiStrong = rsi > 55
// MACD
= ta.macd(close, 12, 26, 9)
macdCross = ta.crossover(macdLine, signalLine)
macdEarly = macdCross and macdLine < 0
macdStrong = macdCross and macdLine > 0
// Bollinger
= ta.bb(close, lenBB, multBB)
bollBreakout = close > bbUpper
// Candle & Volume
bullishCandle = close > open
volCondition = volume > ta.sma(volume, volLen)
// Price vs MAs
smaCondition = close > sma20 and close > sma50 and close > sma50 * (1 + smaBuffP/100.0)
// Confirm-on-close helper
useSignal(cond) =>
confirmOnClose ? (cond and barstate.isconfirmed) : cond
// Entries
confirmedEntry = useSignal(rsiStrong and macdStrong and bollBreakout and bullishCandle and volCondition and smaCondition)
earlyEntry = useSignal(rsiEarly and macdEarly and close > sma20 and bullishCandle) and not confirmedEntry
longSignal = confirmedEntry or (useEarly and earlyEntry)
// ========= Risk Mgmt =========
atr = ta.atr(atrLen)
slPrice = close - atr * slATR
tpPrice = close + (close - slPrice) * tpRR
trailPts = atr * trailATR
// ========= Orders =========
if strategy.position_size == 0 and longSignal
strategy.entry("Long", strategy.long)
if strategy.position_size > 0
if useTrail
// Trailing Stop
strategy.exit("Exit", "Long", trail_points=trailPts, trail_offset=trailPts)
else
// Normal SL/TP
strategy.exit("Exit", "Long", stop=slPrice, limit=tpPrice)
// Move SL to breakeven when TP1 hit
if moveToBE and high >= tpPrice
strategy.exit("BE", "Long", stop=strategy.position_avg_price)
// ========= Plots =========
plot(sma20, title="SMA 20", color=color.orange, linewidth=2)
plot(sma50, title="SMA 50", color=color.new(color.blue, 0), linewidth=2)
plot(bbUpper, title="BB Upper", color=color.new(color.fuchsia, 0))
plot(bbBasis, title="BB Basis", color=color.new(color.gray, 50))
plot(bbLower, title="BB Lower", color=color.new(color.fuchsia, 0))
plotshape(confirmedEntry, title="🚀 Confirmed", location=location.belowbar,
color=color.green, style=shape.labelup, text="🚀", size=size.tiny)
plotshape(earlyEntry, title="⚠️ Early", location=location.belowbar,
color=color.orange, style=shape.labelup, text="⚠️", size=size.tiny)
// ========= Alerts =========
alertcondition(confirmedEntry, title="🚀 Confirmed Entry", message="🚀 {{ticker}} confirmed entry on {{interval}}")
alertcondition(earlyEntry, title="⚠️ Early Entry", message="⚠️ {{ticker}} early entry on {{interval}}")
ORB - 15 Minute Opening RangeThe Opening Range Breakout (ORB) strategy focuses on price movements that occur shortly after the market opens. Traders define a price range—usually based on the first 5, 15, or 30 minutes—and then look for a breakout above or below that range.
Nor Smart Pivot V5.0 by SJKimNor Smart Pivot V5.0 by SJKim.
Nor Smart Pivot V5.0 by SJKim.
Nor Smart Pivot V5.0 by SJKim.
Vietnamese: Swing Low Detection with SMA Bands & BackgroundThis script detects **swing lows** using a dynamic SMA-based logic and visually highlights them on the chart.
Features
Customizable Moving Averages: Supports multiple MA types (SMA, EMA, WMA, RMA, HMA, DEMA, TEMA, VWMA).
Swing Low Visualization: Identifies swing lows when price closes below the SMA of lows and exits once price trades above the SMA of highs.
Smart Rectangles: Marks detected swing lows with labeled boxes for clear visual reference.
Background Highlights**: Dynamically shades the chart background when price breaks below recent swing lows, helping traders spot potential breakdown zones.
Configurable Parameters: Period length, rectangle length, and MA source can all be tuned.
Use Cases
Spot breakdown/bearish continuation signals when price closes under recent lows.
Combine with higher timeframe trend analysis for confluence.
Notes
* This tool is designed for **visual analysis** and is not a standalone buy/sell signal.
* Works best when combined with broader trend analysis, support/resistance levels, and volume.
Estrategia REGLA DE OROit is an indicator that allows you to design the nearest support and resistance + buy and sell alert.
Crypto Breakout Buy/Sell Sequence
⚙️ Components & Sequence Multiple Timeframe (What It Does)
1. Bollinger Bands – Form the foundation by measuring volatility and creating the dynamic range where squeezes and breakouts occur.
2. Squeeze Dots – Show when price compresses inside the bands, signaling reduced volatility before expansion.
3. Breakout Event (Brk Dot) – Fires when price expands beyond the squeeze zone, confirming volatility expansion. (This paints Intra, before candle close)
4. Buy Signal – Confirms entry after a breakout is validated. (This paints at candle close)
5. Pump Signal – Flags sudden surges that extend sharply from the bands, often linked to strong inflows.
6. Momentum Stream – Tracks the strength of movement following the breakout, from continuation (🟢) to slowing (🟡) to exhaustion (🔴). (Resets at Pump Signal)
7. Overbought Indicator – Confirms when momentum has reached overheated conditions, often aligning with band extremes.
8. Sell Signal – Prints when exhaustion/reversal conditions are met, closing the trade cycle.
The Crypto Breakout Buy/Sell Sequence is a no-repaint event indicator that maps a full trade cycle using Bollinger-band-based volatility states: Bollinger Bands → Squeeze → Breakout → Buy → Pump → Momentum → Top Test → Overbought → Sell. Each stage is rule-based and designed to be read on standard candlesticks.
How It Works (System Logic)
Volatility framework: Bollinger Bands define dynamic range and compression/expansion.
Initiation: Squeeze → Breakout confirms expansion; Buy validates participation after expansion begins.
Management: Pump highlights unusual acceleration; Momentum stream tracks continuation → slowing → exhaustion.
Exhaustion/Exit: Top Testing + Overbought build the exhaustion case; Sell marks the sequence end.
How To Use (Quick Guide)
Wait for Squeeze → Breakout → Buy to establish a structured start.
Manage with Momentum:
🟢 continuation, 🟡 slowing, 🔴 exhaustion pressure.
Monitor extremes: Top Testing and/or Overbought = tighten risk.
Exit on Sell or on your risk rules when exhaustion builds.
Limitations & Good Practice
Signals reflect price/volatility behavior, not certainty.
Strong trends can remain extended; Overbought/Top Test ≠ instant reversal.
Always confirm with your own risk rules, position sizing, and market context.
Initial public release: integrated Squeeze/Breakout/Buy → Momentum → Exhaustion → Sell cycle; improved label clarity; cleaned defaults.
Disclaimer
For educational purposes only. Not financial advice. Past performance does not guarantee future results. Test before live use.
Thank You
Dynamic Linear Regression Channels, w/ input editsinput edits for line width, color, and for upper/lower deviation
VXN Darvas BoxThis indicator is based on other open source scripts. It's designed for Nasdaq futures (NQ or MNQ). It is based on the Darvas Box concept, plotting boxes to identify price breakouts, with buy/sell signals filtered by the VXN index direction to align with bullish or bearish trends.
FXC Order Block FinderThis indicator highlights potential VWAP reversion zones using delta volume (buy vs sell imbalance) combined with order flow confirmation. When price extends away from VWAP with strong delta imbalance, zones are plotted where reversals or mean reversion moves are more likely to occur. Helps traders visualize exhaustion points, liquidity grabs, and reversion setups around VWAP. Works best on intraday timeframes with futures, indices, and liquid markets.
Dynamic Trend Channel# Dynamic Trend Channel (DTC) Indicator
A sophisticated trend-following indicator that creates dynamic channels based on price action and volatility. This indicator helps traders identify trend direction and potential reversal points through adaptive channel boundaries.
## Key Features
1. **Smart Channel Calculation**
- Dynamic channel boundaries based on price and ATR (Average True Range)
- Automatically adjusts to market volatility
- Channel multiplier customization for different trading styles
2. **Trend Direction Analysis**
- Clear trend identification through channel position
- Color-coded channels (green for uptrend, red for downtrend)
- Built-in SMA21 reference line for trend confirmation
3. **Visual Clarity**
- Semi-transparent channel fill for easy price action visibility
- Clean channel boundary lines
- Optional SMA21 display for additional trend context
4. **Breakout Detection**
- Automatic breakout alerts when price crosses channel boundaries
- Custom alert messages with price and time information
- Helps catch potential trend reversals early
## Trading Applications
1. **Trend Trading**
- Use channel direction for trend confirmation
- Trade with the trend within channel boundaries
- Monitor channel breakouts for trend continuation or reversal
2. **Volatility Analysis**
- Channel width indicates market volatility
- Adapt position sizing based on channel width
- Use ATR-based boundaries for volatility-adjusted stops
3. **Risk Management**
- Channel boundaries serve as dynamic support/resistance
- Use opposite channel boundary as stop-loss reference
- Scale positions based on channel width
## Setup Guide
1. **Channel Configuration**
- Adjust ATR period (default: 12) based on your timeframe
- Fine-tune channel multiplier for market volatility
- Enable/disable SMA21 based on your trading style
2. **Alert Setup**
- Configure breakout alerts for real-time notifications
- Customize alert messages for your trading journal
- Set alerts for specific trading sessions
## Best Practices
1. Use multiple timeframes for confirmation
2. Combine with volume analysis for breakout validation
3. Consider market conditions when interpreting channel signals
4. Wait for candle closes beyond channel boundaries for confirmation
## Notes
1. Works best in trending markets
2. Channel width adapts to market conditions
3. Consider using wider channels in higher volatility markets
4. Combine with other indicators for better trade decisions
This indicator is particularly useful for trend traders and swing traders who want to capture major market moves while managing risk through dynamic support and resistance levels. Its adaptive nature makes it suitable for various market conditions and trading styles.
ADR H/L + Bull/Bear TargetsThis indicator calculates the Average Daily/Weekly Range over any given period and plots the Bull and Bear targets for that Session Daily/Weekly or both. Classic targets are calculated at ADR/AWR +/- .50 .75 1.00 1.25. Green is for the + and RED is for the - but colors can been changed to suit.
In 'Settings' there is the ability to toggle:
1. How many sessions you want to plotting on your chart.
2. Switching ON/OFF Bull/Bear targets.
3. Line color/thickness
4. Ability to offset Header for ADR/AWR vertically.
5. I've put in there a FIB option as well as Classic. FIB counts are at .382 .50 .618 1.00 of ADR and labelled as such.
Price Grid# Price Grid Indicator
A versatile price grid indicator designed for multi-instrument trading, providing dynamic grid lines with customizable settings for different trading instruments.
## Key Features
1. 1.
Multi-Instrument Support
- Customizable grid settings for different symbols
- Supports major forex pairs, commodities, and cryptocurrencies
- Automatic symbol detection and parameter application
2. 2.
Dynamic Grid Configuration
- Adjustable grid intervals
- Customizable price range around current price
- Automatic grid line updates based on price movement
3. 3.
Visual Customization
- Three line styles: Solid, Dashed, and Dotted
- Multiple color levels (L1, L2, L3) for different price points
- Adjustable transparency for each color level
- Default grid color for standard price levels
4. 4.
Smart Price Level Detection
- Grid crossover alerts
- Automatic grid line adjustment as price moves
- Efficient line management to maintain performance
5. 5.
Default Settings Include:
- XAUUSD/Gold Futures
- Major Forex Pairs (EUR, GBP, JPY, etc.)
- Crypto Pairs (BTC, ETH)
- E-mini Futures
## Usage Tips
1. 1.
Grid Parameter Format:
- Symbol|Alias:GridInterval,PriceRange
- Multiple instruments separated by semicolons
- Example: "XAUUSD|MGC1!:5,25;EURUSD:0.002,0.02"
2. 2.
Color Matching Format:
- Symbol:PriceLevel=ColorLevel
- Supports multiple levels per instrument
- Example: "XAUUSD:100=L3,50=L2,10=L1"
3. 3.
Best Practices:
- Adjust grid intervals based on instrument volatility
- Use color levels to highlight significant price levels
- Set appropriate price ranges for your trading timeframe
## Notes
1. 1.
Grid lines automatically adjust as price moves
2. 2.
Alerts trigger when price crosses grid lines
3. 3.
Performance optimized for real-time trading
4. 4.
Compatible with all TradingView timeframes
This indicator is particularly useful for scalping, grid trading strategies, and identifying potential support/resistance levels across multiple instruments.