Internals Pressure Index
A market-internals score for trading ES and NQ during the cash session. One line says who owns the day. One histogram says which way the tape is pressing right now. Nothing else is on the chart unless you ask for it.
Bias (line) describes the session: breadth, money, tape aggression and fear, read as a day-level state. Push (histogram) is short-term pressure from the two forces that tested as leading the next 15–30 minutes: tape aggression and the VIX/VXN "fear residual". Push tested best when it agreed with Bias. That agreement is the only thing the indicator tints the background for.
Install
- In TradingView, open the Pine Editor, paste the script, and click Add to chart.
- Use a standard candle, bar or line chart on a 1 to 30 minute timeframe. 1 to 5 minutes is the intended range. Heikin Ashi, Renko, range and seconds charts are rejected with an error, because the internals feeds have no data for them.
- Load it on the instrument you trade: ES, MES, NQ, MNQ, or SPY/QQQ.
The script picks its data for you. On a chart whose symbol contains NQ, NDX, QQQ, NAS100 or US100 it uses NASDAQ internals and VXN; on everything else, NYSE internals and VIX. The label in the corner of the pane confirms which pair is in use. Both can be forced in Settings → Data; an All US universe is also available.
Scoring starts at 9:35 ET by default (five minutes after the open, adjustable) and stops at 16:00. Outside those hours the pane is empty and the label shows the last reading. For the overnight session, see IPI Globex.
Data feeds
All feeds are TradingView's own USI: internals symbols, the same ones used by the common "Market Internals" scripts. For the NYSE universe:
| Feed | Symbol | Used for |
|---|---|---|
| TICK | USI:TICK | Aggression: centre of gravity of the TICK bar, and ±program bursts |
| ADD | USI:ADV, USI:DECL | Breadth: advance/decline as a percentage, and its drift since the open |
| ABVD | USI:PCTABOVEVWAP.NY | Breadth: share of stocks above VWAP |
| VOLD | USI:UVOL, USI:DVOL | Money: up-volume vs down-volume tilt |
| TKCD | USI:UPTKS.NY, USI:DNTKS.NY | Aggression: up-tick vs down-tick trades |
| BATD | USI:TRDS.ASK.NY, USI:TRDS.BID.NY | Aggression: trades at the ask vs at the bid |
| Fear | CBOE:VIX or CBOE:VXN | Fear: the fear residual |
| DXY | TVC:DXY | Fear: dollar move, weighted only when it has been correlating with your instrument |
NASDAQ and All-US variants swap the suffixes (TICKQ, ADVQ, .NQ, .US and so on). If a feed is missing, the label says so and the score is computed from what remains.
Reading the pane
| Element | What it is | How to read it |
|---|---|---|
| Bias line | Weighted blend of the four forces over the session so far, smoothed over 3 bars. | Green when the day is in an uptrend regime, red in a downtrend, grey in balance. The regime has hysteresis: it switches on at ±25 and only switches off when Bias falls back inside ±12.5, so an ordinary pullback does not flip the day to balance. |
| Push histogram | Pressure over the last 15 minutes from aggression (40%) and fear (60%). | Cyan above zero, red below. Bars are bright when |Push| ≥ 25 (a lean) and dim otherwise. Dim bars are noise; do not read direction into them. |
| Background tint | The state (regime × lean). | Strong tint when Push leans with the regime, which is where Push tested best. Faint tint when Push leans without a trend behind it, or against the trend. No tint when there is no lean. |
| Label | One line in the corner. | Which internals universe and fear gauge are in use. Warnings grow beneath it only while they apply. See The label. |
| Ease | Optional thin line with dots. | Divergence between price and the pressure behind it. See Ease. |
Earlier versions printed Bias, Push, the state name and a dozen context rows in a table. All of it restated what the chart already shows, and the trader's eye went to the table instead of the bars. The numbers are still available in the Data Window (see Diagnostics); the pane shows only what changes a decision in the next fifteen minutes.
The nine states
A state is the Bias regime crossed with the Push lean. The script does not name states on the chart; it encodes them in the line colour and the tint. This grid is the decoder. The guidance column reflects what the testing supported and nothing more.
Bias ≥ +25
|Bias| < 25
Bias ≤ −25
The two aligned states are the only ones with a strong tint and the only ones with a dedicated alert. Everything else is context.
The label
The label always shows the active data pair, for example IPI · NASDAQ · VXN, and · last RTH reading after the close. Lines appear underneath it only while the condition holds:
| Line | When it appears |
|---|---|
| Gap: ADD +42% at 9:35, undecided / being bought / being sold (fill) | Only when the opening advance/decline reading is beyond ±30% and only until 11:30 ET, when the verdict is final and the line is removed. The verdict uses the morning's average share of stocks above VWAP, so one noisy print cannot flip it. |
| ⚠ Range is 1.4× the implied move: don't chase | When the session's high-to-low range exceeds 1.3× the one-day move implied by the fear gauge. |
| ⚠ Bias forces disagree (31% aligned) | When less than 40% of the Bias weight points the same way: the day reading is a compromise between forces that disagree. |
| 3 TICK buy programs beyond +600 in 15m, no sell programs | When TICK has printed three or more bursts past its adaptive program level one way and none the other way, inside the Push window. |
| ⚠ No data for TKCD, BATD (scored without) | When a feed is unavailable. The score keeps running on the remaining feeds; this is the only place the degradation is reported. |
Ease
Ease is an optional plot that answers a question Bias and Push do not: is price moving more than the internals account for? It is price's move over the Push window, scaled the same way the forces are, minus Push itself, then halved so it sits on the same −100 to +100 scale.
- Above zero: price is rising on more than the internals are supplying. An unsupported move.
- Below zero: price is falling with less selling pressure behind it than the fall suggests.
- Near zero: price has moved about as far as the pressure explains.
The line is drawn faint (amber above zero, violet below) and is smoothed more heavily than the scores, because a rolling price change lurches every time a large bar drops out of the window. Dots print only where |Ease| crosses a threshold (50 by default). The dots are the only part meant to catch your eye.
Ease is in the spirit of Ease of Movement (result against effort) and has not been tested against forward returns. Read it as divergence context, not as a signal. The dot threshold of 50 is a starting guess: if dots print constantly, raise it; if they never print, lower it. The dropdown also offers Bias slope (Bias now minus Bias fifteen minutes ago) as an alternative, or Off.
How it is built
Four forces
| Force | Components | Bias weight | Push weight |
|---|---|---|---|
| Breadth | ADD%, ADD drift since the open (so the gap is stripped out), ABVD | 35 | 0 |
| Money | VOLD tilt: (up-vol − down-vol) / total | 35 | 0 |
| Aggression | TICK centre of gravity (50%), TKCD tilt (20%), BATD tilt (30%) | 15 | 40 |
| Fear | Fear residual (75%), DXY move gated by its recent correlation with price (up to 25%) | 15 | 60 |
Breadth and money carry zero Push weight by default because in testing they moved with price and told nothing about the next half hour. They stay in Bias because they describe the day well. The weights are inputs; the defaults are the tested ones.
One scale for everything
Each component is divided by its own typical size, an exponentially weighted RMS over roughly the last ten sessions, and squashed into −1 to +1 with a tanh. That is why NYSE and NASDAQ internals, 1-minute and 5-minute charts, and calm and violent regimes all read on the same −100 to +100 axis. RMS rather than a z-score: zero is a meaningful "balanced" point for tug-of-war measures, and a persistent one-sided tilt is signal, so no mean is subtracted. The scale needs about a session to settle after the script is first added.
Day totals and windows
UVOL/DVOL, up-ticks/down-ticks and trades-at-ask/at-bid are cumulative day totals. The day tilt feeds Bias; the change in both totals over the Push window gives the recent flow for Push. Nothing ever reaches back before the day's first scored bar.
The fear residual
VIX falls when ES rises; that part of its move is not information. The script estimates the beta of 5-minute VIX returns to 5-minute price returns (exponentially weighted, clamped between −15 and −1, −6 until there is a session of data), and defines the residual as the fear gauge's log move since the open minus beta times price's log move. Residual rising means fear is building beyond what the price move explains; falling means fear is draining. The sign is flipped so that draining fear scores bullish.
TRIN
TRIN is computed and available in Diagnostics but not scored: TRIN = (ADV/DECL) ÷ (UVOL/DVOL), so it repeats information already present in ADD and VOLD.
What testing showed
These are the author's own tests on TradingView data, SPY and QQQ, 1-minute bars from August to October 2026 and 5-minute bars from October 2025 to October 2026. Sample sizes are those windows; nothing here has been audited.
- Breadth and money move with price. They carried no information about the next 30 minutes, even after removing their co-movement with price. Hence Push weight zero.
- Bias did not predict the rest of the day. Read it as a description of the session, not a forecast. Its job is to say which Push leans have a trend behind them.
- Push correlated roughly +0.04 to +0.09 with the next 30-minute return out of sample. Top-fifth versus bottom-fifth Push readings differed by about 2–3 basis points per 30 minutes, roughly 2 ES or 6–7 NQ points. That is a lean, not a trading system, and it will not survive a wide stop or a careless entry.
- Counter-trend pushes did not reliably revert. Earlier "buy the pullback" triggers were removed for that reason.
- The weights were chosen on the first 60% of the 5-minute year and checked on the rest. Treat them as provisional, and use the self-check below on your own chart.
An effect of r ≈ 0.05 needs roughly 1,500 independent samples to separate from zero at ordinary confidence. At eleven non-overlapping samples per session that is about 140 sessions. The self-check therefore withholds its correlation until it has 500 samples, and on a 1-minute chart TradingView's history will usually never get there. Use a 5-minute chart with a year loaded if you want to see the number.
Diagnostics and export
Two switches in Settings → Display add series to the Data Window (the panel TradingView shows when you hover a bar) without drawing anything in the pane.
Diagnostics in Data Window
d_TRIN- Arms index rebuilt from the same feeds.
d_fearResidual%,d_fearBeta- The fear residual in percent and the beta in use.
d_dxyCorr- Recent correlation of 5-minute DXY and price returns. DXY weight scales with |corr| up to 0.3.
d_rangeVsImplied- Session range as a multiple of the one-day move implied by the fear gauge.
d_biasAlign%- Share of Bias weight pointing the same way. 100 = all four forces agree.
d_tickBuyPrograms,d_tickSellPrograms- TICK bursts past the adaptive program level inside the Push window.
d_selfcheck_r,d_selfcheck_n- Correlation between Push and the next 30-minute return on the history loaded, sampled every 30 minutes from 10:00 to 15:00 ET so forward windows do not overlap. r is withheld (shows as n/a) until n ≥ 500.
d_leanHit%,d_alignedHit%- Of the samples where |Push| ≥ 25, how often the next 30 minutes went Push's way; and the same restricted to samples where Push agreed with the regime.
Export columns
Adds the raw feeds (x_tickHi, x_adv, x_uvol, x_fear and so on) plus x_bias, x_push, x_state and x_regime to the Data Window and to TradingView's Export chart data, so the indicator can be rebuilt and checked offline.
Settings
Data
- Internals universe Auto
- Auto, NYSE, NASDAQ or All US. Auto matches the chart symbol.
- Fear gauge Auto
- Auto, VIX or VXN. On TradingView, 1-minute VIX history is shorter than VXN's; live data is unaffected.
- ABVD, TKCD, BATD, DXY all on
- Include or exclude each optional feed.
Calculation
- Push window 15 minutes
- How far back Push looks. Shorter is faster and noisier.
- Skip first N minutes after 9:30 5
- Opening auctions make TICK, VIX and breadth erratic. Scoring starts after this.
- Calibration memory 10 sessions
- How much history the adaptive scale remembers.
- Smoothing 3 bars
- EMA applied to Bias and Push, restarted every session.
Force weights
- Breadth / Money / Aggression / Fear Bias 35 / 35 / 15 / 15
- Weights are normalised, so only their ratios matter.
- Push 0 / 0 / 40 / 60
- The tested defaults. Giving breadth or money Push weight adds a force that tested as non-predictive.
Signals
- Bias threshold 25
- |Bias| above this means the day has a direction.
- Trend exit 50% of threshold
- Hysteresis. The regime holds until Bias falls back below this share of the threshold.
- Push lean threshold 25
- |Push| above this counts as a lean. At 25, Push leaned about 30% of the time in testing.
- Gap: opening ADD% 30
- Opening advance/decline beyond this counts as a breadth gap.
- Extended: range ÷ implied 1σ 1.3
- Range warning threshold.
Display
- Tint background by state on
- Turn off to keep the pane monochrome.
- Plot the four Bias forces off
- Draws breadth, money, aggression and fear as four thin lines, for seeing which force is driving Bias.
- Extra plot Ease
- Ease, Bias slope, or Off.
- Ease: mark divergence beyond ± 50
- Dot threshold.
- Label, Label position on, top right
- The one-line label and its corner.
- Diagnostics in Data Window, Export columns off, off
- See Diagnostics.
Alerts
Three alert conditions are exposed to TradingView's alert dialog:
- Aligned lean up: the state becomes Uptrend · Push up.
- Aligned lean down: the state becomes Downtrend · Push down.
- State change: any state change during scoring hours.
The first two are the only states the testing supported. If you set one alert, set those.
Limits and honest caveats
- Regular session only. The internals feeds are built from cash-session stock trades and do not exist overnight. IPI Globex covers 18:00–09:30 ET with different inputs.
- It is a lean of a few basis points. The measured edge is smaller than a typical ES spread plus slippage on a careless fill. It is useful as a tie-breaker against your own levels, not as an entry trigger.
- Calibration takes a session. The first day after adding the script, the scale is still learning typical sizes and readings may run hot or cold.
- Feeds drop. TradingView's internals symbols occasionally stall. The label is the only place that is reported; glance at it when a reading looks wrong.
- Nothing here is trading advice. The indicator describes the tape. Entries, exits and size are yours.