RSI Bands: Price Projections, Midline and Pine Script
This RSI Bands implementation projects the next source value that would produce a chosen gain/loss ratio after one more smoothing update. It plots the 70 and 30 projections plus their arithmetic midpoint. The midpoint is not generally the price projection for RSI 50, and the labels “Resistance” and “Support” do not establish a reversal probability.
Inspect the Pine ScriptWhat the code actually calculates
With length N = 14, the helper smooths positive and negative source changes using EMA length 2N − 1 = 27. Let the resulting current states be U and D, and let S be the current source. That EMA has coefficient 1/N. The default source is close.
TradingView’s standard RSI explanation uses Wilder RMA for gain and loss. The RMA reference and EMA reference distinguish their initialization: RMA starts with an SMA, whereas EMA starts from its first available source. Equal coefficients do not make these states identical over finite history. Do not promise exact agreement with ta.rsi(close, 14).
Wilder’s RSI dates to 1978; that date does not establish when this overlay was invented. The explanation here follows the displayed helper rather than assigning the overlay an unsupported origin.
Derive each price projection
For a threshold q strictly between 0 and 100 and N greater than 1, form x = (N − 1) × [D × q / (100 − q) − U]. The projected source B(q) is S + x when x is nonnegative, and S + x × (100 − q) / q otherwise. The second branch is essential: a falling source adds to losses rather than gains.
delta = B(q) − S
U_next = ((N − 1) × U + max(delta, 0)) / N
D_next = ((N − 1) × D + max(−delta, 0)) / N
RSI_next = 100 × U_next / (U_next + D_next)
When the denominator is positive, substituting the solved delta yields q. This is one hypothetical next update from the current state, not a forecast. The line is drawn at the current bar with no forward plot offset. A next-bar source compared with the previous bar’s band tests that projection; comparing it with a newly recalculated band tests a different state.
A synthetic example that exposes the midpoint error
Assume S = 100, U = 2, D = 1 and N = 14. These are specified internal states, not an observed trade or a backtest. The current internal ratio corresponds to RSI 66.6667.
| Target q | Projected source B(q) | Next internal RSI |
|---|---|---|
| 70 | 104.333333 | 70 |
| 50 | 87 | 50 |
| 30 | 52.333333 | 30 |
The plotted midpoint is (104.333333 + 52.333333) / 2 = 78.333333. One next update to that source gives RSI 42.857143, not 50. The true 50 projection is S + (N − 1) × (D − U) = 87. Averaging two prices does not average their nonlinear RSI values.
Holding this same state and length fixed, changing 70/30 to 65/35 moves the projections to 99 and 64.714286: the band width shrinks from 52 to 34.285714. Calling 65/35 “wider bands” is incorrect. Changing length at the same time also changes smoothing states, so that is a separate comparison.
Read a touch without confusing source, wick and time
For valid nonnegative U and D with a positive sum, the same-bar source satisfies S ≥ B(q) exactly when its current internal RSI is at least q. Equality corresponds to that threshold. This follows because the sign of B(q) − S is the sign of q − 100U/(U + D). It concerns this EMA-based state, not guaranteed equality with standard RMA-based RSI.
A candle high touching a band calculated from close does not establish a closing RSI threshold. Nor does a touch establish a bounce, profitable short, or filled limit order. At a realtime tick, close and the bands can both change; the snippet has no bar-close gate. Inspect closed bars when comparing finalized historical readings.
The arithmetic midpoint is simply a display line. A midpoint bounce is not automatically an RSI-50 event. Repeated upper-band closes can describe sustained momentum without proving when it will end.
Parameters, missing states and comparison boundaries
The copied call is fixed at close, 14, 70 and 30. It contains no input declarations, alert conditions or strategy orders. Change the call in the editor to test alternatives, or explicitly add inputs. Pineify’s Visual Editor configuration separately exposes source, length and threshold fields; that does not create settings controls in this copied snippet.
Use N greater than 1 and 0 < lower threshold < upper threshold < 100 for the derivation above. The helper does not validate custom arguments. At thresholds 0 or 100 its expressions can divide by zero. N = 1 collapses the projections to the source and cannot generally encode intermediate RSI targets.
If U and D are both zero, the lines also collapse to S, but their implied RSI is undefined. Missing values and initialization require separate inspection; the code has no custom valid-state gate. Recursive EMA history is not a hard 14-bar window, and 14 daily bars do not mean two calendar weeks.
Bollinger Bands use a moving basis and standard deviation, while this envelope solves a smoothed gain/loss equation. Neither a narrow RSI band nor a simultaneous touch of two envelopes proves an imminent breakout or independent confirmation. Compare formulas and test results instead of assigning unsupported reliability grades.
A reproducible evaluation procedure
- Record the symbol, data adjustments, session, timeframe, source and exact code. Check the U/D initialization against a numerical implementation before comparing to standard RSI.
- Reproduce the synthetic states above. Then verify real closed bars using the previous band for next-update tests and the current band for same-state tests; keep wick and close rules separate.
- If evaluating a trading rule, specify crossing versus occupancy, entry timing, position sizing, exits and fees. A band touch is not itself an execution model.
- Vary one parameter at a time, keep an untouched evaluation period, and report actual trade counts and drawdown alongside returns. ADX or ATR filters are hypotheses to test, not guarantees that a move pays transaction costs.
Pine Script v6: implementation and limits
The complete helper below is retained so its two-branch projection can be inspected. The fixed call uses close/14/70/30 and draws three live lines; “Resistance” and “Support” are plot labels, not validated price barriers. No alert or backtest is implemented.
// 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 Bands", overlay=true, max_labels_count=500)
p_custom_sources() =>
[open, high, low, close, volume]
p_ta_rsi_bands(series float source, simple int length, simple int obLevel, simple int osLevel) =>
ep = 2 * length - 1
auc = ta.ema(math.max(source - source[1], 0), ep)
adc = ta.ema(math.max(source[1] - source, 0), ep)
x1 = (length - 1) * (adc * obLevel / (100 - obLevel) - auc)
ub = x1 >= 0 ? source + x1 : source + x1 * (100 - obLevel) / obLevel
x2 = (length - 1) * (adc * osLevel / (100 - osLevel) - auc)
lb = x2 >= 0 ? source + x2 : source + x2 * (100 - osLevel) / osLevel
basis = (ub + lb) / 2
[basis, ub, lb]
[p_ind_1_basis, p_ind_1_upper, p_ind_1_lower] = p_ta_rsi_bands(close, 14, 70, 30)
plot(p_ind_1_upper, "RSI Bands - Resistance", color.rgb(244, 67, 54, 0), 2)
plot(p_ind_1_lower, "RSI Bands - Support", color.rgb(76, 175, 80, 0), 2)
plot(p_ind_1_basis, "RSI Bands - Midline", color.rgb(158, 158, 158, 0), 1)
Specify a checkable adaptation in Pineify
Ask the Pine Script AI Coding Agent for an adaptation with explicit inputs, valid-state checks, a separately calculated RSI-50 projection and clearly specified bar-close alerts. Review the generated source, validate syntax, and reproduce the example numerically in TradingView. Access and usage depend on the current product plan; generated code still needs verification.
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.