BUBLE BOBLE

Description

VOLUME ON THE CHART CANDLES> MORE TO COME!

Categories & Tags

Comments (0)

0/2000

Loading comments…

Source code

function calculate(bars, ctx) {
  // ===== Inputs =====
  const sizeScale = ctx.input('Bubble Size Scale', 3, { min: 0.5, max: 10, step: 0.5 });
  const minVolume = ctx.input('Min Volume to Show', 0, { min: 0, max: 10000, step: 1 });
  const maxBubbles = ctx.input('Max Bubbles', 200, { min: 10, max: 1000, step: 10 });
  const lookback = ctx.input('Lookback Bars', 500, { min: 50, max: 5000, step: 50 });

  // ===== Check footprint data =====
  if (!ctx.footprint.available) {
    ctx.label(bars.length - 1, bars[bars.length - 1].high, 'Waiting for tick data...', {
      color: '#ff9800', textColor: '#fff', size: 12
    });
    return;
  }

  const startIdx = Math.max(0, bars.length - lookback);

  // ===== Collect total volumes for global scaling =====
  const volumes = [];
  let maxTotalVol = 0;

  for (let i = startIdx; i < bars.length; i++) {
    const fp = ctx.footprint.bar(i);
    if (!fp) continue;
    const buyVol = fp.askVolume || 0;
    const sellVol = fp.bidVolume || 0;
    const totalVol = buyVol + sellVol;
    if (totalVol > maxTotalVol) maxTotalVol = totalVol;
    volumes.push({ barIdx: i, buyVol, sellVol, totalVol });
  }

  if (maxTotalVol === 0) return;

  // ===== Filter and draw bubbles =====
  let drawn = 0;
  for (const v of volumes) {
    if (drawn >= maxBubbles) break;
    if (v.totalVol < minVolume) continue;

    const isBuy = v.buyVol >= v.sellVol;
    const color = isBuy ? '#2196f3' : '#4caf50';
    const volRatio = v.totalVol / maxTotalVol;
    const bubbleSize = Math.max(4, volRatio * sizeScale * 20);

    ctx.shape(v.barIdx, 'circle', {
      color: color,
      position: 'below',
      size: bubbleSize,
      text: Math.round(v.totalVol).toString()
    });
    drawn++;
  }

  // ===== Legend label =====
  const last = bars.length - 1;
  ctx.label(last, bars[last].low - (bars[last].high - bars[last].low) * 0.5,
    '● Buy  ● Sell  |  Size=Volume  |  Showing ' + drawn + ' bars', {
    color: 'rgba(0,0,0,0.5)', textColor: '#787b86', size: 10
  });
}