Institutional Order Block

I’m wondering if anyone knows if there’s an institutional order block indicator? I’ve been searching through the custom indicators section and don’t see any. If someone could point me in the right direction I would greatly appreciate it.

just create this script its not perfect, but will get you on your way.

const predef = require("./tools/predef");
const SMA = require("./tools/SMA");
const { px, du, op, min } = require("./tools/graphics");

function find_order_block(xs, t, ob_period) {
  let order_blocks = [];
  for (let i = 0; i < xs.length - 1; ++i) {}

  return order_blocks;
}

function find_local_extrema(xs, t) {
  let extrema = [];
  // iterate through all points and compare direct neighbors
  for (let i = 1; i < xs.length - 1; ++i) {
    if (t == undefined || t == "p") {
      // peaks
      if (xs[i] > xs[i - 1] && xs[i] > xs[i + 1]) {
        extrema.push(i);
      }
    } else {
      // throughs
      if (xs[i] < xs[i - 1] && xs[i] < xs[i + 1]) {
        extrema.push(i);
      }
    }
  }

  return extrema;
}

function mapZ(d){
    return {
     index: d.index(),
      open : d.open(),
      close : d.close(),
      high : d.high(),
      low : d.low()
    };
}

function resample(xs, t) {
  let data = [];
  // iterate through all points and compare direct neighbors
  let z=0;
  d = mapZ(xs[0]);
  for (let i = 1; i < xs.length; i++) {
    let v = mapZ(xs[i]);
    if (i > 0 && i % t == 0){
       data.push(d);
       d = v;
       continue;
    }
    
    d.close = v.close;
    if(v.high > d.high) {
        d.high=v.high;
    }
    
     if(v.low < d.low) {
        d.low=v.low;
    }
    
    
  }

  return data;
}

class order_block {
  init() {
    this.candle_count = 5; // this.props.period; // Relevant Periods to identify OB
    this.threshold = 0.0; // Min. Percent move to identify OB", step = 0.1)
    this.usewicks = false;
    this.showbull = true;
    this.showbear = true;
    this.ob_period = this.periods + 1;
    this.sma = SMA(this.props.period);
  }

  map(d, i, history) {
    let items = [];

    const data = history.data;
    
    if (i > (this.candle_count + 1)) {
      const most_left_candle = i - (this.candle_count + 1);

      const bullishOB =
        data[most_left_candle].close() < data[most_left_candle].open();

      if (bullishOB) {
        const z = most_left_candle;

        let upcandles = 0;
        let high = 0;
        let low = 0;
        let avg = 0;

        for (let j = most_left_candle; j < i; ++j) {
          if (data[j].close() > data[j].open()) {
            upcandles++;
          }
        }

        if (upcandles >= this.candle_count) {
          high = data[z].open();
          low = data[z].low();

          high = data[z].open() > high ? data[z].open() : high;
          low = data[z].low() < low ? data[z].low() : low;
          avg = (low + high) / 2.0;

          
          items.push({
            tag: "Shapes",
            key: "rects",
            primitives: [
              {
                tag: "Rectangle",
                position: {
                  x: du(d.index()),
                  y: du(low),
                },
                size: {
                  height: du(high - low),
                  width: du(data.length),
                },
              },
            ],
            fillStyle: {
              color: "green",
              opacity: 30,
            },
          });

      
        }
      }
      
       const bearishOB =
        data[most_left_candle].close() > data[most_left_candle].open();

      if (bearishOB) {
        const z = most_left_candle;

        let candles = 0;
        let high = 0;
        let low = 0;
        let avg = 0;

        for (let j = most_left_candle; j < i; ++j) {
          if (data[j].close() < data[j].open()) {
            candles++;
          }
        }

        if (candles >= this.candle_count) {
          high = data[z].high();
          low = data[z].open();

          high = data[z].high() > high ? data[z].high() : high;
          low = data[z].open() < low ? data[z].open() : low;
          avg = (low + high) / 2.0;

          
          items.push({
            tag: "Shapes",
            key: "rects",
            primitives: [
              {
                tag: "Rectangle",
                position: {
                  x: du(d.index()),
                  y: du(low),
                },
                size: {
                  height: du(high - low),
                  width: du(data.length),
                },
              },
            ],
            fillStyle: {
              color: "red",
              opacity: 30,
            },
          });

      
        }
      }

   
      return {
        graphics: {
          items: items,
        }
      };

      //return this.sma(d.close());
    }
  }
}

module.exports = {
  name: "order block",
  description: "order block",
  calculator: order_block,
  inputType: "bars",
  params: {
    period: predef.paramSpecs.period(14),
  },
  tags: ["My Indicators"],
  schemeStyles: predef.styles.solidLine("#8cecff"),
};

btw I created the script from an existing trading view script

That is awesome! Thank you. Would it be to to add the code when once the price wicks through the block its no longer valid and would delete from the screen?