Market Memory Levels for ThinkorSwim

chewie76

Well-known member
VIP
VIP Enthusiast

Market Memory Levels​

A Higher-Timeframe Volume Acceptance Map for Identifying Historical Areas of Market Interest.

Market Memory Levels is a higher-timeframe volume distribution indicator designed to identify price areas where the market has historically spent the greatest amount of time and volume. Rather than attempting to predict future price action, it highlights the levels that the market itself has repeatedly recognized as important.

Change the timeframe in settings based on your trading timeframe. WEEKLY is by default. If you're trading on a 30 minute or less chart, use DAILY. If you're trading on a daily chart, use MONTHLY.

The indicator builds a rolling volume profile within a selected higher timeframe (such as a week) and converts those areas of concentrated participation into horizontal "memory levels." These levels often act as natural support and resistance because they represent prices where buyers and sellers previously found agreement. The colors of the levels indicate strength of the retest. Red is a weak pullback, yellow is an average pullback, green is strong and cyan is an extreme pullback.

Key Observations​

  • High-volume areas tend to attract future price action. Markets frequently revisit these levels before deciding on the next directional move.
  • Strong trends often pause or consolidate near Market Memory Levels. What appears to be random hesitation is often the market interacting with a prior area of heavy participation.
  • The most significant levels often become magnets. Price may accelerate toward them from a distance, then either reject sharply or consolidate before continuing.
  • Memory Levels are dynamic. As each higher timeframe period develops, the distribution evolves, allowing new areas of market acceptance to emerge while older structures gradually lose relevance.
  • The indicator works best as a context tool rather than a standalone signal generator. Combining Market Memory Levels with trend analysis, price action, or momentum studies can help identify higher-probability trading opportunities.
Unlike traditional support and resistance that rely on swing highs and lows, Market Memory Levels are derived from where the market actually conducted business. The result is a visual map of historical market acceptance that can provide valuable insight into where future reactions are most likely to occur. Sometimes price will smash below the levels capture some liquidity and rip higher. This happened twice in the below picture where there is a <. Below picture is /NQ on the 1 hour chart.

1780874151158.png


CODE:
Code:
#========================
# Market_Memory_Levels
# Created by Chewie 6/7/2026
#========================

declare upper;

#========================
# INPUTS
#========================

input Aggregation = {default Weekly, Daily, Monthly};
input ATRLength = 100;
input ATRMultiplier = 0.25;
input LookbackBars = 200;

#========================
# HTF PERIOD
#========================

def newPeriod =
    if Aggregation == Aggregation.Weekly then GetWeek() <> GetWeek()[1]
    else if Aggregation == Aggregation.Daily then GetDay() <> GetDay()[1]
    else GetMonth() <> GetMonth()[1];

#========================
# FIXED HTF RANGE
#========================

rec hi =
    if newPeriod then high
    else Max(high, hi[1]);

rec lo =
    if newPeriod then low
    else Min(low, lo[1]);

def range = hi - lo;


#========================
# ATR BIN SIZE
#========================

def atr = Average(TrueRange(high, close, low), ATRLength);
def bin = Max(atr * ATRMultiplier, TickSize());

#========================
# PRE-COMPUTE BIN LEVELS
#========================

def b1l = lo;
def b1h = b1l + bin;
def b2l = b1h;
def b2h = b2l + bin;
def b3l = b2h;
def b3h = b3l + bin;
def b4l = b3h;
def b4h = b4l + bin;
def b5l = b4h;
def b5h = b5l + bin;

#========================
# RAW VOLUME (ISOLATED DEFINITIONS)
#========================

def v1 =
fold i1 = 0 to LookbackBars
with a1 = 0
do a1 + (if close[i1] >= b1l and close[i1] < b1h then volume[i1] else 0);

def v2 =
fold i2 = 0 to LookbackBars
with a2 = 0
do a2 + (if close[i2] >= b2l and close[i2] < b2h then volume[i2] else 0);

def v3 =
fold i3 = 0 to LookbackBars
with a3 = 0
do a3 + (if close[i3] >= b3l and close[i3] < b3h then volume[i3] else 0);

def v4 =
fold i4 = 0 to LookbackBars
with a4 = 0
do a4 + (if close[i4] >= b4l and close[i4] < b4h then volume[i4] else 0);

def v5 =
fold i5 = 0 to LookbackBars
with a5 = 0
do a5 + (if close[i5] >= b5l and close[i5] < b5h then volume[i5] else 0);

#========================
# MAX VOLUME (SAFE REDUCTION)
#========================

def maxV1 = Max(v1, v2);
def maxV2 = Max(v3, v4);
def maxV3 = Max(maxV1, maxV2);
def maxVol = Max(maxV3, v5);

#========================
# NORMALIZED SCORES
#========================

def p1 = if maxVol > 0 then v1 / maxVol else 0;
def p2 = if maxVol > 0 then v2 / maxVol else 0;
def p3 = if maxVol > 0 then v3 / maxVol else 0;
def p4 = if maxVol > 0 then v4 / maxVol else 0;
def p5 = if maxVol > 0 then v5 / maxVol else 0;

#========================
# VISUAL OUTPUT
#========================

plot L1 = if p1 > 0.6 then (b1h + b1l) / 2 else Double.NaN;
L1.SetPaintingStrategy(PaintingStrategy.POINTS);
L1.SetDefaultColor(Color.YELLOW);

plot L2 = if p2 > 0.6 then (b2h + b2l) / 2 else Double.NaN;
L2.SetPaintingStrategy(PaintingStrategy.POINTS);
L2.SetDefaultColor(Color.CYAN);

plot L3 = if p3 > 0.6 then (b3h + b3l) / 2 else Double.NaN;
L3.SetPaintingStrategy(PaintingStrategy.POINTS);
L3.SetDefaultColor(Color.GREEN);

#========================================================
# PART 2 — HEATMAP LAYERS
#========================================================

input showHeatmap = yes;

#========================
# COLORS
#========================

DefineGlobalColor("Low", Color.BLUE);
DefineGlobalColor("Mid", Color.CYAN);
DefineGlobalColor("High", Color.YELLOW);
DefineGlobalColor("Extreme", Color.RED);

#========================================================
# BIN 1
#========================================================

AddCloud(
if showHeatmap and p1 > 0.25 then b1h else Double.NaN,
if showHeatmap and p1 > 0.25 then b1l else Double.NaN,
GlobalColor("Low"),
GlobalColor("Low"));

#========================================================
# BIN 2
#========================================================

AddCloud(
if showHeatmap and p2 > 0.30 then b2h else Double.NaN,
if showHeatmap and p2 > 0.30 then b2l else Double.NaN,
GlobalColor("Low"),
GlobalColor("Mid"));

#========================================================
# BIN 3
#========================================================

AddCloud(
if showHeatmap and p3 > 0.40 then b3h else Double.NaN,
if showHeatmap and p3 > 0.40 then b3l else Double.NaN,
GlobalColor("Mid"),
GlobalColor("Mid"));

#========================================================
# BIN 4
#========================================================

AddCloud(
if showHeatmap and p4 > 0.50 then b4h else Double.NaN,
if showHeatmap and p4 > 0.50 then b4l else Double.NaN,
GlobalColor("Mid"),
GlobalColor("High"));

#========================================================
# BIN 5
#========================================================

AddCloud(
if showHeatmap and p5 > 0.60 then b5h else Double.NaN,
if showHeatmap and p5 > 0.60 then b5l else Double.NaN,
GlobalColor("High"),
GlobalColor("High"));

#========================================================
# EXTENSION BIN 6
#========================================================

def b6l = b5h;
def b6h = b6l + bin;
def v6 =
fold i6 = 0 to LookbackBars
with a6 = 0
do a6 + (if close[i6] >= b6l and close[i6] < b6h then volume[i6] else 0);
def p6 = if maxVol > 0 then v6 / maxVol else 0;

AddCloud(
if showHeatmap and p6 > 0.55 then b6h else Double.NaN,
if showHeatmap and p6 > 0.55 then b6l else Double.NaN,
GlobalColor("High"),
GlobalColor("Extreme"));

#========================================================
# EXTENSION BIN 7
#========================================================

def b7l = b6h;
def b7h = b7l + bin;
def v7 =
fold i7 = 0 to LookbackBars
with a7 = 0
do a7 + (if close[i7] >= b7l and close[i7] < b7h then volume[i7] else 0);
def p7 = if maxVol > 0 then v7 / maxVol else 0;

AddCloud(
if showHeatmap and p7 > 0.65 then b7h else Double.NaN,
if showHeatmap and p7 > 0.65 then b7l else Double.NaN,
GlobalColor("Extreme"),
GlobalColor("Extreme"));

#========================================================
# PART 3 — LIQUIDITY LEVELS ENGINE
#========================================================

input showLevels = yes;
input levelStrength = 0.65;

#========================
# STRENGTH CONDITIONS
#========================

def st1 = p1 > levelStrength;
def st2 = p2 > levelStrength;
def st3 = p3 > levelStrength;
def st4 = p4 > levelStrength;
def st5 = p5 > levelStrength;
def st6 = p6 > levelStrength;
def st7 = p7 > levelStrength;

#========================
# LEVEL MIDPOINTS
#========================

def mid1 = (b1h + b1l) / 2;
def mid2 = (b2h + b2l) / 2;
def mid3 = (b3h + b3l) / 2;
def mid4 = (b4h + b4l) / 2;
def mid5 = (b5h + b5l) / 2;
def mid6 = (b6h + b6l) / 2;
def mid7 = (b7h + b7l) / 2;

#========================
# BREAK CONDITIONS
#========================

def br1 = close < mid1;
def br2 = close < mid2;
def br3 = close < mid3;
def br4 = close < mid4;
def br5 = close < mid5;
def br6 = close < mid6;
def br7 = close < mid7;

#========================
# PERSISTENT LEVELS
#========================

rec lvlA1 =
if newPeriod then Double.NaN
else if st1 and !br1 then mid1
else if br1 then Double.NaN
else lvlA1[1];

rec lvlA2 =
if newPeriod then Double.NaN
else if st2 and !br2 then mid2
else if br2 then Double.NaN
else lvlA2[1];

rec lvlA3 =
if newPeriod then Double.NaN
else if st3 and !br3 then mid3
else if br3 then Double.NaN
else lvlA3[1];

rec lvlA4 =
if newPeriod then Double.NaN
else if st4 and !br4 then mid4
else if br4 then Double.NaN
else lvlA4[1];

rec lvlA5 =
if newPeriod then Double.NaN
else if st5 and !br5 then mid5
else if br5 then Double.NaN
else lvlA5[1];

rec lvlA6 =
if newPeriod then Double.NaN
else if st6 and !br6 then mid6
else if br6 then Double.NaN
else lvlA6[1];

rec lvlA7 =
if newPeriod then Double.NaN
else if st7 and !br7 then mid7
else if br7 then Double.NaN
else lvlA7[1];

#========================
# PLOTS
#========================

plot Liquidity_A1 =
if showLevels then lvlA1 else Double.NaN;
Liquidity_A1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Liquidity_A1.SetDefaultColor(Color.YELLOW);
Liquidity_A1.SetLineWeight(2);

plot Liquidity_A2 =
if showLevels then lvlA2 else Double.NaN;
Liquidity_A2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Liquidity_A2.SetDefaultColor(Color.CYAN);
Liquidity_A2.SetLineWeight(2);

plot Liquidity_A3 =
if showLevels then lvlA3 else Double.NaN;
Liquidity_A3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Liquidity_A3.SetDefaultColor(Color.GREEN);
Liquidity_A3.SetLineWeight(2);

plot Liquidity_A4 =
if showLevels then lvlA4 else Double.NaN;
Liquidity_A4.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Liquidity_A4.SetDefaultColor(Color.BLUE);

Liquidity_A4.SetLineWeight(2);

plot Liquidity_A5 =
if showLevels then lvlA5 else Double.NaN;
Liquidity_A5.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Liquidity_A5.SetLineWeight(2);
Liquidity_A5.SetDefaultColor(Color.GRAY);

plot Liquidity_A6 =
if showLevels then lvlA6 else Double.NaN;
Liquidity_A6.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Liquidity_A6.SetDefaultColor(Color.MAGENTA);
Liquidity_A6.SetLineWeight(2);

plot Liquidity_A7 =
if showLevels then lvlA7 else Double.NaN;
Liquidity_A7.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Liquidity_A7.SetDefaultColor(Color.RED);
Liquidity_A7.SetLineWeight(2);

#========================================================
# PART 4 — FILTERED LIQUIDITY EVENTS
#========================================================

input showSignals = yes;
input minStrength = 0.70;

#========================
# ONLY HIGH-QUALITY LEVELS
#========================

def strongZone =
    (p1 > minStrength or
     p2 > minStrength or
     p3 > minStrength or
     p4 > minStrength or
     p5 > minStrength or
     p6 > minStrength or
     p7 > minStrength);


#========================
# TRUE MAX LIQUIDITY SELECTION
#========================

def maxP = Max(p1,
           Max(p2,
           Max(p3,
           Max(p4,
          Max(p5,
           Max(p6, p7))))));#
def keyLevel =
if p1 == maxP then mid1
else if p2 == maxP then mid2
else if p3 == maxP then mid3
else if p4 == maxP then mid4
else if p5 == maxP then mid5
else if p6 == maxP then mid6
else mid7;


#========================
# SWEEP ONLY AT KEY LEVEL
#========================

def sweepUp =
high > keyLevel and close < keyLevel;

def sweepDown =
low < keyLevel and close > keyLevel;

#========================
# CONFIRMATION FILTER
# must be at strong zone
#========================

def validSweepUp = sweepUp and strongZone;
def validSweepDown = sweepDown and strongZone;

#========================
# SINGLE CLEAN SIGNAL PLOTS
#========================

plot SellSignal =
if showSignals and validSweepUp then high else Double.NaN;
SellSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
SellSignal.SetDefaultColor(Color.RED);
SellSignal.SetLineWeight(3);

plot BuySignal =
if showSignals and validSweepDown then low else Double.NaN;
BuySignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BuySignal.SetDefaultColor(Color.GREEN);
BuySignal.SetLineWeight(3);

#========================
# OPTIONAL: ALERT FILTER
#========================

def signal =
validSweepUp or validSweepDown;

Alert(signal, "Liquidity Sweep at Key Level", Alert.BAR, Sound.Ding);


input showPOC = yes;
input pocLineWeight = 4;

#========================================================
# PART 5 - DOMINANT LIQUIDITY NODE
#========================================================

def maxP1 =
Max(p1,
Max(p2,
Max(p3,
Max(p4,
Max(p5,
Max(p6, p7))))));

def POC =
if p1 == maxP1 then mid1
else if p2 == maxP1 then mid2
else if p3 == maxP1 then mid3
else if p4 == maxP1 then mid4
else if p5 == maxP1 then mid5
else if p6 == maxP1 then mid6
else mid7;

plot PointOfControl =
if showPOC then POC else Double.NaN;

PointOfControl.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
PointOfControl.SetDefaultColor(Color.WHITE);
PointOfControl.SetLineWeight(pocLineWeight);

Here is a picture of a one minute chart. Notice the arrows where price breaks down. These could be good areas to short on a continued downtrend.

1780876011342.png


Here is a 5 min. chart of /GC. Price uses the levels as support until it breaks much lower.

1780876214973.png
 
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
1903 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