Le moyen le plus rapide de catcher un breakout imminent, c'est de repérer la phase de compression critique de la volatilité couplée à une accumulation de volume sous-jacente, bien avant que le prix ne sorte de sa boîte.
Le problème : Pourquoi tu achètes systématiquement le top
On est tous passés par cette enfer. Tu ouvres ton broker ou ton DEX, tu vois un token à +25% sur les deux dernières heures, tu fomo en long comme un bourrin, et… exactement trois minutes plus tard, le chart se casse la figure comme un pèse. Bravo, tu viens de servir de liquidité de sortie aux mecs positionnés en sous-marin depuis des heures.
La majorité des retail traders agissent comme des moutons : ils réagissent au price action une fois qu'il est déjà fait. Quand le jeton est déjà en train de moon, que les bots d'alerte spamment et que les canaux Telegram hurlent à la « to the moon », les smart money sont déjà en train de TP leurs positions sur tes ordres market. Si tu veux arrêter de financer le PnL des autres, il faut apprendre à entrer quand le chart est chiant au possible et que la volatilité est littéralement au point mort.
La mécanique : Ce qui se passe vraiment avant le pump
Le marché alterne perpétuellement entre deux phases : l'accumulation (compression) et la distribution (expansion). Tu ne peux pas compresser un ressort à l'infini, tôt ou tard, il pète.
Quand un market maker ou un gros fonds monte une position sur un altcoin, il ne peut pas se permettre de faire pumper le prix, sous peine d'exploser son prix moyen d'entrée. Il va donc éponger l'offre disponible tout doucement dans un range hyper étroit. Visuellement sur le chart, ça donne ça :
- Écrasement de l'amplitude : L'écart entre le High et le Low journalier s'effondre.
- Chute de la volatilité historique (HV) : Le chart ressemble à une ligne droite ou une vieille « scie » bien plate.
- Assèchement de l'order book : Les ordres des petits porteurs se font sortir ou se font annuler, le carnet est complètement figé.
- Anomalies sur le Delta de Volume : Le prix ne bouge pas d'un iota, mais à l'intérieur des petites bougies, tu vois passer de gros achats market ou un spike anormal du volume relatif (RVOL).
Dès que le float en circulation est totalement aspiré du carnet, c'est le vide sanitaire. Le moindre ordre market à 50k$ ou 100k$ envoie le jeton sur la lune parce qu'il n'y a plus aucun ordre limite vendeur pour bloquer l'ascension.
Benchmark des métriques de screening
Pour éviter de vous taper 500 charts à la main comme un stakhanoviste, on va filtrer tout ça via des métriques d'écartement mathématique bien précises :
| Métrique | Valeur « Ressort » | Valeur « Explosion » | Traduction en cash |
|---|---|---|---|
| BB Width (20, 2) | < 0.03 - 0.05 | > 0.15 | Volatilité compressée au max, la largeur des bandes de Bollinger est au plus bas depuis 14 à 30 jours. |
| RVOL (Relative Vol) | > 2.2 pendant la compression | > 5.0 | Le prix fait du surplace mais les volumes sont 2x à 3x au-dessus de la moyenne. Quelqu'un est en train d'aspirer le carnet en douce. |
| Keltner / BB Ratio | Inside les canaux | Cassure des bornes | Les bandes de Bollinger sont rentrées entièrement à l'intérieur du canal de Keltner (le setup TTM Squeeze classique). |
| Funding Rate | Proche de 0.00% ou négatif | Spike brutal + ou - | Le retail n'a encore rien capté. Pas de déséquilibre majeur sur le levier. |
| Open Interest (OI) | Stable ou hausse lente | Hausse explosive | L'Open Interest grimpe pendant la phase de flat — c'est du gros capital institutional qui s'installe, pas trois péquenauds en levier 50. |
Le workflow de screening en 30 secondes
Si tu utilises des screener pro (TradingView, Coinglass, ScalpStation ou ton propre outil custom), voici la checklist exacte à appliquer :
- Tri par BBW (Bollinger Bands Width) : Timeframe 15m ou 1h. Tu filtres du plus petit au plus grand.
- Filtre par Volume (24h) : Tu dégages les shitcoins illiquides sous la barre des 5M$–10M$ de volume daily (trop de slippage, impossible de sortir proprement).
- Cross-check RVOL / OI : On cherche la confluences : un BBW au sous-sol combiné à un RVOL 1h ou 15m qui pète les +200-300%.
- Validation de la structure : Tu cartes le chart. Si tu vois un vrai range ultra-resserré de 1-1.5% max avec un flatline parfait du Cumulative Volume Delta, le token est prêt à envoyer la sauce.
Bot d'agrégation Python (Production-Ready)
Voilà le script clé en main pour catcher ces anomalies. Ça tourne sous ccxt, ça pinge le marché futures, ça calcule le TTM Squeeze et le RVOL, puis ça te sort directement en console les paires prêtes à exploser.
import asyncio
import ccxt.async_support as ccxt
import pandas as pd
import numpy as np
# Limitation du nombre de requêtes simultanées
MAX_CONCURRENT_REQUESTS = 20
async def analyze_market(exchange, symbol, semaphore):
async with semaphore:
try:
# Requête pour 100 bougies en timeframe 15m
ohlcv = await exchange.fetch_ohlcv(
symbol,
timeframe='15m',
limit=100
)
if not ohlcv or len(ohlcv) < 50:
return None
df = pd.DataFrame(
ohlcv,
columns=['time', 'open', 'high', 'low', 'close', 'volume']
)
# ===== Bollinger Bands (20, 2) =====
df['sma'] = df['close'].rolling(window=20).mean()
df['std'] = df['close'].rolling(window=20).std()
df['bb_upper'] = df['sma'] + (df['std'] * 2)
df['bb_lower'] = df['sma'] - (df['std'] * 2)
# Protection contre la division par zéro
df['bb_width'] = np.where(
df['sma'] != 0,
(df['bb_upper'] - df['bb_lower']) / df['sma'],
np.nan
)
# ===== Relative Volume (RVOL) =====
df['vol_sma'] = df['volume'].rolling(window=20).mean()
# Protection contre la division par zéro
df['rvol'] = np.where(
df['vol_sma'] != 0,
df['volume'] / df['vol_sma'],
np.nan
)
# Remplacement des inf par des NaN
df.replace([np.inf, -np.inf], np.nan, inplace=True)
# Vérification de l'intégrité des données
if len(df) < 52:
return None
# Dernière bougie fermée
last_width = df['bb_width'].iloc[-2]
last_rvol = df['rvol'].iloc[-2]
last_close = df['close'].iloc[-2]
# Validation NaN
if pd.isna(last_width) or pd.isna(last_rvol):
return None
# Largeur minimale des bandes sur les 50 bougies précédentes
# (en excluant la bougie en cours d'analyse)
historical_widths = df['bb_width'].iloc[-52:-2]
if historical_widths.isna().all():
return None
min_width_50 = historical_widths.min()
# Conditions de détection
is_squeezed = last_width <= (min_width_50 * 1.15)
has_volume_spike = last_rvol >= 2.5
if is_squeezed and has_volume_spike:
return {
'symbol': symbol,
'close': float(last_close),
'bb_width': round(float(last_width), 4),
'rvol': round(float(last_rvol), 2)
}
except Exception as e:
print(f"[ERROR] {symbol}: {e}")
return None
async def main():
exchange = ccxt.binance({
'enableRateLimit': True,
'options': {
'defaultType': 'future'
}
})
semaphore = asyncio.Semaphore(MAX_CONCURRENT_REQUESTS)
try:
await exchange.load_markets()
# Périmètre limité aux perpétuels USDT
symbols = [
symbol
for symbol in exchange.symbols
if symbol.endswith('/USDT:USDT')
]
print(f"[*] Scan en cours sur {len(symbols)} paires Futures...")
tasks = [
analyze_market(exchange, symbol, semaphore)
for symbol in symbols
]
results = await asyncio.gather(*tasks)
hot_targets = [
result
for result in results
if result is not None
]
# Tri par ordre décroissant de RVOL
hot_targets.sort(
key=lambda x: x['rvol'],
reverse=True
)
print("\n=== SETUP IMPULSIFS DÉTECTÉS ===")
if not hot_targets:
print("Aucun setup détecté.")
return
print(
f"{'Ticker':<18} | "
f"{'Prix':<15} | "
f"{'BB Width':<10} | "
f"{'RVOL':<8}"
)
print("-" * 65)
for target in hot_targets:
print(
f"{target['symbol']:<18} | "
f"{target['close']:<15.8f} | "
f"{target['bb_width']:<10} | "
f"{target['rvol']:<8}"
)
finally:
await exchange.close()
if __name__ == '__main__':
asyncio.run(main())Risk Management et exécution : Comment éviter de se faire fumer sur une fausse sortie
Spotter une compression, c'est la moitié du travail. L'autre moitié, c'est d'éviter de se faire liquider ou de prendre un stop inutile quand un market maker envoie un Shakeout (une mèche de piège à liquidité avant le vrai moove).
Interdiction de rentrer « market » à l'aveugle : Repérer un squeeze ne veut pas dire in direct les yeux fermés. Tu rentres soit en ordre limite sur le bas de range (si tu accumules en spot), soit sur confirmation pure (clôture de bougie 5m/15m Hors des bandes de Bollinger avec du gros volume).
Calcul du Stop-Loss :
- Pas de stop « au pif » ni de Stop fixe à 1%. C'est le meilleur moyen de se faire décapiter.
- Utilise l'ATR (Average True Range). On place le stop à une distance de 1.5 * ATR du point d'entrée, bien calé derrière la borne opposée de la zone d'accumulation.
Gestion des Take-Profit (TP) :
- TP1 (50% de la taille du bag) : Sur la première extension correspondant à la largeur totale de la zone d'accumulation (Risk/Reward de 1:2 minimum). On passe la position restante à BE (Break-Even).
- TP2 (les 50% restants) : Trailing stop dynamique en suivant l'EMA9/EMA21 en 15m tant que la tendance reste propre.
Gestion des Bull/Bear Traps : Si le prix casse le range mais que le volume s'effondre sec et que la bougie suivante réintègre la zone : c'est une manipulation. Pas de DCA désespéré, tu coupes ta perte immédiatement.
Garde ça en tête : Un vrai breakout après compression ne laisse pas le temps de gamberger. Si le prix pète le niveau et commence à bégayer ou réintégrer, le move est mort : tu fermes le trade.
Le layer « Alpha » avancé : les signaux invisibles pour 95 % des traders
La majorité des screeners se contentent de chercher une simple compression de prix. Le problème ? Une compression isolee débouche très souvent sur un chop monumental qui vient raser vos stops des deux côtés. Pour viser un winrate propre de 75 à 80 %, il faut impérativement ajouter une deuxième couche de filtrage : l'analyse du contexte sur les dérivés.
1. Déséquilibre Open Interest (OI) & Funding Rate
Le « ressort » parfait se tend lorsque le prix est bloqué dans un range ultra-resserré, alors que le marché futures s'emballe de manière anormale :
- Scénario de Short Squeeze : Le prix compresse dans un mouchoir de poche (range de 1 %). L'Open Interest (OI) explose de 15 à 20 % en l'espace de deux heures. Le Funding Rate plonge dans le rouge vif (par exemple -0.04 %). Traduction : le retail short sauvagement le range en espérant un breakdown. Le Market Maker repère cette mer de stops et de liquidations au-dessus du cours et déclenche un pump d'impulsion dans le sens inverse.
- Scénario de Long Squeeze : L'effet miroir exact. L'OI grimpe, le funding s'envole (+0.05 % ou plus), mais le prix fait du surplace. Il n'y a plus aucune liquidité à aller chercher en haut : l'impulsion va dump pour nettoyer les positions long un peu trop gourmandes.
2. Cascade de compression multi-timeframe (MTF Cascade)
Une impulsion isolée en M15 offre un mouvement classique de 2 à 4 %. En revanche, si cette impulsion s'aligne avec une compression simultanée sur l'unité H1 et H4, on parle de mouv sans retracement pouvant aller de 15 % à plus de 50 %.
Traquez les alts dont le BB Width stagne dans le centile inférieur (les 5 % les plus bas sur 30 jours) en H4, alors qu'un spike de volume anormal déboule en M15 (RVOL > 3.0). C'est exactement le moment où la petite mèche M15 fait sauter la dynamite des UT supérieures.
Script Pine Script clé en main (TradingView v5)
Si vous préférez visualiser les signaux du screener directement sur vos charts TradingView, voici un indicateur prêt à l'emploi. Il met en évidence les zones de compression de volatilité (quand les bandes de Bollinger rentrent dans le canal de Keltner) et balance des alertes dès qu'un volume anormal pointe son nez.
//@version=5
indicator("Quant Squeeze & Volume Trigger [EXPERT v2]", overlay=true, max_labels_count=500)
// ======================================================
// Configuration
// ======================================================
groupBB = "Bollinger Bands"
groupKC = "Keltner Channels"
groupVOL = "Volume"
groupTREND = "Trend Filter"
bbLength = input.int(20, "Longueur BB", minval=1, group=groupBB)
bbMult = input.float(2.0, "Multiplicateur BB", minval=0.1, group=groupBB)
kcLength = input.int(20, "Longueur KC", minval=1, group=groupKC)
kcMult = input.float(1.5, "Multiplicateur KC", minval=0.1, group=groupKC)
rvolThreshold = input.float(2.2, "Seuil RVOL (x)", minval=0.1, group=groupVOL)
emaLength = input.int(200, "EMA Tendance", minval=1, group=groupTREND)
showLongs = input.bool(true, "Afficher LONG", group=groupTREND)
showShorts = input.bool(true, "Afficher SHORT", group=groupTREND)
// ======================================================
// Bollinger Bands
// ======================================================
[bbMiddle, bbUpper, bbLower] = ta.bb(close, bbLength, bbMult)
// Protection contre la division par 0
bbWidth = bbMiddle != 0 ? (bbUpper - bbLower) / bbMiddle : na
// ======================================================
// Keltner Channels
// ======================================================
kcMa = ta.ema(close, kcLength)
// L'ATR est plus fiable pour Keltner
kcAtr = ta.atr(kcLength)
kcUpper = kcMa + (kcAtr * kcMult)
kcLower = kcMa - (kcAtr * kcMult)
// ======================================================
// Relative Volume
// ======================================================
volSma = ta.sma(volume, 20)
rvol = (not na(volSma) and volSma > 0) ? volume / volSma : na
// ======================================================
// Logique TTM Squeeze
// ======================================================
// Bollinger totalement à l'intérieur de Keltner
isSqueezed = bbUpper < kcUpper and bbLower > kcLower
// Squeeze récent
wasSqueezed = isSqueezed[1]
// Sortie de squeeze
squeezeReleased = wasSqueezed and not isSqueezed
// ======================================================
// Filtre de Tendance
// ======================================================
emaTrend = ta.ema(close, emaLength)
bullTrend = close > emaTrend
bearTrend = close < emaTrend
// ======================================================
// Confirmation de Breakout
// ======================================================
// Confirmation par le volume
volumeConfirmed = not na(rvol) and rvol >= rvolThreshold
// Confirmation par le prix
bullBreakout = close > bbUpper
bearBreakout = close < bbLower
// ======================================================
// Logique Anti-Spam
// ======================================================
// Évite les signaux en boucle
var int lastLongBar = na
var int lastShortBar = na
cooldownBars = 10
canLong =
na(lastLongBar) or
(bar_index - lastLongBar > cooldownBars)
canShort =
na(lastShortBar) or
(bar_index - lastShortBar > cooldownBars)
// ======================================================
// Signaux Finaux
// ======================================================
longSignal =
showLongs and
barstate.isconfirmed and
squeezeReleased and
volumeConfirmed and
bullBreakout and
bullTrend and
canLong
shortSignal =
showShorts and
barstate.isconfirmed and
squeezeReleased and
volumeConfirmed and
bearBreakout and
bearTrend and
canShort
if longSignal
lastLongBar := bar_index
if shortSignal
lastShortBar := bar_index
// ======================================================
// Visualisation
// ======================================================
// Couleur de fond pendant le squeeze
bgcolor(
isSqueezed
? color.new(color.orange, 88)
: na,
title="Squeeze Background"
)
// EMA Tendance
plot(
emaTrend,
title="EMA Trend",
color=color.blue,
linewidth=2
)
// LONG
plotshape(
longSignal,
title="Signal LONG",
style=shape.triangleup,
location=location.belowbar,
color=color.lime,
size=size.small,
text="LONG"
)
// SHORT
plotshape(
shortSignal,
title="Signal SHORT",
style=shape.triangledown,
location=location.abovebar,
color=color.red,
size=size.small,
text="SHORT"
)
// ======================================================
// Alertes
// ======================================================
alertcondition(
longSignal,
title="LONG Breakout",
message="LONG breakout detected on {{ticker}}"
)
alertcondition(
shortSignal,
title="SHORT Breakout",
message="SHORT breakout detected on {{ticker}}"
)Anatomie des pièges : distinguer un vrai Breakout d'un Shakeout
La Smart Money sait exactement où se trouvent les stops des traders de squeeze. C'est pourquoi dans environ 40 % des cas, un deviance / fakedown (Spring/Upthrust) se produit juste avant le vrai move.

Comment éviter de servir de liquidité :
Analysez le Delta sur la bougie de mèche. Si le prix casse le bas du range d'accumulation, laisse une longue mèche basse, mais que la Delta Cumulative montre des achats market massifs (bougie rouge avec delta vert), c'est une absorption passive pure et dure. Un gros acheteur limit est en train d'absorber tous les panic sells et les stops du retail.
La règle des 3 bougies : Une vraie impulsion ne réintègre jamais sa zone de compression. Si juste après le breakout, la première ou la deuxième bougie réintègre le range d'origine, coupez immédiatement. C'était un simple liqu-sweep.
Checklist pré-trade (5 secondes avant de cliquer)
Avant de cliquer sur Achat/Vente au premier signal de votre screener, validez ces 5 points :
| Étape | Métrique | Feu Vert (Entry OK) | Red Flag (No Trade) |
|---|---|---|---|
| 1 | Volume 24h | > $10,000,000 | < $2,000,000 (Le slippage va ruiner votre R:R) |
| 2 | Corrélation BTC | Bitcoin range ou suit la dynamique de l'alt | Bitcoin est en train de pump/dump de >1.5 % au même instant |
| 3 | Orderbook Spot/Futures | Pas de gros murs d'ordres limit en face | Un mur de liquidité est posé à seulement 0.5 % du prix actuel |
| 4 | Spread (Bid/Ask) | < 0.05 % | > 0.2 % (Carnet illiquide) |
| 5 | Espace jusqu'au niveau clé | Marge suffisante pour viser un Risk:Reward d'au moins 1:3 | Le prix bloque déjà contre une résistance Weekly (W1) |
Le mot de la fin
Un screener de volatilité n'est pas une boule de cristal. C'est avant tout un outil de productivité fait pour éliminer 98 % du bruit du marché en trente secondes chrono, afin de concentrer toute votre attention sur les 2 % d'actifs où une baleine est en train de placer ses pions.
Ne jouez pas aux devins au milieu du squeeze sans confirmation du volume et du delta. Laissez le marché abattre ses cartes en premier, entrez sur l'impulsion confirmée, et sécurisez vos 3 à 8 % de hausse avec un risque maîtrisé.