OPEN-SOURCE SCRIPT
VWAP based long only- AdamMancini

//version=6
indicator("US500 Levels Signal Bot (All TF) [Bias + Levels] v6", overlay=true, max_labels_count=500, max_lines_count=500)
//====================
// Inputs
//====================
levelsCSV = input.string("4725,4750,4792.5,4820", "Key Levels (CSV)")
biasMode = input.string("Auto", "Bias Timeframe", options=["Auto","H4","D","W","Off"])
emaLen = input.int(21, "Bias EMA Length", minval=1)
rsiLen = input.int(14, "RSI Length", minval=1)
atrLen = input.int(14, "ATR Length", minval=1)
proxATR = input.float(0.35, "Level Proximity (x ATR)", minval=0.05, step=0.05)
slATR = input.float(1.30, "SL (x ATR)", minval=0.1, step=0.05)
tp1ATR = input.float(1.60, "TP1 (x ATR)", minval=0.1, step=0.05)
tp2ATR = input.float(2.80, "TP2 (x ATR)", minval=0.1, step=0.05)
useTrend = input.bool(true, "Enable Trend Trigger (Break & Close)")
useMeanRev = input.bool(true, "Enable Mean-Reversion Trigger (Sweep & Reclaim)")
showLevels = input.bool(true, "Plot Levels")
//====================
// Bias TF auto-mapping
//====================
f_autoBiasTf() =>
sec = timeframe.in_seconds(timeframe.period)
string out = "240" // default H4
if sec > 3600 and sec <= 14400
out := "D" // 2H/4H -> Daily bias
else if sec > 14400 and sec <= 86400
out := "W" // D -> Weekly bias
else if sec > 86400
out := "W"
out
biasTF = biasMode == "Auto" ? f_autoBiasTf() :
biasMode == "H4" ? "240" :
biasMode == "D" ? "D" :
biasMode == "W" ? "W" : "Off"
//====================
// Parse levels CSV + plot lines (rebuild on change)
//====================
var float[] levels = array.new_float()
var line[] lvlLines = array.new_line()
f_clearLines() =>
int n = array.size(lvlLines)
if n > 0
// delete from end to start
for i = n - 1 to 0
line.delete(array.get(lvlLines, i))
array.clear(lvlLines)
f_parseLevels(_csv) =>
array.clear(levels)
parts = str.split(_csv, ",")
for i = 0 to array.size(parts) - 1
s = str.trim(array.get(parts, i))
v = str.tonumber(s)
if not na(v)
array.push(levels, v)
f_drawLevels() =>
f_clearLines()
if showLevels
int n = array.size(levels)
if n > 0
for i = 0 to n - 1
lv = array.get(levels, i)
array.push(lvlLines, line.new(bar_index, lv, bar_index + 1, lv, extend=extend.right))
if barstate.isfirst or levelsCSV != levelsCSV[1]
f_parseLevels(levelsCSV)
f_drawLevels()
// Nearest level
f_nearestLevel(_price) =>
float best = na
float bestD = na
int n = array.size(levels)
if n > 0
for i = 0 to n - 1
lv = array.get(levels, i)
d = math.abs(_price - lv)
if na(bestD) or d < bestD
bestD := d
best := lv
best
//====================
// Bias filter (higher TF) - Off supported
//====================
bool biasBull = true
bool biasBear = true
if biasTF != "Off"
b_close = request.security(syminfo.tickerid, biasTF, close, barmerge.gaps_off, barmerge.lookahead_off)
b_ema = request.security(syminfo.tickerid, biasTF, ta.ema(close, emaLen), barmerge.gaps_off, barmerge.lookahead_off)
b_rsi = request.security(syminfo.tickerid, biasTF, ta.rsi(close, rsiLen), barmerge.gaps_off, barmerge.lookahead_off)
biasBull := (b_close > b_ema) and (b_rsi > 50)
biasBear := (b_close < b_ema) and (b_rsi < 50)
//====================
// Execution logic = chart timeframe (closed candle only)
//====================
atr1 = ta.atr(atrLen)[1]
rsi1 = ta.rsi(close, rsiLen)[1]
c1 = close[1]
c2 = close[2]
h1 = high[1]
l1 = low[1]
// Manual execution reference: current bar open (next-bar-open proxy)
entryRef = open
lvl = f_nearestLevel(c1)
prox = proxATR * atr1
nearLevel = not na(lvl) and (math.abs(c1 - lvl) <= prox or (l1 <= lvl and h1 >= lvl))
crossUp = (c2 < lvl) and (c1 > lvl)
crossDown = (c2 > lvl) and (c1 < lvl)
sweepDownReclaim = (l1 < lvl) and (c1 > lvl)
sweepUpReject = (h1 > lvl) and (c1 < lvl)
momBull = rsi1 > 50
momBear = rsi1 < 50
buySignal = nearLevel and biasBull and momBull and ((useTrend and crossUp) or (useMeanRev and sweepDownReclaim))
sellSignal = nearLevel and biasBear and momBear and ((useTrend and crossDown) or (useMeanRev and sweepUpReject))
//====================
// SL/TP (ATR-based)
//====================
slBuy = entryRef - slATR * atr1
tp1Buy = entryRef + tp1ATR * atr1
tp2Buy = entryRef + tp2ATR * atr1
slSell = entryRef + slATR * atr1
tp1Sell = entryRef - tp1ATR * atr1
tp2Sell = entryRef - tp2ATR * atr1
//====================
// Plot signals
//====================
plotshape(buySignal, title="BUY", style=shape.labelup, text="BUY", location=location.belowbar, size=size.tiny)
plotshape(sellSignal, title="SELL", style=shape.labeldown, text="SELL", location=location.abovebar, size=size.tiny)
//====================
// Alerts (Dynamic) - set alert to "Any alert() function call"
//====================
if buySignal
msg = "US500 BUY | TF=" + timeframe.period + " | Bias=" + biasTF +
" | Lvl=" + str.tostring(lvl) +
" | EntryRef=" + str.tostring(entryRef) +
" | SL=" + str.tostring(slBuy) +
" | TP1=" + str.tostring(tp1Buy) +
" | TP2=" + str.tostring(tp2Buy)
alert(msg, alert.freq_once_per_bar_close)
if sellSignal
msg = "US500 SELL | TF=" + timeframe.period + " | Bias=" + biasTF +
" | Lvl=" + str.tostring(lvl) +
" | EntryRef=" + str.tostring(entryRef) +
" | SL=" + str.tostring(slSell) +
" | TP1=" + str.tostring(tp1Sell) +
" | TP2=" + str.tostring(tp2Sell)
alert(msg, alert.freq_once_per_bar_close)
indicator("US500 Levels Signal Bot (All TF) [Bias + Levels] v6", overlay=true, max_labels_count=500, max_lines_count=500)
//====================
// Inputs
//====================
levelsCSV = input.string("4725,4750,4792.5,4820", "Key Levels (CSV)")
biasMode = input.string("Auto", "Bias Timeframe", options=["Auto","H4","D","W","Off"])
emaLen = input.int(21, "Bias EMA Length", minval=1)
rsiLen = input.int(14, "RSI Length", minval=1)
atrLen = input.int(14, "ATR Length", minval=1)
proxATR = input.float(0.35, "Level Proximity (x ATR)", minval=0.05, step=0.05)
slATR = input.float(1.30, "SL (x ATR)", minval=0.1, step=0.05)
tp1ATR = input.float(1.60, "TP1 (x ATR)", minval=0.1, step=0.05)
tp2ATR = input.float(2.80, "TP2 (x ATR)", minval=0.1, step=0.05)
useTrend = input.bool(true, "Enable Trend Trigger (Break & Close)")
useMeanRev = input.bool(true, "Enable Mean-Reversion Trigger (Sweep & Reclaim)")
showLevels = input.bool(true, "Plot Levels")
//====================
// Bias TF auto-mapping
//====================
f_autoBiasTf() =>
sec = timeframe.in_seconds(timeframe.period)
string out = "240" // default H4
if sec > 3600 and sec <= 14400
out := "D" // 2H/4H -> Daily bias
else if sec > 14400 and sec <= 86400
out := "W" // D -> Weekly bias
else if sec > 86400
out := "W"
out
biasTF = biasMode == "Auto" ? f_autoBiasTf() :
biasMode == "H4" ? "240" :
biasMode == "D" ? "D" :
biasMode == "W" ? "W" : "Off"
//====================
// Parse levels CSV + plot lines (rebuild on change)
//====================
var float[] levels = array.new_float()
var line[] lvlLines = array.new_line()
f_clearLines() =>
int n = array.size(lvlLines)
if n > 0
// delete from end to start
for i = n - 1 to 0
line.delete(array.get(lvlLines, i))
array.clear(lvlLines)
f_parseLevels(_csv) =>
array.clear(levels)
parts = str.split(_csv, ",")
for i = 0 to array.size(parts) - 1
s = str.trim(array.get(parts, i))
v = str.tonumber(s)
if not na(v)
array.push(levels, v)
f_drawLevels() =>
f_clearLines()
if showLevels
int n = array.size(levels)
if n > 0
for i = 0 to n - 1
lv = array.get(levels, i)
array.push(lvlLines, line.new(bar_index, lv, bar_index + 1, lv, extend=extend.right))
if barstate.isfirst or levelsCSV != levelsCSV[1]
f_parseLevels(levelsCSV)
f_drawLevels()
// Nearest level
f_nearestLevel(_price) =>
float best = na
float bestD = na
int n = array.size(levels)
if n > 0
for i = 0 to n - 1
lv = array.get(levels, i)
d = math.abs(_price - lv)
if na(bestD) or d < bestD
bestD := d
best := lv
best
//====================
// Bias filter (higher TF) - Off supported
//====================
bool biasBull = true
bool biasBear = true
if biasTF != "Off"
b_close = request.security(syminfo.tickerid, biasTF, close, barmerge.gaps_off, barmerge.lookahead_off)
b_ema = request.security(syminfo.tickerid, biasTF, ta.ema(close, emaLen), barmerge.gaps_off, barmerge.lookahead_off)
b_rsi = request.security(syminfo.tickerid, biasTF, ta.rsi(close, rsiLen), barmerge.gaps_off, barmerge.lookahead_off)
biasBull := (b_close > b_ema) and (b_rsi > 50)
biasBear := (b_close < b_ema) and (b_rsi < 50)
//====================
// Execution logic = chart timeframe (closed candle only)
//====================
atr1 = ta.atr(atrLen)[1]
rsi1 = ta.rsi(close, rsiLen)[1]
c1 = close[1]
c2 = close[2]
h1 = high[1]
l1 = low[1]
// Manual execution reference: current bar open (next-bar-open proxy)
entryRef = open
lvl = f_nearestLevel(c1)
prox = proxATR * atr1
nearLevel = not na(lvl) and (math.abs(c1 - lvl) <= prox or (l1 <= lvl and h1 >= lvl))
crossUp = (c2 < lvl) and (c1 > lvl)
crossDown = (c2 > lvl) and (c1 < lvl)
sweepDownReclaim = (l1 < lvl) and (c1 > lvl)
sweepUpReject = (h1 > lvl) and (c1 < lvl)
momBull = rsi1 > 50
momBear = rsi1 < 50
buySignal = nearLevel and biasBull and momBull and ((useTrend and crossUp) or (useMeanRev and sweepDownReclaim))
sellSignal = nearLevel and biasBear and momBear and ((useTrend and crossDown) or (useMeanRev and sweepUpReject))
//====================
// SL/TP (ATR-based)
//====================
slBuy = entryRef - slATR * atr1
tp1Buy = entryRef + tp1ATR * atr1
tp2Buy = entryRef + tp2ATR * atr1
slSell = entryRef + slATR * atr1
tp1Sell = entryRef - tp1ATR * atr1
tp2Sell = entryRef - tp2ATR * atr1
//====================
// Plot signals
//====================
plotshape(buySignal, title="BUY", style=shape.labelup, text="BUY", location=location.belowbar, size=size.tiny)
plotshape(sellSignal, title="SELL", style=shape.labeldown, text="SELL", location=location.abovebar, size=size.tiny)
//====================
// Alerts (Dynamic) - set alert to "Any alert() function call"
//====================
if buySignal
msg = "US500 BUY | TF=" + timeframe.period + " | Bias=" + biasTF +
" | Lvl=" + str.tostring(lvl) +
" | EntryRef=" + str.tostring(entryRef) +
" | SL=" + str.tostring(slBuy) +
" | TP1=" + str.tostring(tp1Buy) +
" | TP2=" + str.tostring(tp2Buy)
alert(msg, alert.freq_once_per_bar_close)
if sellSignal
msg = "US500 SELL | TF=" + timeframe.period + " | Bias=" + biasTF +
" | Lvl=" + str.tostring(lvl) +
" | EntryRef=" + str.tostring(entryRef) +
" | SL=" + str.tostring(slSell) +
" | TP1=" + str.tostring(tp1Sell) +
" | TP2=" + str.tostring(tp2Sell)
alert(msg, alert.freq_once_per_bar_close)
Open-source script
In true TradingView spirit, the creator of this script has made it open-source, so that traders can review and verify its functionality. Kudos to the author! While you can use it for free, remember that republishing the code is subject to our House Rules.
Disclaimer
The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.
Open-source script
In true TradingView spirit, the creator of this script has made it open-source, so that traders can review and verify its functionality. Kudos to the author! While you can use it for free, remember that republishing the code is subject to our House Rules.
Disclaimer
The information and publications are not meant to be, and do not constitute, financial, investment, trading, or other types of advice or recommendations supplied or endorsed by TradingView. Read more in the Terms of Use.