mod note:
Day traders use this study to visualize a “synthetic footprint” inside each candle, helping them quickly gauge buying and selling pressure.
By dividing every candle into multiple rows and coloring each block based on an estimated delta (calculated from candle direction and volume), the script mimics volume-at-price without needing real bid/ask data.
This lets traders see whether buyers or sellers were dominant within the candle’s range, helping them spot momentum shifts, absorption, and potential reversals in real time.
Code:
# ===================================================================
# FOOTPRINT STYLE CANDLE (TOS-Compatible Synthetic Footprint)
# Author: Custom for Abhay Devgan
# ===================================================================
declare upper;
# ----------
# Settings
# ----------
input bins = 12; # How many rows inside each candle
input deltaStrength = 1.5; # Sensitivity of delta coloring
# ----------
# Candle Data
# ----------
def hi = high;
def lo = low;
def op = open;
def cl = close;
def vol = volume;
def range = hi - lo;
def step = range / bins;
# ----------
# Delta Approximation
# TOS cannot read bid/ask volume, so:
# Synthetic Delta = Candle Body Size * Volume
# ----------
def delta = (cl - op) * vol;
# Normalize delta for coloring
def deltaNorm = delta / HighestAll(AbsValue(delta));
# ----------
# Footprint Blocks per Level
# ----------
DefineGlobalColor("BuyStrong", Color.GREEN);
DefineGlobalColor("BuyWeak", Color.LIGHT_GREEN);
DefineGlobalColor("SellStrong", Color.RED);
DefineGlobalColor("SellWeak", Color.LIGHT_RED);
# Loop through footprint rows
# We simulate “volume-at-price” by dividing candle volume evenly
def blockVol = vol / bins;
# Plot each footprint row as a bubble box “▉”
# Each row is placed between lo → hi
plot row0 = lo + step * 0;
plot row1 = lo + step * 1;
plot row2 = lo + step * 2;
plot row3 = lo + step * 3;
plot row4 = lo + step * 4;
plot row5 = lo + step * 5;
plot row6 = lo + step * 6;
plot row7 = lo + step * 7;
plot row8 = lo + step * 8;
plot row9 = lo + step * 9;
plot row10 = lo + step * 10;
plot row11 = lo + step * 11;
# ---------------------
# APPLY FOOTPRINT COLORS
# ---------------------
def cBuy = deltaNorm > deltaStrength * 0.1;
def cSell = deltaNorm < -deltaStrength * 0.1;
DefineGlobalColor("Strong", Color.GREEN);
DefineGlobalColor("Weak", Color.LIGHT_GREEN);
AddChartBubble(!IsNaN(row0), row0, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row1), row1, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row2), row2, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row3), row3, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row4), row4, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row5), row5, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row6), row6, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row7), row7, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row8), row8, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row9), row9, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row10), row10, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
AddChartBubble(!IsNaN(row11), row11, "▉",
if deltaNorm > 0.5 then GlobalColor("BuyStrong")
else if deltaNorm > 0 then GlobalColor("BuyWeak")
else if deltaNorm < -0.5 then GlobalColor("SellStrong")
else GlobalColor("SellWeak"),
no);
# ----------
# Labels
# ----------
AddLabel(yes, "Synthetic Delta: " + Round(delta, 0),
if delta > 0 then Color.GREEN else Color.RED);
AddLabel(yes, "Volume: " + vol, Color.WHITE);
Last edited by a moderator: