Indicador Trade Size Distribution: fórmula, ajustes y cómo leerlo
Trade Size Distribution mide lo concentrado que está el volumen de una barra en sus niveles de precio más pesados. Indica el porcentaje del volumen de la barra negociado en niveles por encima de un umbral de percentil calculado sobre esa misma barra, el percentil 80 por defecto.
Senzoukria · Indicadores · Updated September 2026
Trade Size Distribution — Cinta y flujo, en su propio panel debajo del gráfico.
Qué mide Trade Size Distribution
En cada barra, los volúmenes de sus niveles de precio se ordenan y se toma un umbral por rango más cercano, sin interpolación, así que el umbral es siempre un volumen de nivel realmente observado y no un número calculado entre dos niveles. El indicador suma luego el volumen de todos los niveles estrictamente por encima de ese umbral, lo divide por el volumen total de niveles de la barra y expresa el resultado en porcentaje. Los niveles que comparten precio se fusionan primero y los niveles sin cantidad se excluyen, así que una fuente que publique una lista de niveles sin fusionar no puede inflar el número de niveles. Una barra de footprint está agregada y se pierde el orden de las ejecuciones, de modo que lo que se mide es la concentración del flujo entre precios, no un histograma de los tamaños de cada operación.
La fórmula, tal como está implementada
No es la definición habitual en otros sitios: es lo que calcula el código que se distribuye, documentado junto a su implementación:
Points d'histogramme : `f` rend `null` quand la barre n'a pas d'information — la barre n'émet alors PAS de point (contrat `HistogramPoint` : pas de trou, pas de valeur inventée). */ function histPoints( bars: readonly FootprintBar[], f: (bar: FootprintBar, i: number) => number | null, ): HistogramPoint[] { const out: HistogramPoint[] = []; for (let i = 0; i < bars.length; i++) { const v = f(bars[i], i); if (v !== null) out.push({ time: bars[i].bucketTsNs, value: v }); } return out; } function histOut( points: HistogramPoint[], positiveColor: string, negativeColor: string, ): SeriesOutput { return { shape: "histogram", points, positiveColor, negativeColor }; } /** Un niveau de la barre indexé par sa CLÉ ENTIÈRE (indice de tick quand le tick est connu, quantification 1e-6 sinon — canon : jamais de clé f64). */ type KeyedLevel = { key: number; price: number; buy: number; sell: number }; /** Niveaux EXPLOITABLES de la barre (canon : qty = 0 et prix non fini exclus), agrégés par clé de prix, rendus en ordre ASCENDANT. L'agrégation est indispensable : deux entrées `levels` au même prix (source qui n'a pas fusionné, ou deux prix qui tombent sur le même tick) ne doivent compter QUE POUR UN niveau — sinon le compte de niveaux, les percentiles et la largeur traversée mentent tous les trois. / function barLevelsByKey( bar: FootprintBar, tickSize: number | null, ): KeyedLevel[] { const byKey = new Map<number, KeyedLevel>(); for (const lvl of usableLevels(bar)) { const key = priceKey(lvl.price, tickSize); const cur = byKey.get(key); if (cur !== undefined) { cur.buy += lvl.buyVolume; cur.sell += lvl.sellVolume; } else { byKey.set(key, { key, price: lvl.price, buy: lvl.buyVolume, sell: lvl.sellVolume, }); } } return [...byKey.values()].sort((a, b) => a.key - b.key); } /** CVD de séance par barre + indice de la PREMIÈRE barre de sa séance. CVD = Σ `totalDelta` depuis l'ouverture CME 17:00 CT, RESET à chaque ouverture (`splitSessions`) — canon, jamais le début du chart. Le second tableau permet aux fenêtres glissantes de refuser de comparer deux barres séparées par un reset : la différence de CVD n'aurait alors aucun sens. / function sessionCvd(bars: readonly FootprintBar[], ctx: SeriesContext): { cvd: number[]; sessionStart: number[]; } { const cvd = new Array<number>(bars.length).fill(0); const sessionStart = new Array<number>(bars.length).fill(0); for (const s of splitSessions(bars, ctx)) { let running = 0; for (let i = s.start; i <= s.end; i++) { running += bars[i].totalDelta; cvd[i] = running; sessionStart[i] = s.start; } } return { cvd, sessionStart }; } /** VWAP de séance par barre : Σ(tp·vol)/Σvol cumulé depuis l'ouverture CME 17:00 CT, reset à CHAQUE ouverture. Prix d'échantillon = prix TYPIQUE (H+L+C)/3, poids = volume de la barre — exactement le mode `typical` de `vwap.ts` (parité ATAS/Sierra/TradingView) : un second VWAP maison qui divergerait du VWAP dessiné serait pire qu'inutile. Barres à volume nul : n'alimentent rien ; avant le premier volume de la séance → `null` (pas de VWAP, pas de distance). / function sessionVwap(bars: readonly FootprintBar[], ctx: SeriesContext): Array<number | null> { const out = new Array<number | null>(bars.length).fill(null); for (const s of splitSessions(bars, ctx)) { let pv = 0; let v = 0; for (let i = s.start; i <= s.end; i++) { const w = bars[i].totalVolume; if (w > 0) { pv += typicalPrice(bars[i]) * w; v += w; } out[i] = v > 0 ? pv / v : null; } } return out; } /** Extrêmes COURANTS (running high/low) de la séance en cours, reset à chaque ouverture 17:00 CT. Définis dès la 1ʳᵉ barre : un extrême courant existe immédiatement, contrairement à une moyenne — pas de warm-up. */ function runningSessionExtremes( bars: readonly FootprintBar[], ctx: SeriesContext, ): Array<{ hi: number; lo: number }> { const out = new Array<{ hi: number; lo: number }>(bars.length); for (const s of splitSessions(bars, ctx)) { let hi = Number.NEGATIVE_INFINITY; let lo = Number.POSITIVE_INFINITY; for (let i = s.start; i <= s.end; i++) { if (bars[i].high > hi) hi = bars[i].high; if (bars[i].low < lo) lo = bars[i].low; out[i] = { hi, lo }; } } return out; } /** Offset de la barre depuis l'ouverture de SA séance, en NANOSECONDES. Les buckets sont des ns entiers sur la grille du timeframe : la clé est exacte (la règle `priceKey` ne concerne que les PRIX). */ function offsetNs(bar: FootprintBar, openSec: number): number { return bar.bucketTsNs - openSec * 1e9; } /** Offset de la barre depuis l'ouverture de SA séance, en MINUTES ENTIÈRES (plancher). Clé plus grossière qu'`offsetNs` — voir `time-of-day-volume` pour la raison d'être de ce choix. */ function offsetMinutes(bar: FootprintBar, openSec: number): number { return Math.floor((bar.bucketTsNs / 1e9 - openSec) / 60); } /** Seuil de percentile par RANG LE PLUS PROCHE (nearest-rank, méthode NIST « inverse empirique ») sur une liste TRIÉE ASCENDANTE et NON VIDE : rang = ⌈pct/100 × m⌉, borné à [1, m] → seuil = trié[rang − 1] Choix documenté : pas d'interpolation linéaire. Sur 4 ou 5 niveaux — le cas courant d'une barre footprint — une interpolation fabriquerait un seuil qui n'existe dans aucun niveau ; le rang le plus proche rend toujours un volume RÉELLEMENT observé. */ function nearestRankThreshold(sortedAsc: readonly number[], pct: number): number { const m = sortedAsc.length; const rank = Math.min(m, Math.max(1, Math.ceil((pct / 100) * m))); return sortedAsc[rank - 1]; } // ── Microstructure (Tape & flow) ──────────────────────────────────────────── /** Distribution des tailles — part du volume venant des niveaux LOURDS : seuil = percentile P des volumes de niveau de la barre (nearest-rank) value = 100 × Σ { vol(niveau) : vol(niveau) > seuil } / Σ vol(niveau) POURQUOI : une barre de 1 000 lots répartie sur 20 niveaux et une barre de 1 000 lots dont 800 sont tombés sur 2 prix ne racontent pas la même histoire. Cet indicateur mesure la CONCENTRATION du flux, c'est-à-dire la trace que laissent les gros participants — le seul angle honnête sur la « taille des trades » que permette une barre footprint AGRÉGÉE : la distribution des tailles trade par trade exigerait le tape brut (l'ordre des exécutions est perdu à l'agrégation). Le doc-comment le dit plutôt que le nom seul. Convention : comparaison STRICTE au seuil (`>`), donc une barre dont TOUS les niveaux pèsent pareil rend 0 — c'est une valeur MESURÉE (aucune concentration), pas un 0/0 déguisé : le dénominateur, lui, est > 0 par construction (`usableLevels` exclut les niveaux à volume nul). Défaut P=80 : le décile supérieur est trop fin pour 3-5 niveaux, la médiane ne mesure plus la concentration mais la simple asymétrie. Barre sans niveau exploitable → PAS de point. Aucun tick size requis (les clés ne servent qu'à dédupliquer).
Cómo leerlo
- Las lecturas bajas indican que el volumen de la barra se repartió de forma bastante uniforme entre sus niveles de precio; las altas, que una gran parte cayó en muy pocos precios.
- Una concentración que aparece en el extremo de un rango merece abrirse en el propio footprint, donde puedes ver qué lado de la cinta la produjo.
- El número de niveles utilizables de una barra decide lo que el umbral por defecto puede dejar por encima: por debajo de cinco niveles, el percentil 80 cae en el nivel más pesado y la lectura es 0 por construcción.
- Un valor exactamente igual a 0 es un resultado medido, no un dato ausente: significa que ningún nivel llevó más volumen que el umbral.
- Las barras sin ningún nivel utilizable no producen punto, así que un hueco en el panel significa que la barra no tenía datos por nivel, no una lectura de cero.
Parámetros y valores por defecto
El percentil es 80 por defecto y acepta de 1 a 99. Como el umbral se toma por rango más cercano, el percentil y el número de niveles interactúan directamente: una barra solo devuelve un valor distinto de cero cuando tiene al menos 100/(100 − P) niveles utilizables, es decir, cinco niveles con el valor por defecto. En una barra de exactamente cinco niveles, el umbral cae en el cuarto más pesado, así que la lectura es la parte que lleva el nivel más pesado; en barras más anchas cubre aproximadamente la quinta parte superior. Bajar el percentil hacia 50 sitúa el umbral en el nivel mediano de la barra, lo que sube los valores y mide más la asimetría que la concentración. Subirlo hacia 99 exige cien niveles antes de que algo pueda superar el umbral, así que en barras de footprint normales todas las lecturas se quedan en 0.
| Parámetro | Tipo | Por defecto | Rango |
|---|---|---|---|
| Percentile | number | 80 | 1 – 99 |
Lo que no muestra
No es una distribución del tamaño de cada operación. Reconstruir el tamaño de cada ejecución requiere la cinta en bruto, y esa información desaparece en cuanto una barra agrega sus niveles. La comparación estricta tiene una consecuencia que conviene conocer: una barra negociada a un único precio devuelve 0, porque ningún nivel puede superar un umbral igual a sí mismo, aunque esa barra esté concentrada al máximo; la misma aritmética explica todos los 0 en barras estrechas con el percentil por defecto. La lectura depende por tanto de cuántos niveles contiene una barra, lo que depende de la temporalidad, del rango de la barra y de la agrupación de precios de la fuente, así que las lecturas solo son comparables dentro de un mismo instrumento y una misma temporalidad. Por último, requiere datos por nivel con volumen por precio; una fuente que solo proporciona apertura, máximo, mínimo, cierre y volumen no produce nada.
Indicadores relacionados
- Unfinished Auctions — Cinta y flujo
- Effort vs Result — Cinta y flujo
- POC Drift (ticks) — Cinta y flujo
- Cumulative buy volume — Cinta y flujo
- Cumulative sell volume — Cinta y flujo
- Buy/sell ratio — Cinta y flujo
Esta página en otros idiomas
Frequently asked questions
- ¿Se puede medir el tamaño de cada operación en un gráfico footprint?
- No a partir de una barra de footprint agregada. La agregación conserva el volumen negociado en cada precio, pero descarta la secuencia y el tamaño de las ejecuciones individuales que lo produjeron. Lo que sigue siendo medible es lo concentrado que está ese volumen entre precios, que es lo que indica este indicador.
- ¿Qué significa una lectura de 0 en trade size distribution?
- Significa que ningún nivel de precio de esa barra llevó más volumen que el umbral de percentil, porque la comparación es estricta. Ocurre cuando todos los niveles pesan más o menos lo mismo, en una barra negociada a un único precio y en cualquier barra con menos de cinco niveles utilizables con el percentil 80 por defecto, donde el umbral cae en el propio nivel más pesado. Es un valor medido, no un error.
- ¿Qué percentil uso para trade size distribution?
- Parte del valor por defecto, 80, que funciona en barras con cinco niveles o más. Antes de cambiarlo, comprueba cuántos niveles tienen realmente tus barras: un percentil P necesita al menos 100/(100 − P) niveles antes de que alguno pueda superar el umbral, así que 99 es inutilizable en una barra de footprint típica. Un percentil cercano a 50 mide lo asimétrica que es la distribución más que lo concentrada que está.