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

1 Like

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?

1 Like

@Dennis_Rutjes This is very helpful, thank you. Would it be possible to address @Jason_Lacerda 's request to have the order block disappears once it’s not valid? Thanks!

Hi @Dennis_Rutjes , wondering if you can help me with something.
I was trying to write a code which can highlight low volume prints.
Like if you have ES1 with 100,200,800 contracts and suddenly 0/5 appears, whould you know how to highlight volume between 1-25 for example?

I was trying to figure it out from “VPOC of each bar” indicator, without success.

Thanks

MK