Iceberg and absorption detector on individual orders
Individual orders: mark bars where a resting order kept refilling at its price, and bars where a large resting order was hit hard and held. When the chart has no order level data it falls back to the tape, so it still draws.
//@xfscript 1
indicator("Iceberg and Absorption")
let min_refills: float = input.float(3, "minRefills", "Refills for an iceberg", 1, 50, 1)
let min_fill: float = input.float(50, "minFill", "Filled size for absorption", 1, 100000, 1)
let tape_size: float = input.float(150, "tapeSize", "Tape fallback size", 1, 100000, 1)
let bid_color: color = input.color("#22C55E", "bidColor", "Buyers holding")
let ask_color: color = input.color("#EF4444", "askColor", "Sellers holding")
let has_orders: bool = mbo.supported() && mbo.available()
let icebergs: float = mbo.iceberg_count(min_refills)
let big: int = mbo.largest_index()
let big_side: side = mbo.side(big)
let big_price: float = mbo.price(big)
let big_filled: float = mbo.filled(big)
let big_refills: float = mbo.refills(big)
let big_active: bool = mbo.status(big) == "active"
let iceberg_bid: bool = has_orders && icebergs > 0 && big_side == "BUY" && big_refills >= min_refills
let iceberg_ask: bool = has_orders && icebergs > 0 && big_side == "SELL" && big_refills >= min_refills
let held_bid: bool = has_orders && big_active && big_side == "BUY" && big_filled >= min_fill && low >= big_price
let held_ask: bool = has_orders && big_active && big_side == "SELL" && big_filled >= min_fill && high <= big_price
plot.marker(iceberg_bid, big_price, bid_color, "diamond", "below", 10, 2)
plot.marker(iceberg_ask, big_price, ask_color, "diamond", "above", 10, 2)
plot.zone(held_bid, big_price, big_price - chart.tick_size() * 2, bid_color, 0.25, 0, 20, "bullish")
plot.zone(held_ask, big_price + chart.tick_size() * 2, big_price, ask_color, 0.25, 0, 20, "bearish")
let heavy_tape: bool = !has_orders && tape.available() && tape.volume_above(tape_size) > 0
let tape_absorb_bid: bool = heavy_tape && tape.sell_volume_above(tape_size) > tape.buy_volume_above(tape_size) && close >= open
let tape_absorb_ask: bool = heavy_tape && tape.buy_volume_above(tape_size) > tape.sell_volume_above(tape_size) && close <= open
plot.marker(tape_absorb_bid, low, bid_color, "circle", "below", 7, 2)
plot.marker(tape_absorb_ask, high, ask_color, "circle", "above", 7, 2)
plot.histogram(nz(icebergs, 0), bid_color, ask_color)
if has_orders {
plot.label(str.concat("ICEBERGS ", format.compact(icebergs), " BIGGEST ", format.compact(mbo.largest_size())), "#E5E7EB")
} else {
plot.label("ORDER DATA OFF, TAPE ONLY", "#6B7280")
}