// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © all free courses tg- @sarpanch0000
//@version=5
indicator("all free courses tg- @sarpanch0000", overlay=true,
max_boxes_count=500, max_lines_count=500, max_labels_count=500)
// ===== INPUTS =====
grpSwing = "Swing Detection"
swingLen = input.int(5, "Swing Pivot Length", minval=2, group=grpSwing)
historyBars = input.int(2000, "History Lookback (bars)", minval=100, maxval=5000, group=grpSwing)
grpVP = "Volume Profile (per swing)"
showVP = input.bool(true, "Show Volume Profile", group=grpVP)
vpRows = input.int(12, "Rows per Swing", minval=5, maxval=40, group=grpVP)
vpWidth = input.int(15, "Max Bar Width (bars)", minval=5, group=grpVP)
upColor = input.color(color.new(#26A69A, 50), "Up Volume", group=grpVP)
dnColor = input.color(color.new(#EF5350, 50), "Down Volume", group=grpVP)
pocColor = input.color(color.new(color.yellow, 30), "POC Color", group=grpVP)
showPOC = input.bool(true, "Highlight POC", group=grpVP)
vpRecentOnly = input.int(20, "VP Only Last N Swings", minval=5, maxval=100, group=grpVP, tooltip="Volume profiles drawn only for recent swings to save box limit")
grpOB = "HVN Order Block Zones"
showOB = input.bool(true, "Show HVN Boxes", group=grpOB)
extendBars = input.int(30, "Extend Box Right", group=grpOB)
tpATRmult = input.float(2.0, "TP ATR Multiplier", step=0.1, group=grpOB)
slATRmult = input.float(1.0, "SL ATR Multiplier", step=0.1, group=grpOB)
buyColor = input.color(color.new(#00BCD4, 80), "Buy HVN", group=grpOB)
sellColor = input.color(color.new(#E91E63, 80), "Sell HVN", group=grpOB)
showLabels = input.bool(true, "Show TP Labels", group=grpOB)
labelRecentOnly = input.int(15, "Labels Only Last N Boxes", minval=3, maxval=50, group=grpOB)
grpSig = "Signals"
showSignals = input.bool(true, "Show Buy/Sell Arrows", group=grpSig)
buyArrow = input.color(#00E676, "Buy Arrow", group=grpSig)
sellArrow = input.color(#FF1744, "Sell Arrow", group=grpSig)
grpDash = "Dashboard"
showDash = input.bool(true, "Show Dashboard", group=grpDash)
dashLoc = input.string("top_right", "Position", options=["top_right","top_left","bottom_right","bottom_left","middle_right"], group=grpDash)
dashSize = input.string("normal", "Size", options=["tiny","small","normal","large"], group=grpDash)
// ===== HELPERS =====
atrV = ta.atr(14)
txtSize = dashSize == "tiny" ? size.tiny : dashSize == "small" ? size.small : dashSize == "large" ? size.large : size.normal
dashPos = dashLoc == "top_left" ? position.top_left : dashLoc == "bottom_right" ? position.bottom_right : dashLoc == "bottom_left" ? position.bottom_left : dashLoc == "middle_right" ? position.middle_right : position.top_right
// ===== STATS COUNTERS =====
var int totalSignals = 0
var int buySignals = 0
var int sellSignals = 0
var int wins = 0
var int losses = 0
var int openTrades = 0
var int holograms = 0
// Track open trades
var float[] openBuyEntries = array.new_float()
var float[] openBuyTPs = array.new_float()
var float[] openBuySLs = array.new_float()
var float[] openSellEntries = array.new_float()
var float[] openSellTPs = array.new_float()
var float[] openSellSLs = array.new_float()
// Track signal counts to limit recent VP/labels
var int totalSwings = 0
// ===== USE LINES instead of BOXES for HVN (saves box limit!) =====
drawHVNZone(int startBar, float hi, float lo, bool isBuy) =>
if showOB
col = isBuy ? color.new(#00BCD4, 50) : color.new(#E91E63, 50)
fillCol = isBuy ? buyColor : sellColor
// Use lines for top/bottom (no box limit issue)
line.new(startBar, hi, bar_index + extendBars, hi, color=col, width=2)
line.new(startBar, lo, bar_index + extendBars, lo, color=col, width=2)
// Optional: use linefill for shading
topL = line.new(startBar, hi, bar_index + extendBars, hi, color=color.new(col, 100))
botL = line.new(startBar, lo, bar_index + extendBars, lo, color=color.new(col, 100))
linefill.new(topL, botL, color=fillCol)
// ===== DRAW SWING VP (only recent ones) =====
drawSwingVP(int startBar, int endBar, float hi, float lo) =>
if showVP and endBar > startBar and hi > lo
bars = endBar - startBar
rowH = (hi - lo) / vpRows
float[] upVols = array.new_float(vpRows, 0)
float[] dnVols = array.new_float(vpRows, 0)
for i = 0 to bars - 1
barIdx = endBar - i
offset = bar_index - barIdx
if offset >= 0 and offset < 5000
bH = high[offset]
bL = low[offset]
bV = volume[offset]
bUp = close[offset] >= open[offset]
for r = 0 to vpRows - 1
rLo = lo + r * rowH
rHi = rLo + rowH
if bH >= rLo and bL <= rHi
share = bV / vpRows
if bUp
array.set(upVols, r, array.get(upVols, r) + share)
else
array.set(dnVols, r, array.get(dnVols, r) + share)
float maxVol = 0.0
int pocRow = 0
for r = 0 to vpRows - 1
tot = array.get(upVols, r) + array.get(dnVols, r)
if tot > maxVol
maxVol := tot
pocRow := r
if maxVol > 0
for r = 0 to vpRows - 1
up = array.get(upVols, r)
dn = array.get(dnVols, r)
tot = up + dn
if tot > 0
wTotal = math.max(1, int((tot / maxVol) * vpWidth))
wUp = int((up / tot) * wTotal)
wDn = wTotal - wUp
rLo = lo + r * rowH
rHi = rLo + rowH
isPOC = showPOC and r == pocRow
if wUp > 0
box.new(startBar, rHi, startBar + wUp, rLo,
bgcolor = isPOC ? pocColor : upColor,
border_color=color.new(color.gray, 95))
if wDn > 0
box.new(startBar + wUp, rHi, startBar + wUp + wDn, rLo,
bgcolor = isPOC ? pocColor : dnColor,
border_color=color.new(color.gray, 95))
// ===== Draw label only for recent =====
drawTPLabel(int barIdx, float hi, float lo, bool isBuy, float tp, int swingNum) =>
if showLabels and (totalSwings - swingNum) <= labelRecentOnly
txtCol = isBuy ? color.new(#00BCD4, 0) : color.new(#E91E63, 0)
txt = (isBuy ? "BUY HVN\nTP: " : "SELL HVN\nTP: ") + str.tostring(tp, format.mintick)
label.new(bar_index + extendBars, (hi + lo) / 2, txt,
style=label.style_label_left, color=txtCol, textcolor=color.white, size=size.small)
// ===== PIVOT DETECTION =====
ph = ta.pivothigh(high, swingLen, swingLen)
pl = ta.pivotlow(low, swingLen, swingLen)
var int lastPivotBar = na
var float lastPivotPrice = na
var bool lastWasHigh = false
inHistory = bar_index > (last_bar_index - historyBars)
// ===== SELL SWING =====
if not na(ph) and inHistory
pivotBar = bar_index - swingLen
pivotPrice = ph
if not na(lastPivotBar) and not lastWasHigh
hi = pivotPrice
lo = lastPivotPrice
totalSwings += 1
// Draw VP only for recent N swings
// (Will be checked when we know totalSwings on last bar - for now draw all & rely on box limit)
drawSwingVP(lastPivotBar, pivotBar, hi, lo)
if showOB
entry = close
tp = entry - atrV * tpATRmult
sl = entry + atrV * slATRmult
drawHVNZone(pivotBar, hi, hi - (hi - lo) * 0.15, false)
drawTPLabel(pivotBar, hi, hi - (hi - lo) * 0.15, false, tp, totalSwings)
array.push(openSellEntries, entry)
array.push(openSellTPs, tp)
array.push(openSellSLs, sl)
sellSignals := sellSignals + 1
totalSignals := totalSignals + 1
openTrades := openTrades + 1
holograms := holograms + 1
if showSignals
label.new(pivotBar, hi, "▼", style=label.style_none, textcolor=sellArrow, size=size.normal, yloc=yloc.abovebar)
lastPivotBar := pivotBar
lastPivotPrice := pivotPrice
lastWasHigh := true
// ===== BUY SWING =====
if not na(pl) and inHistory
pivotBar = bar_index - swingLen
pivotPrice = pl
if not na(lastPivotBar) and lastWasHigh
hi = lastPivotPrice
lo = pivotPrice
totalSwings += 1
drawSwingVP(lastPivotBar, pivotBar, hi, lo)
if showOB
entry = close
tp = entry + atrV * tpATRmult
sl = entry - atrV * slATRmult
drawHVNZone(pivotBar, lo + (hi - lo) * 0.15, lo, true)
drawTPLabel(pivotBar, lo + (hi - lo) * 0.15, lo, true, tp, totalSwings)
array.push(openBuyEntries, entry)
array.push(openBuyTPs, tp)
array.push(openBuySLs, sl)
buySignals := buySignals + 1
totalSignals := totalSignals + 1
openTrades := openTrades + 1
holograms := holograms + 1
if showSignals
label.new(pivotBar, lo, "▲", style=label.style_none, textcolor=buyArrow, size=size.normal, yloc=yloc.belowbar)
lastPivotBar := pivotBar
lastPivotPrice := pivotPrice
lastWasHigh := false
// ===== TRACK WIN/LOSS =====
if array.size(openBuyEntries) > 0
for i = array.size(openBuyEntries) - 1 to 0
tp = array.get(openBuyTPs, i)
sl = array.get(openBuySLs, i)
if high >= tp
wins := wins + 1
openTrades := openTrades - 1
array.remove(openBuyEntries, i)
array.remove(openBuyTPs, i)
array.remove(openBuySLs, i)
else if low <= sl
losses := losses + 1
openTrades := openTrades - 1
array.remove(openBuyEntries, i)
array.remove(openBuyTPs, i)
array.remove(openBuySLs, i)
if array.size(openSellEntries) > 0
for i = array.size(openSellEntries) - 1 to 0
tp = array.get(openSellTPs, i)
sl = array.get(openSellSLs, i)
if low <= tp
wins := wins + 1
openTrades := openTrades - 1
array.remove(openSellEntries, i)
array.remove(openSellTPs, i)
array.remove(openSellSLs, i)
else if high >= sl
losses := losses + 1
openTrades := openTrades - 1
array.remove(openSellEntries, i)
array.remove(openSellTPs, i)
array.remove(openSellSLs, i)
// ===== DASHBOARD =====
if showDash and barstate.islast
closedTrades = wins + losses
winRate = closedTrades > 0 ? (wins / closedTrades) * 100 : 0
var table dash = table.new(dashPos, 2, 9, border_width=1, border_color=color.new(color.gray, 50))
table.cell(dash, 0, 0, "🎯 Swing VP Pro", bgcolor=color.new(#7B1FA2, 0), text_color=color.white, text_size=txtSize)
table.cell(dash, 1, 0, "Stats", bgcolor=color.new(#7B1FA2, 0), text_color=color.white, text_size=txtSize)
bgRow = color.new(color.black, 70)
txtCol = color.white
table.cell(dash, 0, 1, "Holograms", bgcolor=bgRow, text_color=txtCol, text_size=txtSize)
table.cell(dash, 1, 1, str.tostring(holograms), bgcolor=bgRow, text_color=color.yellow, text_size=txtSize)
table.cell(dash, 0, 2, "Total Signals", bgcolor=bgRow, text_color=txtCol, text_size=txtSize)
table.cell(dash, 1, 2, str.tostring(totalSignals), bgcolor=bgRow, text_color=color.aqua, text_size=txtSize)
table.cell(dash, 0, 3, "Buy Signals", bgcolor=bgRow, text_color=txtCol, text_size=txtSize)
table.cell(dash, 1, 3, str.tostring(buySignals), bgcolor=bgRow, text_color=#00E676, text_size=txtSize)
table.cell(dash, 0, 4, "Sell Signals", bgcolor=bgRow, text_color=txtCol, text_size=txtSize)
table.cell(dash, 1, 4, str.tostring(sellSignals), bgcolor=bgRow, text_color=#FF1744, text_size=txtSize)
table.cell(dash, 0, 5, "Open Trades", bgcolor=bgRow, text_color=txtCol, text_size=txtSize)
table.cell(dash, 1, 5, str.tostring(openTrades), bgcolor=bgRow, text_color=color.orange, text_size=txtSize)
table.cell(dash, 0, 6, "Wins ✅", bgcolor=bgRow, text_color=txtCol, text_size=txtSize)
table.cell(dash, 1, 6, str.tostring(wins), bgcolor=bgRow, text_color=color.lime, text_size=txtSize)
table.cell(dash, 0, 7, "Losses ❌", bgcolor=bgRow, text_color=txtCol, text_size=txtSize)
table.cell(dash, 1, 7, str.tostring(losses), bgcolor=bgRow, text_color=color.red, text_size=txtSize)
wrColor = winRate >= 70 ? color.lime : winRate >= 50 ? color.yellow : color.red
table.cell(dash, 0, 8, "Win Rate 🏆", bgcolor=color.new(#1A237E, 0), text_color=color.white, text_size=txtSize)
table.cell(dash, 1, 8, str.tostring(winRate, "#.##") + "%", bgcolor=color.new(#1A237E, 0), text_color=wrColor, text_size=txtSize)
// ===== ALERTS =====
alertcondition(not na(pl), "Buy Swing Signal", "🟢 Bullish HVN swing detected")
alertcondition(not na(ph), "Sell Swing Signal", "🔴 Bearish HVN swing detected")