Original indicator Concept: https://www.tradingview.com/script/0O1X4gMd-Market-Memory-Average-Zeiierman/
At its core, Market Memory Average (MMA) is trying to answer one question:
1.
Market Memory (Similarity Engine)
Instead of just using RSI or moving averages, this model:
Think of it like:
2.
This is the final “memory-adjusted price.”
It is NOT a moving average.
It is:
So:
Upper Chart:
Lower Indicator:
What This Indicator Actually Is
At its core, Market Memory Average (MMA) is trying to answer one question:
“What has price done in similar conditions in the past, and what is it likely to do now?”
1.
Instead of just using RSI or moving averages, this model:
- Looks at past market states (11–30 bars ago)
- Compares them to the current market using:
- 1-bar, 3-bar, and 5-bar momentum (ROC)
- RSI level
- Volatility (ATR)
- Relative volume
- Scores how similar each past moment is (sim1–sim5)
- Weights their future outcome (roc5[x])
- Produces a probabilistic expectation of forward movement
“When the market looked like THIS before, what happened next?”
2.
Market Memory Average Line
This is the final “memory-adjusted price.”It is NOT a moving average.
It is:
Price adjusted by expected future behavior derived from historical similarity
So:
- Above = bullish regime expectation
- Below = bearish regime expectation
- Flat = indecision / transition
Upper Chart:
Code:
# Market_Memory_Average
# Original Concept by Zeiierman
# Modified with target bands and simplified version
# Assembled by Chewie 5/11/2026
#====================================================
# INPUTS
#====================================================
input colorbar = yes;
input sensitivity = 1.5;
input rsiLength = 14;
input atrLength = 14;
input volLength = 20;
input smartSmoothLength = 50;
input smartTrendLength = 20;
input showCloud = yes;
input cloudSpread = 1.5;
#====================================================
# FEATURE CALCULATIONS
#====================================================
def roc1 = ((close / close[1]) - 1) * 100;
def roc3 = ((close / close[3]) - 1) * 100;
def roc5 = ((close / close[5]) - 1) * 100;
def rsiVal = RSI(length = rsiLength) / 100;
def atrVal = ATR(length = atrLength) / close * 100;
def volMA = Average(volume, volLength);
def volRel = if volMA != 0 then volume / volMA else 1;
#====================================================
# SIMILARITY ENGINE
#====================================================
# ----- MATCH 1 -----
def d1_1 = AbsValue(roc1 - roc1[11]) / 2;
def d2_1 = AbsValue(roc3 - roc3[11]) / 4;
def d3_1 = AbsValue(roc5 - roc5[11]) / 6;
def d4_1 = AbsValue(rsiVal - rsiVal[11]) * 2;
def d5_1 = AbsValue(atrVal - atrVal[11]) / 2;
def d6_1 = AbsValue(volRel - volRel[11]) / 1.5;
def dist1 = d1_1 + d2_1 + d3_1 + d4_1 + d5_1 + d6_1;
def sim1 = 100 * Exp(-dist1 * sensitivity);
def wm1 = roc5[11] * sim1;
# ----- MATCH 2 -----
def d1_2 = AbsValue(roc1 - roc1[15]) / 2;
def d2_2 = AbsValue(roc3 - roc3[15]) / 4;
def d3_2 = AbsValue(roc5 - roc5[15]) / 6;
def d4_2 = AbsValue(rsiVal - rsiVal[15]) * 2;
def d5_2 = AbsValue(atrVal - atrVal[15]) / 2;
def d6_2 = AbsValue(volRel - volRel[15]) / 1.5;
def dist2 = d1_2 + d2_2 + d3_2 + d4_2 + d5_2 + d6_2;
def sim2 = 100 * Exp(-dist2 * sensitivity);
def wm2 = roc5[15] * sim2;
# ----- MATCH 3 -----
def d1_3 = AbsValue(roc1 - roc1[20]) / 2;
def d2_3 = AbsValue(roc3 - roc3[20]) / 4;
def d3_3 = AbsValue(roc5 - roc5[20]) / 6;
def d4_3 = AbsValue(rsiVal - rsiVal[20]) * 2;
def d5_3 = AbsValue(atrVal - atrVal[20]) / 2;
def d6_3 = AbsValue(volRel - volRel[20]) / 1.5;
def dist3 = d1_3 + d2_3 + d3_3 + d4_3 + d5_3 + d6_3;
def sim3 = 100 * Exp(-dist3 * sensitivity);
def wm3 = roc5[20] * sim3;
# ----- MATCH 4 -----
def d1_4 = AbsValue(roc1 - roc1[25]) / 2;
def d2_4 = AbsValue(roc3 - roc3[25]) / 4;
def d3_4 = AbsValue(roc5 - roc5[25]) / 6;
def d4_4 = AbsValue(rsiVal - rsiVal[25]) * 2;
def d5_4 = AbsValue(atrVal - atrVal[25]) / 2;
def d6_4 = AbsValue(volRel - volRel[25]) / 1.5;
def dist4 = d1_4 + d2_4 + d3_4 + d4_4 + d5_4 + d6_4;
def sim4 = 100 * Exp(-dist4 * sensitivity);
def wm4 = roc5[25] * sim4;
# ----- MATCH 5 -----
def d1_5 = AbsValue(roc1 - roc1[30]) / 2;
def d2_5 = AbsValue(roc3 - roc3[30]) / 4;
def d3_5 = AbsValue(roc5 - roc5[30]) / 6;
def d4_5 = AbsValue(rsiVal - rsiVal[30]) * 2;
def d5_5 = AbsValue(atrVal - atrVal[30]) / 2;
def d6_5 = AbsValue(volRel - volRel[30]) / 1.5;
def dist5 = d1_5 + d2_5 + d3_5 + d4_5 + d5_5 + d6_5;
def sim5 = 100 * Exp(-dist5 * sensitivity);
def wm5 = roc5[30] * sim5;
#====================================================
# WEIGHTED MOMENTUM
#====================================================
def totalWeightedMomentum = wm1 + wm2 + wm3 + wm4 + wm5;
def totalWeight = sim1 + sim2 + sim3 + sim4 + sim5;
def avgWeightedMomentum =
if totalWeight != 0
then totalWeightedMomentum / totalWeight
else 0;
#====================================================
# MARKET MEMORY AVERAGE
#====================================================
def rawLine = close * (1 + avgWeightedMomentum / 100);
plot MarketMemoryAverage =
ExpAverage(rawLine, smartSmoothLength);
#====================================================
# TREND
#====================================================
def smartSlope =
MarketMemoryAverage -
MarketMemoryAverage[smartTrendLength];
def isBull = smartSlope > 0;
def isBear = smartSlope < 0;
# Prevent neutral/white transition flashes
MarketMemoryAverage.AssignValueColor(
if isBull then Color.GREEN
else if isBear then Color.RED
else Color.CURRENT
);
MarketMemoryAverage.SetLineWeight(3);
#====================================================
# CLOUD GEOMETRY
#====================================================
def cloudRef =
MarketMemoryAverage +
ATR(length = atrLength) * cloudSpread *
(if isBull then -1
else if isBear then 1
else 0);
def cloudA =
MarketMemoryAverage +
(cloudRef - MarketMemoryAverage) * 0.25;
def cloudB =
MarketMemoryAverage +
(cloudRef - MarketMemoryAverage) * 0.50;
def cloudC =
MarketMemoryAverage +
(cloudRef - MarketMemoryAverage) * 0.75;
#====================================================
# TARGET BANDS
#====================================================
plot XUP =
MarketMemoryAverage +
ATR(length = atrLength) * cloudSpread * 1.38;
plot XUP2 =
MarketMemoryAverage +
ATR(length = atrLength) * cloudSpread * 2.5;
XUP.SetDefaultColor(Color.magenta);
XUP2.SetDefaultColor(Color.magenta);
plot XDN =
MarketMemoryAverage -
ATR(length = atrLength) * cloudSpread * 1.38;
plot XDN2 =
MarketMemoryAverage -
ATR(length = atrLength) * cloudSpread * 2.5;
XDN.SetDefaultColor(Color.CYAN);
XDN2.SetDefaultColor(Color.CYAN);
AddCloud(XUP, XUP2, createColor(200,0,150), createColor(200,0,150));
AddCloud(XDN, XDN2, createColor(0,130,170), createColor(0,130,170));
# =========================
# PRICE COLOR
# =========================
AssignPriceColor(
if !Colorbar then Color.CURRENT
else if high > XUP2 then Color.MAGENTA
else if low < XDN2 then Color.CYAN
else if close > marketmemoryaverage then Color.GREEN
else if close < marketmemoryaverage then Color.RED
else Color.YELLOW);
#====================================================
# BULLISH CLOUD
#====================================================
plot BullLine =
if isBull and showCloud
then MarketMemoryAverage
else Double.NaN;
plot BullA =
if isBull and showCloud
then cloudA
else Double.NaN;
plot BullB =
if isBull and showCloud
then cloudB
else Double.NaN;
plot BullC =
if isBull and showCloud
then cloudC
else Double.NaN;
plot BullRef =
if isBull and showCloud
then cloudRef
else Double.NaN;
BullA.SetDefaultColor(createColor(0,210,0)); BullA.HideTitle(); BullA.HideBubble();
BullB.SetDefaultColor(createColor(0,180,0)); BullB.HideTitle(); BullB.HideBubble();
BullC.SetDefaultColor(createColor(0,150,0)); BullC.HideTitle(); BullC.HideBubble();
BullRef.SetDefaultColor(createColor(0,100,0)); BullRef.HideTitle(); BullRef.HideBubble();
AddCloud(BullLine, BullA,
Color.GREEN, Color.GREEN);
AddCloud(BullA, BullB,
CreateColor(0,200,0),
CreateColor(0,200,0));
AddCloud(BullB, BullC,
CreateColor(0,150,0),
CreateColor(0,150,0));
AddCloud(BullC, BullRef,
CreateColor(0,100,0),
CreateColor(0,100,0));
#====================================================
# BEARISH CLOUD
#====================================================
plot BearLine =
if isBear and showCloud
then MarketMemoryAverage
else Double.NaN;
plot BearA =
if isBear and showCloud
then cloudA
else Double.NaN;
plot BearB =
if isBear and showCloud
then cloudB
else Double.NaN;
plot BearC =
if isBear and showCloud
then cloudC
else Double.NaN;
plot BearRef =
if isBear and showCloud
then cloudRef
else Double.NaN;
BearA.SetDefaultColor(createColor(210,0,0)); BearA.HideTitle(); BearA.HideBubble();
BearB.SetDefaultColor(createColor(180,0,0)); BearB.HideTitle(); BearB.HideBubble();
BearC.SetDefaultColor(createColor(150,0,0)); BearC.HideTitle(); BearC.HideBubble();
BearRef.SetDefaultColor(createColor(100,0,0)); BearRef.HideTitle(); BearRef.HideBubble();
AddCloud(BearLine, BearA,
Color.RED, Color.RED);
AddCloud(BearA, BearB,
CreateColor(200,0,0),
CreateColor(200,0,0));
AddCloud(BearB, BearC,
CreateColor(150,0,0),
CreateColor(150,0,0));
AddCloud(BearC, BearRef,
CreateColor(100,0,0),
CreateColor(100,0,0));
#====================================================
# LABEL
#====================================================
AddLabel(
yes,
if isBull then "Memory Bullish"
else if isBear then "Memory Bearish"
else "Memory Neutral",
if isBull then Color.GREEN
else if isBear then Color.RED
else Color.CYAN
);
Lower Indicator:
Code:
# Market Memory Oscillator – Lower
# Assembled by Chewie 5/11/2006
#====================================================
# INPUTS
#====================================================
declare lower;
input sensitivity = 1.5;
input rsiLength = 14;
input atrLength = 14;
input volLength = 20;
input smartSmoothLength = 50;
input smartTrendLength = 20;
input cloudSpread = 1.5;
input showBands = yes;
#====================================================
# FEATURE CALCULATIONS
#====================================================
def roc1 = ((close / close[1]) - 1) * 100;
def roc3 = ((close / close[3]) - 1) * 100;
def roc5 = ((close / close[5]) - 1) * 100;
def rsiVal = RSI(length = rsiLength) / 100;
def atrVal = ATR(length = atrLength) / close * 100;
def volMA = Average(volume, volLength);
def volRel = if volMA != 0 then volume / volMA else 1;
#====================================================
# SIMILARITY ENGINE
#====================================================
def dist1 = AbsValue(roc1 - roc1[11]) / 2 +
AbsValue(roc3 - roc3[11]) / 4 +
AbsValue(roc5 - roc5[11]) / 6 +
AbsValue(rsiVal - rsiVal[11]) * 2 +
AbsValue(atrVal - atrVal[11]) / 2 +
AbsValue(volRel - volRel[11]) / 1.5;
def sim1 = 100 * Exp(-dist1 * sensitivity);
def wm1 = roc5[11] * sim1;
def dist2 = AbsValue(roc1 - roc1[15]) / 2 +
AbsValue(roc3 - roc3[15]) / 4 +
AbsValue(roc5 - roc5[15]) / 6 +
AbsValue(rsiVal - rsiVal[15]) * 2 +
AbsValue(atrVal - atrVal[15]) / 2 +
AbsValue(volRel - volRel[15]) / 1.5;
def sim2 = 100 * Exp(-dist2 * sensitivity);
def wm2 = roc5[15] * sim2;
def dist3 = AbsValue(roc1 - roc1[20]) / 2 +
AbsValue(roc3 - roc3[20]) / 4 +
AbsValue(roc5 - roc5[20]) / 6 +
AbsValue(rsiVal - rsiVal[20]) * 2 +
AbsValue(atrVal - atrVal[20]) / 2 +
AbsValue(volRel - volRel[20]) / 1.5;
def sim3 = 100 * Exp(-dist3 * sensitivity);
def wm3 = roc5[20] * sim3;
def dist4 = AbsValue(roc1 - roc1[25]) / 2 +
AbsValue(roc3 - roc3[25]) / 4 +
AbsValue(roc5 - roc5[25]) / 6 +
AbsValue(rsiVal - rsiVal[25]) * 2 +
AbsValue(atrVal - atrVal[25]) / 2 +
AbsValue(volRel - volRel[25]) / 1.5;
def sim4 = 100 * Exp(-dist4 * sensitivity);
def wm4 = roc5[25] * sim4;
def dist5 = AbsValue(roc1 - roc1[30]) / 2 +
AbsValue(roc3 - roc3[30]) / 4 +
AbsValue(roc5 - roc5[30]) / 6 +
AbsValue(rsiVal - rsiVal[30]) * 2 +
AbsValue(atrVal - atrVal[30]) / 2 +
AbsValue(volRel - volRel[30]) / 1.5;
def sim5 = 100 * Exp(-dist5 * sensitivity);
def wm5 = roc5[30] * sim5;
#====================================================
# MMA (replicated)
#====================================================
def totalWeight = sim1 + sim2 + sim3 + sim4 + sim5;
def avgWeightedMomentum = if totalWeight != 0
then (wm1 + wm2 + wm3 + wm4 + wm5) / totalWeight
else 0;
def rawLine = close * (1 + avgWeightedMomentum / 100);
def MMA = ExpAverage(rawLine, smartSmoothLength);
def smartSlope = MMA - MMA[smartTrendLength];
def isBull = smartSlope > 0;
def isBear = smartSlope < 0;
#====================================================
# NORMALIZED OSCILLATOR
# Units: multiples of (ATR * cloudSpread)
# Zero = MMA
# ±1.38 = inner band crossing
# ±2.5 = outer band crossing
#====================================================
def atrAbs = ATR(length = atrLength);
def unit = if atrAbs * cloudSpread != 0
then atrAbs * cloudSpread
else 1;
plot Osc = (close - MMA) / unit;
Osc.setdefaultColor(color.white);
Osc.SetLineWeight(2);
Osc.HideBubble();
#====================================================
# ZERO LINE
#====================================================
plot ZeroLine = 0;
Zeroline.AssignValueColor(
if isBull then Color.GREEN
else if isBear then Color.RED
else Color.GRAY);
ZeroLine.SetLineWeight(4);
Zeroline.HideBubble();
#====================================================
# HORIZONTAL BAND LEVELS (true constants)
#====================================================
plot BandUp1 = if showBands then 1.38 else Double.NaN;
plot BandUp2 = if showBands then 2.5 else Double.NaN;
plot BandDn1 = if showBands then -1.38 else Double.NaN;
plot BandDn2 = if showBands then -2.5 else Double.NaN;
BandUp1.SetDefaultColor(Color.MAGENTA);
BandUp1.SetLineWeight(1);
BandUp1.HideBubble();
BandUp2.SetDefaultColor(Color.MAGENTA);
BandUp2.SetLineWeight(1);
BandUp2.HideBubble();
BandDn1.SetDefaultColor(Color.CYAN);
BandDn1.SetLineWeight(1);
BandDn1.HideBubble();
BandDn2.SetDefaultColor(Color.CYAN);
BandDn2.SetLineWeight(1);
BandDn2.HideBubble();
AddCloud(BandUp1, BandUp2, CreateColor(200, 0, 150), CreateColor(200, 0, 150));
AddCloud(BandDn1, BandDn2, CreateColor(0, 130, 170), CreateColor(0, 130, 170));
Last edited: