# Do volume profile levels (POC, value area, HVN/LVN) work as support and resistance on NSE?

> On 9 months of 1-minute data for the 50 most liquid NSE stocks, profile levels held no more often than random prices.

Published 2026-10-30 by TRINETRA.


**Date:** 2026-10-30 · **Script:** `engine/scripts/bench_orderflow_levels.py`
**Data:** Upstox 1-minute bars, the 50 most liquid NSE stocks by 20-session median turnover,
2 Feb → 29 Oct 2026 (~185 sessions each). Results in `BENCH_orderflow_levels.json`.

## Verdict

**No volume-profile level predicts support or resistance better than a random price.** The
apparent power of a "rejection on volume" at a level is mostly arithmetic. What remains is
general intraday mean reversion that random prices share. Print-level delta and depth walls
can't be tested from bars and have no history. TRINETRA now records them every session.

## Design

- Levels for day D come only from data before D. The 5-session composite profile gives POC,
  value-area high/low, high-volume nodes and low-volume nodes. The prior session gives POC,
  VAH, VAL, high, low and VWAP.
- **Placebo:** 8 random prices per stock-day, drawn uniformly within the same prior 5-session
  range.
- For each level's first touch on day D: **hold** if price moves R away on the approach side
  before a bar closes R beyond; **break** otherwise. R = 0.3% and 0.5%. Unresolved touches are
  excluded.
- 95% intervals bootstrap trading **dates**, because touches on one day share the market.

## 1. Levels vs random prices (R = 0.3%)

| level | touches | hold | vs random | 95% CI |
|---|---|---|---|---|
| yesterday VWAP | 3,427 | 56.8% | +1.4 | −0.4 to +3.1 |
| yesterday value high | 3,123 | 56.2% | +0.8 | −1.1 to +2.8 |
| high-volume node | 18,078 | 56.1% | +0.7 | −0.3 to +1.8 |
| 5-day value high | 2,101 | 56.0% | +0.6 | −1.8 to +2.6 |
| low-volume node | 15,987 | 55.9% | +0.5 | −0.5 to +1.6 |
| **random price** | 15,956 | **55.4%** | — | — |
| 5-day POC | 2,349 | 55.1% | −0.3 | −2.5 to +2.0 |
| yesterday POC | 3,157 | 55.1% | −0.3 | −1.9 to +1.5 |
| yesterday high / low | 2,650 / 2,783 | 54.2 / 53.8% | −1.2 / −1.6 | both span 0 |
| 5-day value low | 2,156 | 53.7% | −1.7 | −3.9 to +0.5 |

Every interval spans zero, and the 0.5% threshold gives the same picture. POCs sit slightly
**below** random, consistent with a POC being where price spends time rather than a barrier.

## 2. The reaction at the touch

At R = 0.3%, a "rejection on volume" (touch bar closes back on the approach side, at ≥2× the
volume of the 30 bars before it) holds **71%** at profile levels against 48% for a plain touch.
It looks like the order-flow edge. Then remove the arithmetic: the outcome window starts at
the touch bar's close, and a rejection candle closes nearer the hold target. A random walk from
distance x reaches +R before −R with probability (R + x) / 2R.

| touch type (R = 0.3%) | hold | random-walk expected | excess |
|---|---|---|---|
| profile level, rejection + volume | 71.0% | 66.5% | +4.5 (CI 3.1 to 5.9) |
| random price, rejection + volume | 68.5% | 65.0% | +3.5 (CI 1.3 to 5.5) |
| profile level, plain touch | 48.2% | 42.4% | +5.9 (CI 3.5 to 8.1) |
| random price, plain touch | 49.1% | 42.5% | +6.6 (CI 3.6 to 9.9) |
| profile level, volume without rejection | 43.7% | 33.6% | +10.0 (CI 8.2 to 11.8) |
| random price, volume without rejection | 40.6% | 33.7% | +7.0 (CI 4.9 to 9.3) |

- About 20 of the 23-point gap is arithmetic. A rejection on volume is **not** better than a
  plain touch once its starting position is accounted for.
- Every row beats random walk by 3–10 points, **including random prices**. That's general
  intraday mean reversion in NSE large caps, not a property of levels.
- Profile levels and random prices overlap in every row. The one gap that looks large
  (volume without rejection: +10.0 vs +7.0) also has overlapping intervals.

## Product decisions (built 2026-10-30)

- **Order Flow page** (`/order-flow/SYMBOL`): live print-level delta, buyer-initiated share,
  book imbalance, 5-level book, resting walls, footprint, today's profile against the 5-day
  composite, VWAP ±1σ and estimated CVD. Labelled **descriptive, not predictive**. Every level
  carries its row from the table above.
- **Recording:** every watched symbol is written to `data/orderflow/<date>/<SYM>.jsonl` every
  5 s. `scripts/record_orderflow.py --top 50` records a fixed universe for a whole session.
  When about 40 sessions exist, test: do walls hold more than random prices, and does print
  delta at a touch add anything beyond the random-walk expectation?

## Limits

- 1-minute bars spread each bar's volume evenly across its range; the profile is exact only
  at that resolution.
- Large caps only. Thin stocks may behave differently, untested.
- 9 months, one regime. ~185 sessions × 50 stocks is large for touches but small for regimes.
- Live delta is classified per feed update (Lee-Ready against the prior quote), not per
  exchange trade.


_TRINETRA is a research and education tool. Nothing on this site is investment advice or a recommendation to buy or sell any security. Markets carry risk; do your own research and consult a SEBI-registered adviser before investing._
