RSI Candles: Exact Bar Colors and Pine Script
RSI Candles compresses a gain/loss oscillator into three display states: green above 70, red below 30, and no color override otherwise. It changes the appearance of the main chart bars; it does not create synthetic RSI candles or calculate a trading result. The returned RSI value is not plotted in this snippet.
Inspect the Pine ScriptFollow the actual formula and its zero cases
The helper applies Wilder RMA to positive and negative changes in close. With length N, its recursive coefficient is 1/N after initialization. TradingView’s RSI explanation describes the gain/loss ratio; the code below adds explicit zero tests.
U = RMA(max(change(source), 0), N)
D = RMA(max(−change(source), 0), N)
if D = 0: RSI = 100
else if U = 0: RSI = 0
else: RSI = 100 − 100 / (1 + U / D)
Branch order matters. Once initialized, a constant-price history has U = D = 0, so the first test returns 100 and the default overlay colors bars green. This is the helper’s explicit policy, not evidence of buying pressure. Do not describe the script as identical to every built-in RSI implementation at undefined or missing-data boundaries.
The first possible RMA seed with uninterrupted prices requires N changes, hence N + 1 closes. With N = 14 that is 15 closes. Afterward the averages retain recursively decaying history; they do not use only the latest 14 bars. Missing data can alter initialization and comparison availability.
Color states include equality and initialization
| Computed value | Default action | Meaning in this code |
|---|---|---|
| RSI > 70 | Green override | Upper state on every qualifying bar |
| RSI < 30 | Red override | Lower state on every qualifying bar |
| 30 ≤ RSI ≤ 70 | No override | Includes equality at both boundaries |
| RSI unavailable | No override | Not proof of a valid neutral reading |
The barcolor documentation explains that an na color leaves bars unchanged. An ordinary chart bar might already be green or red, so its visible color alone does not prove this overlay applied it. Use distinctive colors or a separate numeric plot when diagnosing the state.
The conditions do not inspect open. A green override does not necessarily mean close is above open, above the previous close, or that RSI rose on this bar. The code checks the current level, not its slope.
Reproduce a green bar during a price decline
Take a hypothetical initialized length-14 state U = 4 and D = 1, corresponding to RSI 80. Let the next close fall by 1. The updates are U = 52/14 and D = 14/14, giving RSI = 100 × 52/66 = 78.787879. The new bar is still colored green despite the falling close and falling RSI. This arithmetic example is not a market-performance claim.
For a boundary-only test, supply computed RSI values 69, 70, 71, 72, 70, 30, 29, 30. The actions are unchanged, unchanged, green, green, unchanged, unchanged, red, unchanged. There are two green states but only one entry into the upper state. The move 72 → 70 ends the color at equality; a strict cross below 70 has not occurred yet.
Likewise, “isDown becomes false” does not necessarily mean the new bar is neutral. RSI could jump from below 30 to above 70, making it green. Define the destination range explicitly if a rule needs a return to neutral.
What changing thresholds can and cannot guarantee
Holding the same RSI series fixed, increasing the upper level from 70 to 80 and lowering the lower level from 30 to 20 cannot increase the number of extreme-state bars. The new colored set is a subset of the old one. The reduction need not be 50%, and the number of separate entry or exit events need not decrease.
Changing length or source changes the RSI series itself, so that subset argument no longer applies. There is no fixed multiplier for colored-bar counts when length is halved. HL2 is a different source, not a guarantee of fewer colors.
Multiplying every price by a positive constant multiplies both smoothed gains and losses by that constant and preserves their ratio. A claim that larger absolute price swings alone must generate more colored bars is therefore unsupported. Asset, session and timeframe comparisons need measured data and consistent definitions.
Implementation limits and a checkable workflow
The copied script fixes source/length/upper/lower at close/14/70/30. It has no input declarations, numeric RSI plot, divergence detection, multi-timeframe request, alerts or strategy orders. The separate Pineify Visual Editor configuration exposes four parameters and color controls; those controls are not automatically present in this standalone script.
Use a positive length and ordered lower/upper thresholds when adapting it. The helper does not validate crossed thresholds. If lower exceeds upper, both booleans can be true for values between them; the outer color expression gives green priority.
There is no bar-close confirmation gate. Realtime price changes can change a forming bar’s color, while historical bars show finalized calculations. A bar-close policy must be explicitly implemented if that is the intended behavior.
- Check initialization, constant prices, equality at 30/70, and the synthetic falling-price example before interpreting a chart.
- Compare the actual RSI value in a numeric plot when exact values or divergence matter. Stochastic measures position within a price range; it does not display an exact RSI value.
- For trading tests, define state versus transition, entry timing, exits, fees and an untouched evaluation period. A trend or volume filter does not have an established win-rate benefit here.
Pine Script v6: implementation and limits
The complete original helper is shown below, including its zero-loss-first policy. Inspect that behavior before substituting it for another RSI implementation. This example colors bars only and retains fixed parameters.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify
//@version=6
indicator(title="RSI Candles", overlay=true, max_labels_count=500)
p_ta_rsi_chart_bars(series float src, simple int len, simple int upLevel, simple int downLevel) =>
up = ta.rma(math.max(ta.change(src), 0), len)
down = ta.rma(-math.min(ta.change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
isUp = rsi > upLevel
isDown = rsi < downLevel
[rsi, isUp, isDown]
[p_ind_1_rsi, p_ind_1_isUp, p_ind_1_isDown] = p_ta_rsi_chart_bars(close, 14, 70, 30)
barcolor(p_ind_1_isUp ? color.rgb(0, 255, 0, 0) : p_ind_1_isDown ? color.rgb(255, 0, 0, 0) : na, title="RSI Candles - Bar Color")
Specify a checkable adaptation in Pineify
Ask for explicit inputs, distinguishable colors, a numeric RSI in the Data Window and a documented policy for zero gains and losses. If requesting alerts, specify state-entry versus threshold-crossing and bar-close behavior. Validate the generated source and compare these edge cases in TradingView before using it.
Open Pine Script AI Coding AgentEducational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.