Market Memory Average (Zeiierman) for ThinkOrSwim [Upper and Lower]

chewie76

Well-known member
VIP
VIP Enthusiast
Original indicator Concept: https://www.tradingview.com/script/0O1X4gMd-Market-Memory-Average-Zeiierman/

🧠 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. 🧩 Market Memory (Similarity Engine)

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
Then it:
  • Scores how similar each past moment is (sim1–sim5)
  • Weights their future outcome (roc5[x])
  • Produces a probabilistic expectation of forward movement
👉 Think of it like:

“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
Here is the QQQ on the 4 hour chart.

1778546466394.png

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:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
1267 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top