Indicatore Trade Size Distribution: formula, impostazioni e lettura
Trade Size Distribution misura quanto il volume di una barra è concentrato sui suoi livelli di prezzo più pesanti. Riporta la percentuale del volume della barra scambiata sui livelli sopra una soglia percentile calcolata sulla barra stessa, per impostazione predefinita l'80° percentile.
Senzoukria · Indicatori · Updated September 2026
Trade Size Distribution — Tape e flusso, in un pannello separato sotto il grafico.
Che cosa misura Trade Size Distribution
Per ogni barra, i volumi dei suoi livelli di prezzo vengono ordinati e la soglia viene presa per rango più vicino, senza interpolazione, quindi è sempre un volume di livello effettivamente osservato e non un numero calcolato tra due livelli. L'indicatore somma poi il volume di ogni livello strettamente sopra quella soglia, lo divide per il volume totale dei livelli della barra e riporta il risultato in percentuale. I livelli con lo stesso prezzo vengono prima fusi e quelli senza quantità esclusi, così una fonte che pubblica un elenco di livelli non fuso non può gonfiare il numero di livelli. Una barra footprint è aggregata e l'ordine delle esecuzioni è perso, quindi ciò che si misura è la concentrazione del flusso tra i prezzi, non un istogramma delle dimensioni dei singoli scambi.
La formula, così come è implementata
Non è la definizione consueta altrove: è ciò che calcola il codice distribuito, documentato accanto alla sua implementazione:
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).
Come leggerlo
- Letture basse significano che il volume della barra era distribuito in modo abbastanza uniforme sui suoi livelli di prezzo; letture alte significano che una quota ampia è finita su pochissimi prezzi.
- Una concentrazione all'estremo di un range merita di essere aperta sul footprint stesso, dove puoi vedere quale lato del nastro l'ha prodotta.
- Il numero di livelli utilizzabili in una barra decide cosa la soglia predefinita può lasciare sopra di sé: sotto i cinque livelli, l'80° percentile cade sul livello più pesante e la lettura è 0 per costruzione.
- Un valore esattamente pari a 0 è un risultato misurato, non un dato mancante: significa che nessun livello ha portato più volume della soglia.
- Le barre senza livelli utilizzabili non producono alcun punto, quindi un vuoto nel pannello significa che la barra non aveva dati per livello, non una lettura pari a zero.
Parametri e valori predefiniti
Il percentile è 80 per impostazione predefinita e accetta valori da 1 a 99. Poiché la soglia viene presa per rango più vicino, percentile e numero di livelli interagiscono direttamente: una barra restituisce un valore non nullo solo se contiene almeno 100/(100 − P) livelli utilizzabili, cioè cinque livelli con il valore predefinito. Su una barra di esattamente cinque livelli la soglia cade sul quarto più pesante, quindi la lettura è la quota portata dal solo livello più pesante; sulle barre più ampie copre circa il quinto superiore dei livelli. Abbassare il percentile verso 50 porta la soglia sul livello mediano della barra, il che alza i valori e misura l'asimmetria più che la concentrazione. Alzarlo verso 99 richiede cento livelli prima che qualcosa possa superare la soglia, quindi sulle normali barre footprint ogni lettura crolla a 0.
| Parametro | Tipo | Predefinito | Intervallo |
|---|---|---|---|
| Percentile | number | 80 | 1 – 99 |
Ciò che non mostra
Non è una distribuzione delle dimensioni per singolo scambio. Ricostruire la dimensione di ogni esecuzione richiede il nastro grezzo, e quell'informazione è persa una volta che una barra aggrega i suoi livelli. Il confronto stretto ha una conseguenza da conoscere: una barra che ha scambiato a un solo prezzo restituisce 0, perché nessun livello può superare una soglia uguale a sé stesso, anche se una tale barra è concentrata al massimo; la stessa aritmetica spiega ogni 0 sulle barre strette con il percentile predefinito. La lettura dipende quindi da quanti livelli contiene una barra, cosa che deriva dal timeframe, dal range della barra e dal raggruppamento dei prezzi della fonte, per cui le letture sono confrontabili solo all'interno di uno stesso strumento e di uno stesso timeframe. Infine, richiede dati per livello con il volume per prezzo; una fonte che fornisce solo apertura, massimo, minimo, chiusura e volume non produce nulla.
Indicatori correlati
- Unfinished Auctions — Tape e flusso
- Effort vs Result — Tape e flusso
- POC Drift (ticks) — Tape e flusso
- Cumulative buy volume — Tape e flusso
- Cumulative sell volume — Tape e flusso
- Buy/sell ratio — Tape e flusso
Questa pagina in altre lingue
Frequently asked questions
- Si possono misurare le dimensioni dei singoli scambi su un grafico footprint?
- Non da una barra footprint aggregata. L'aggregazione conserva il volume scambiato a ogni prezzo ma scarta la sequenza e la dimensione delle singole esecuzioni che lo hanno prodotto. Ciò che resta misurabile è quanto quel volume è concentrato tra i prezzi, ed è ciò che riporta questo indicatore.
- Cosa significa una lettura pari a 0 su trade size distribution?
- Significa che nessun livello di prezzo di quella barra ha portato più volume della soglia percentile, perché il confronto è stretto. Succede quando tutti i livelli pesano più o meno lo stesso, su una barra che ha scambiato a un solo prezzo, e su qualsiasi barra con meno di cinque livelli utilizzabili all'80° percentile predefinito, dove la soglia cade sul livello più pesante stesso. È un valore misurato, non un errore.
- Quale percentile usare per trade size distribution?
- Parti dal valore predefinito di 80, che funziona sulle barre con cinque livelli o più. Prima di cambiarlo, controlla quanti livelli hanno davvero le tue barre: un percentile P richiede almeno 100/(100 − P) livelli prima che un livello possa superare la soglia, quindi 99 è inutilizzabile su una tipica barra footprint. Un percentile vicino a 50 misura quanto è asimmetrica la distribuzione più che quanto è concentrata.