HalfTrend + TMA Centered Bands Indicator v0.42 BY LUPEN
HalfTrend + TMA Centered Bands Indicator v0.42 BY LUPEN
//author: mladen
//rebound arrows and TMA angle caution: Ale
//rewritten from MQL5 to Pine: Brylator
indicator("HalfTrend + TMA Centered Bands Indicator v0.42 BY LUPEN", overlay =
true, max_lines_count = 500, max_labels_count = 500)
//INPUTS
var GRP1 = "MA Centered Bands Indicator --> Parameters"
HalfLength = input.int(12, "Centered TMA half period", group = GRP1)
string PriceType = input.string("Weighted", "Price to use", options = ["Close",
"Open", "High", "Low", "Median", "Typical", "Weighted", "Average"], group = GRP1)
AtrPeriod = input.int(100, "Average true range period", group = GRP1)
AtrMultiplier = input.float(2, "Average true range multiplier", group = GRP1)
TMAangle = input.int(4, "Centered TMA angle caution", group = GRP1)
//VARIABLES
float tmac = na
float tmau = na
float tmad = na
//COLORS
var GRP2 = "MA Centered Bands Indicator --> Colors"
var color colorBuffer = na
color colorDOWN = input.color(color.new(color.red, 0), "Bear", inline = "5", group
= GRP2)
color colorUP = input.color(color.new(color.green, 0), "Bull", inline = "5", group
= GRP2)
color colorBands = input.color(color.new(#b2b5be, 0), "Bands", inline = "5", group
= GRP2)
bool cautionInput = input.bool(true, "Caution label", inline = "6", group = GRP2)
//ALERTS
var GRP3 = "Alerts (Needs to create alert manually after every change)"
bool crossUpInput = input.bool(false, "Crossing up", inline = "7", group = GRP3)
bool crossDownInput = input.bool(false, "Crossing down", inline = "7", group =
GRP3)
bool comingBackInput = input.bool(false, "Coming back", inline = "7", group = GRP3)
bool onArrowDownInput = input.bool(false, "On arrow down", inline = "8", group =
GRP3)
bool onArrowUpInput = input.bool(false, "On arrow up", inline = "8", group = GRP3)
//CLEAR LINES
a_allLines = line.all
if array.size(a_allLines) > 0
for p = 0 to array.size(a_allLines) - 1
line.delete(array.get(a_allLines, p))
//GET PRICE
Price(x) =>
float price = switch PriceType
"Close" => close[x]
"Open" => open[x]
"High" => high[x]
"Low" => low[x]
"Median" => (high[x] + low[x]) / 2
"Typical" => (high[x] + low[x] + close[x]) / 3
"Weighted" => (high[x] + low[x] + close[x] + close[x]) / 4
"Average" => (high[x] + low[x] + close[x] + open[x])/ 4
price
atr2 = ta.atr(100) / 2
dev = channelDeviation * atr2
highPrice = high[math.abs(ta.highestbars(amplitude))]
lowPrice = low[math.abs(ta.lowestbars(amplitude))]
highma = ta.sma(high, amplitude)
lowma = ta.sma(low, amplitude)
if nextTrend == 1
maxLowPrice := math.max(lowPrice, maxLowPrice)
if trend == 0
if not na(trend[1]) and trend[1] != 0
up := na(down[1]) ? down : down[1]
arrowUp := up - atr2
arrowUp
else
up := na(up[1]) ? maxLowPrice : math.max(maxLowPrice, up[1])
up
atrHigh := up + dev
atrLow := up - dev
atrLow
else
if not na(trend[1]) and trend[1] != 1
down := na(up[1]) ? up : up[1]
arrowDown := down + atr2
arrowDown
else
down := na(down[1]) ? minHighPrice : math.min(minHighPrice, down[1])
down
atrHigh := down + dev
atrLow := down - dev
atrLow
ht = trend == 0 ? up : down
//MAIN
for i = HalfLength to 0
//ATR
atr = 0.0
for j = 0 to AtrPeriod - 1
atr += math.max(high[i + j + 10], close[i + j + 11]) - math.min(low[i + j +
10], close[i + j + 11])
atr /= AtrPeriod
//BANDS
sum = (HalfLength + 1) * Price(i)
sumw = (HalfLength + 1)
k = HalfLength
for j = 1 to HalfLength
sum += k * Price(i + j)
sumw += k
if (j <= i)
sum += k * Price(i - j)
sumw += k
k -= 1
tmac := sum/sumw
tmau := tmac+AtrMultiplier*atr
tmad := tmac-AtrMultiplier*atr
//ALERTS
if i == 0 //Only on a real candle
if (high > tmau and alertSignal != "UP") //crossing up band
if crossUpInput == true //checks if activated
alert("Crossing up Band") //calling alert
alertSignal := "UP" //to avoid repeating
else if (low < tmad and alertSignal != "DOWN") //crossing down band
if crossDownInput == true
alert("Crossing down Band")
alertSignal := "DOWN"
else if (alertSignal == "DOWN" and high >= tmad and alertSignal != "EMPTY")
//back from the down band
if comingBackInput == true
alert("Coming back")
alertSignal := "EMPTY"
else if (alertSignal == "UP" and low <= tmau and alertSignal !=
"EMPTY") //back from the up band
if comingBackInput == true
alert("Coming back")
alertSignal := "EMPTY"
//SIGNALS
reboundD = 0.0
reboundU = 0.0
caution = 0.0
if pastTmac != 0.0
if (high[i + 1] > pastTmau and close[i + 1] > open[i + 1] and close[i] <
open[i])
reboundD := high[i] + AtrMultiplier * atr / 2
if (tmac - pastTmac > TMAangle * point)
caution := reboundD + 10 * point
if (low[i + 1] < pastTmad and close[i + 1] < open[i + 1] and close[i] >
open[i])
reboundU := low[i] - AtrMultiplier * atr / 2
if (pastTmac - tmac > TMAangle * point)
caution := reboundU - 10 * point
//LAST REAL
if barstate.islast and i == HalfLength
last := true
tmau_temp := tmau
tmac_temp := tmac
tmad_temp := tmad
//DRAW SIGNALS
if reboundD != 0 and highma < maxLowPrice
label.new(bar_index - (i) , reboundD, '▼', color = na, textcolor =
colorDOWN, textalign= text.align_center)
if i == 0 and onArrowDownInput == true //alert
alert("Down arrow")
if caution != 0 and cautionInput == true
label.new(bar_index - (i), reboundD, color = colorUP, style =
label.style_xcross, size = size.tiny, textcolor = na)
if reboundU != 0 and lowma > minHighPrice
label.new(bar_index - (i) , reboundU, '▲', color = na, textcolor =
colorUP, textalign = text.align_center)
if i == 0 and onArrowUpInput == true //alert
alert("UP arrow")
if caution != 0 and cautionInput == true
label.new(bar_index - (i), reboundU, color = colorDOWN, style =
label.style_xcross, size = size.tiny, textcolor = na)
//SAVE HISTORY
pastTmac := tmac
pastTmau := tmau
pastTmad := tmad