Relative-strength moving average (RSMA)

q.indicator.rsma smooths an existing relative-strength series with either an exponential or simple moving average. It does not calculate relative strength or fetch a benchmark itself.

Here AAPL relative strength is first measured against SPY, then smoothed with a 21-session exponential average over the latest five shared years.

import pandas as pd

import qrt as q

prices = pd.concat(
    {
        "AAPL": q.data.datasets.load("aapl")["close"],
        "SPY": q.data.datasets.load("spy")["close"],
    },
    axis=1,
    join="inner",
).dropna()
end = prices.index.max()
prices = prices.loc[end - pd.DateOffset(years=5) :]
strength = q.indicator.relative_strength(prices["AAPL"], prices["SPY"], lookback=63)
strength.tail()
datetime
2026-07-13    0.113860
2026-07-14    0.117231
2026-07-15    0.176773
2026-07-16    0.176675
2026-07-17    0.206154
Name: relative_strength, dtype: float64

Calculate the indicator

Use method="exponential" for an EWM with adjust=False, or method="simple" for a rolling arithmetic mean.

window = 21
average = q.indicator.rsma(strength, window=window, method="exponential")
average.tail()
datetime
2026-07-13    0.058788
2026-07-14    0.064101
2026-07-15    0.074344
2026-07-16    0.083647
2026-07-17    0.094784
Name: rsma, dtype: float64

Compare with SPY

Both lines remain benchmark-relative because the input series measures AAPL returns minus SPY returns.

comparison = pd.DataFrame(
    {
        "AAPL relative strength vs SPY": strength.mul(100),
        f"{window}-session RSMA": average.mul(100),
        "Equal performance": 0.0,
    }
)
fig = q.plot.col(
    comparison,
    title="AAPL relative strength and its moving average versus SPY",
    ylabel="Return difference (percentage points)",
)
fig.show(renderer="notebook_connected")
Back to top