The script
An EMA cloud that changes color with the trend, a background that darkens as RSI goes further past 70 or under 30, and candles highlighted on high volume. Paste it into a new indicator in the Pine Editor, then save and add it to the chart.
//@version=6
indicator("Background, fill and bar colors", overlay = true)
fastLen = input.int(20, "Fast EMA", minval = 1)
slowLen = input.int(50, "Slow EMA", minval = 2)
rsiLen = input.int(14, "RSI length", minval = 2)
volMult = input.float(1.5, "High volume (x 20-bar average)", minval = 1, step = 0.1)
fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)
rsi = ta.rsi(close, rsiLen)
volAvg = ta.sma(volume, 20)
bool bull = fast > slow
// fill() works on plot IDs: keep what plot() returns
pFast = plot(fast, "Fast EMA", bull ? color.teal : color.red)
pSlow = plot(slow, "Slow EMA", color.gray)
fill(pFast, pSlow, bull ? color.new(color.teal, 80) : color.new(color.red, 80), "Trend cloud")
// Background: transparent at 70, stronger as RSI rises to 90 (and the mirror below 30)
color hotColor = color.from_gradient(rsi, 70, 90, color.new(color.red, 100), color.new(color.red, 70))
color coldColor = color.from_gradient(rsi, 10, 30, color.new(color.green, 70), color.new(color.green, 100))
bgcolor(rsi > 70 ? hotColor : rsi < 30 ? coldColor : na, title = "RSI extremes")
// Candles: strong up or down bars on high volume, on the right side of the slow EMA
bool bigVolume = volume > volMult * volAvg
bool strongUp = bigVolume and close > open and close > slow
bool strongDown = bigVolume and close < open and close < slow
barcolor(strongUp ? color.lime : strongDown ? color.fuchsia : na, title = "High-volume bars")How it works
pFast = plot(...).plot()returns an ID, andfill()takes two of them. It can't take the values themselves, and it can't mix a plot ID with an hline ID.- Colors that change per bar.
plot(),fill(),bgcolor()andbarcolor()all accept a series color, so one call covers both trend states.color.new(color.teal, 80)sets the transparency: 0 is opaque, 100 invisible; 80–95 keeps candles readable. color.from_gradient(value, bottom, top, bottomColor, topColor)blends between two colors asvaluemoves frombottomtotop, and clamps outside that range. Here the background goes from invisible at RSI 70 to 70% transparent red at 90.nameans no color. The ternaries returnnaon ordinary bars, so the background and candles keep their normal look there.titlenames each element in the Style tab, where the user can hide or recolor it.
Pitfalls
- Calling them in an if block.
if bullfollowed bybgcolor(...)gives Cannot use bgcolor in local scope. Put the condition in the color instead:bgcolor(bull ? color.new(color.teal, 90) : na). - The old transp argument.
bgcolor(color.red, transp = 80)is v4 code: v6 removedtransp(the transp argument page). Usecolor.new(color.red, 80). - A moving level with hline().
hline()draws a fixed level, sohline(ta.sma(close, 50))fails with series float vs input float. Plot the moving value, and fill between plots. - Filling plot values instead of IDs.
fill(fast, slow, ...)passes two series of prices, whichfill()doesn't accept. Pass whatplot()returned. - A fill with hidden lines. To show only the cloud, keep the plots but give them a fully transparent color (
color.new(color.gray, 100)): the fill still needs the two plots to exist.
Variations
Zones in an oscillator pane. fill() between two hline() levels shades a fixed zone, and a fill between the RSI plot and an invisible midline shows which side of 50 it is on.
//@version=6
indicator("RSI with filled zones", overlay = false)
rsi = ta.rsi(close, 14)
h70 = hline(70, "Overbought", color.gray)
h30 = hline(30, "Oversold", color.gray)
fill(h70, h30, color.new(color.blue, 92), "Neutral zone")
pRsi = plot(rsi, "RSI", color.purple)
pMid = plot(50, "Midline", color.new(color.gray, 100))
fill(pRsi, pMid, rsi > 50 ? color.new(color.teal, 80) : color.new(color.red, 80), "Above or below 50")
Background during a session. bgcolor(not na(time(timeframe.period, "0930-1600", "America/New_York")) ? color.new(color.blue, 92) : na) shades the New York cash session; the session filter guide covers time zones and overnight sessions.
Questions
How do I fill between two lines in Pine Script?
Keep the IDs returned by plot(), for example p1 = plot(fast) and p2 = plot(slow), then call fill(p1, p2, color.new(color.teal, 80)). The color can change per bar. For two fixed levels, use the IDs returned by hline().
How do I color candles in Pine Script?
Call barcolor() at the top level with a color expression, for example barcolor(close > open and volume > ta.sma(volume, 20) ? color.lime : na). Bars where the expression is na keep their normal color.
Why does my background color hide the candles?
The color is too opaque. In color.new(color, transparency), 0 is opaque and 100 invisible: backgrounds usually read well between 80 and 95.
Related pages
Every script on this page was checked with Edgoro Pine Check (Pine Script v6 rules). Pine Check is a static checker, not TradingView's compiler: TradingView compiles the script when you save it in the Pine Editor. The scripts are examples to learn from, not trading systems. Trading involves substantial risk of loss and is not suitable for every investor. Edgoro is a software tool, not a broker or financial adviser: nothing it produces is investment advice, and past or backtested performance does not guarantee future results.