RMO Pine Script: Cascade, Range and Color Logic
This RMO implementation compares price with the average of ten cascaded two-bar SMAs, divides by a rolling source range, and sends the raw result into separate EMA branches. The plotted histogram is the long EMA of that raw result. Its color follows a separate priority rule, so a green column can appear below zero.
Inspect the Pine ScriptIdentify the implementation before comparing systems
Rahul Mohindar’s Viratech user guide identifies him with the RMO system and describes its MetaStock context. The source printed here is Pineify’s inspectable implementation. Its fixed 10/30/30/81 arguments and display rules are not presented as proof of exact equivalence to a proprietary MetaStock package.
The helper is custom code, not a built-in Pine function. This page explains its actual arithmetic and outputs, including asymmetrical color conditions. No measured performance advantage over RSI, MACD or TSI is established.
Ten SMA stages, then two EMA branches
Start with MA1 = SMA(source, 2), then MA2 = SMA(MA1, 2), continuing to MA10. The baseline is the average of all ten stages. It is not just MA10, and it is not SMA(source, 10).
Baseline = (MA1 + MA2 + ... + MA10) / 10
Range = highest(source, swingLength) − lowest(source, swingLength)
Raw = 100 × (source − Baseline) / Range
Swing2 = EMA(Raw, 30)
Swing3 = EMA(Swing2, 30)
RMO = EMA(Raw, 81)
Swing3 receives two EMA passes; RMO receives one directly from Raw. The EMA81 is not applied after Swing3. Changing the first signal EMA affects both Swing2 and Swing3 but not the RMO calculation. Changing the second affects Swing3 and cross events. Changing the RMO length affects the histogram and its trend-dependent colors, not the two signal-line values.
Each two-bar SMA adds one observation to the finite cascade support. With complete data, MA10 needs 11 source observations. The subsequent EMAs retain decaying history, so that initial minimum does not guarantee convergence or matching values from different loaded histories.
Two arithmetic checks expose the range boundary
For a steady synthetic ramp 0, 1, 2, …, 10, the final stage values are 9.5, 9, 8.5, …, 5. Their average is 7.25. At swingLength 10, the final source range is 10 − 1 = 9, so Raw = 100 × (10 − 7.25) / 9 = 30.555556. Using only MA10 would incorrectly give 55.555556.
The raw ratio is not bounded to ±100. Consider 11 sources: an initial 0, nine observations of 100, then 100.001. The last ten sources span only 0.001, but MA10 still includes the initial 0. The ten-stage average is 99.990334277344, and Raw is approximately 1066.572266. These are synthetic calculations of Raw, not prices from a market or a promise that the smoothed histogram immediately takes the same value.
The denominator uses the range of the selected source; with close selected it is not highest high minus lowest low. Reducing a range window can shrink the denominator and enlarge a nonzero raw reading. No clipping occurs in this code.
A zero denominator makes Raw undefined. This copy has no explicit zero-range policy or current-validity gate. EMA’s handling of missing raw inputs can leave a previous smoothed value displayed; that should not be read as a fresh valid range calculation. A constant series from initialization cannot produce a valid ratio. Decide whether an adaptation should hold or hide outputs before testing it.
Read the histogram’s exact priority rule
The helper defines impulseUp as Swing2 > 0, but impulseDown as RMO < 0. Those are different series. The display checks impulseUp first, then impulseDown, then positive RMO. For finite values, its cases are:
| Condition | Column color | Background |
|---|---|---|
| Swing2 > 0, RMO < 0 | Green | Red |
| Swing2 ≤ 0, RMO < 0 | Red | Red |
| RMO > 0, either Swing2 sign | Green | Green |
| RMO = 0, Swing2 ≤ 0 | Blue | Blue |
| RMO = 0, Swing2 > 0 | Green | Blue |
The height is always RMO. Green below zero is therefore permitted, and green does not prove Swing2 is positive. Blue is not the state “positive RMO without upward impulse”; positive RMO selects green. At RMO = 0 the column has zero height even if its color expression selects a color.
The orange line plots Swing2 and the purple line plots Swing3. The background uses only the sign of RMO. Color state, histogram sign and signal-line crossover are separate observations; the code does not require a state to persist for three bars.
Calculated events are not alerts or orders
The helper returns crossover and crossunder booleans for Swing2 and Swing3. The surrounding script does not plot those booleans or declare alert conditions. Its lengths are fixed function arguments, with no input panel controls. It has no divergence detector, ADX filter, volume input, higher-timeframe request or strategy orders.
Current source values can change before bar close, including the source range and all derived plots. There is no fixed two- or three-bar “repainting window.” A closed-bar event needs an explicit confirmation rule; adding a waiting period is a separate trading condition, not proof that data cannot change.
To compare another oscillator or implementation, match the baseline, range window, smoothing branch and initialization first. To test trades, separately define first-event versus continuing-state entries, exits, costs and evaluation data. The printed code establishes none of the win rates or market preferences needed to choose a profitable strategy.
Pine Script v6: implementation and limits
The complete copy retains the existing calculations and color conditions. The introductory comment has been corrected to describe parallel EMA branches rather than three sequential passes.
// 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="Rahul Mohindar Oscillator", overlay=false, max_labels_count=500)
// RMO — average of 10 cascaded SMA stages with separate EMA branches
// Parameters: source=close, swingLength=10, swingEmaLength1=30, swingEmaLength2=30, rmoLength=81
p_ta_rmo(series float source, simple int swingLength, simple int swingEmaLength1, simple int swingEmaLength2, simple int rmoLength) =>
ma1 = ta.sma(source, 2)
ma2 = ta.sma(ma1, 2)
ma3 = ta.sma(ma2, 2)
ma4 = ta.sma(ma3, 2)
ma5 = ta.sma(ma4, 2)
ma6 = ta.sma(ma5, 2)
ma7 = ta.sma(ma6, 2)
ma8 = ta.sma(ma7, 2)
ma9 = ta.sma(ma8, 2)
ma10 = ta.sma(ma9, 2)
swingTrd1 = 100 * (source - (ma1 + ma2 + ma3 + ma4 + ma5 + ma6 + ma7 + ma8 + ma9 + ma10) / 10) / (ta.highest(source, swingLength) - ta.lowest(source, swingLength))
swingTrd2 = ta.ema(swingTrd1, swingEmaLength1)
swingTrd3 = ta.ema(swingTrd2, swingEmaLength2)
rmo = ta.ema(swingTrd1, rmoLength)
buySignal = ta.crossover(swingTrd2, swingTrd3)
sellSignal = ta.crossunder(swingTrd2, swingTrd3)
bullTrend = rmo > 0
bearTrend = rmo < 0
impulseUp = swingTrd2 > 0
impulseDown = rmo < 0
[rmo, swingTrd2, swingTrd3, buySignal, sellSignal, bullTrend, bearTrend, impulseUp, impulseDown]
[p_ind_1_rmo, p_ind_1_swingTrd2, p_ind_1_swingTrd3, p_ind_1_buySignal, p_ind_1_sellSignal, p_ind_1_bullTrend, p_ind_1_bearTrend, p_ind_1_impulseUp, p_ind_1_impulseDown] = p_ta_rmo(close, 10, 30, 30, 81) // RMO
hline(0, title="RMO - Zero Line", color=color.new(#787B86, 50))
p_ind_1_rmo_color = p_ind_1_impulseUp ? color.rgb(76, 175, 80, 0) : p_ind_1_impulseDown ? color.rgb(242, 54, 69, 0) : (p_ind_1_bullTrend ? color.rgb(76, 175, 80, 0) : color.rgb(41, 98, 255, 0))
plot(p_ind_1_rmo, title="RMO - RMO", color=p_ind_1_rmo_color, style=plot.style_columns, linewidth=2)
plot(p_ind_1_swingTrd2, title="RMO - Swing Trend 2", color=color.rgb(255, 152, 0, 0), linewidth=1)
plot(p_ind_1_swingTrd3, title="RMO - Swing Trend 3", color=color.rgb(156, 39, 176, 0), linewidth=1)
p_ind_1_rmo_ribbon_color = p_ind_1_bullTrend ? color.rgb(76, 175, 80, 80) : p_ind_1_bearTrend ? color.rgb(242, 54, 69, 80) : color.rgb(41, 98, 255, 80)
bgcolor(p_ind_1_rmo_ribbon_color, title="RMO - Background Ribbon")
Specify a checkable adaptation in Pineify
Provide the Pine Script AI Coding Agent the exact branch diagram, color truth table and zero-range policy you want. Request intermediate Raw and baseline outputs for comparison, then specify bar-close alert behavior separately. Check the generated code and values before adding trading rules.
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.