Самый быстрый способ поймать зарождающийся пробой - отслеживать фазу критического сжатия волатильности на фоне скрытого накопления объема еще до того, как цена сорвется с места.
Проблема: Почему ты всегда покупаешь на вершине
Каждый трейдер проходил через этот ад. Ты открываешь биржу, видишь монету с +25% за последние два часа, жадно открываешь лонг, и… ровно через три минуты график начинает камнем лететь вниз. Ты стал ликвидностью для тех, кто заходил тихо.
Большинство участников рынка работают как толпа: они реагируют на факт движения. Когда актив уже летит, информеры гудят, а в Telegram-каналах орут про «ракету», крупный игрок уже закрывает свои позиции об твои маркет-ордера. Чтобы перестать спонсировать чужие профиты, нужно научиться заходить в актив тогда, когда график выглядит максимально скучно, а волатильность буквально «умерла».
Механика: Что на самом деле происходит перед импульсом
Рынок перманентно сменяет две фазы: накопление (сжатие) и распределение (расширение). Нельзя бесконечно сжимать пружину, рано или поздно она выстрелит.
Когда маркетмейкер или крупный фонд собирает позицию по альткоину, ему нельзя двигать цену вверх, иначе он ухудшит собственную среднюю точку входа. Он аккуратно поглощает все предложение в узком диапазоне. В этот момент на графике происходит следующее:
- Затухание амплитуды: Разница между дневным максимумом и минимумом стремительно падает.
- Падение исторической волатильности (HV): График превращается в ровную «пилу» или узкий флэт.
- Осушение стакана: Заявки мелких участников выбиваются или снимаются, рынок замирает.
- Аномалии в Volume Delta: Цена стоит на месте, но внутри узкого свечного диапазона начинают проскакивать крупные покупки по маркету или аномальный рост относительного объема (RVOL).
Как только свободный float (монеты в свободном обращении) выедается из стакана, наступает вакуум. Любой толчок на $50k-$100k в маркет-ордер отправляет цену в космос, потому что плотных лимиток в стакане просто не осталось.
Сравнительный анализ метрик для скрининга
Чтобы не листать 500 графиков вручную, мы настраиваем фильтрацию по определенным математическим отклонениям:
| Метрика | Значение «Пружины» | Значение «Взрыва» | Что это значит на языке денег |
|---|---|---|---|
| BB Width (20, 2) | < 0.03 - 0.05 | > 0.15 | Волатильность сжалась до предела, ширина полос Боллинджера минимальна за 14–30 дней. |
| RVOL (Relative Vol) | > 2.2 при сужении | > 5.0 | Цена стоит в боковике, но объемы в 2-3 раза выше нормы. Кто-то тихо «пылесосит» стакан. |
| Keltner / BB Ratio | Внутри каналов | Пробой границы | Полосы Боллинджера полностью вошли внутрь Канала Кельтнера (классический TTM Squeeze). |
| Funding Rate | Около 0.00% или negative | Резкий уход в + или - | Толпа еще не поняла, что происходит. Нет перекоса по плечам. |
| Open Interest (OI) | Стабилен или плавно растет | Взрывной рост | Открытый интерес растет во флэте — заходят серьезные деньги, а не просто розница. |
Алгоритм поиска за 30 секунд
Если ты используешь профессиональные скринеры (TradingView, Coinglass, ScalpStation или собственное ПО), твой чек-лист выглядит так:
- Сортировка по BBW (Bollinger Bands Width): Выставляем таймфрейм 15m или 1h. Фильтруем список от самых низких значений к высоким.
- Фильтр по Volume (24h): Исключаем мертвый щиткоин-мусор с суточным объемом меньше $5M–$10M (там нет ликвидности, тебя просто закроют о проскальзывание).
- Проверка RVOL / OI: Ищем совпадение: BBW внизу списка, а RVOL на 1h или 15m подскочил выше 200-300%.
- Оценка структуры: Открываем график. Если видим ровное «шило» или флэт в рамках 1-1.5% с резким выравниванием кумулятивной дельты — монета в пре-импульсном состоянии.
Профессиональный Python-агрегатор (Production-Ready)
Вот готовый скрипт для поиска аномалий. Он использует ccxt, запрашивает данные по фьючерсному рынку, считает TTM Squeeze и RVOL, после чего выдает в консоль готовый список монет, готовых к пробою.
import asyncio
import ccxt.async_support as ccxt
import pandas as pd
import numpy as np
# Ограничение количества одновременных запросов
MAX_CONCURRENT_REQUESTS = 20
async def analyze_market(exchange, symbol, semaphore):
async with semaphore:
try:
# Запрашиваем 100 свечей на 15-минутном таймфрейме
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)
# Защита от деления на 0
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()
# Защита от деления на 0
df['rvol'] = np.where(
df['vol_sma'] != 0,
df['volume'] / df['vol_sma'],
np.nan
)
# Заменяем inf на NaN
df.replace([np.inf, -np.inf], np.nan, inplace=True)
# Проверяем, что данных достаточно
if len(df) < 52:
return None
# Последняя закрытая свеча
last_width = df['bb_width'].iloc[-2]
last_rvol = df['rvol'].iloc[-2]
last_close = df['close'].iloc[-2]
# Проверка на NaN
if pd.isna(last_width) or pd.isna(last_rvol):
return None
# Минимальная ширина полос за предыдущие 50 свечей
# НЕ включая анализируемую свечу
historical_widths = df['bb_width'].iloc[-52:-2]
if historical_widths.isna().all():
return None
min_width_50 = historical_widths.min()
# Условия поиска
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()
# Только USDT perpetual futures
symbols = [
symbol
for symbol in exchange.symbols
if symbol.endswith('/USDT:USDT')
]
print(f"[*] Сканирование {len(symbols)} пар на фьючерсном рынке...")
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
]
# Сортировка по RVOL
hot_targets.sort(
key=lambda x: x['rvol'],
reverse=True
)
print("\n=== НАЙДЕННЫЕ МОНЕТЫ ПОД ИМПУЛЬС ===")
if not hot_targets:
print("Совпадений не найдено.")
return
print(
f"{'Символ':<18} | "
f"{'Цена':<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())Риск-менеджмент и механика входа: Как не слить депозит на ложном выстреле
Находить сжатие - это только половина дела. Вторая половина - не вылететь по стопу, когда крупный игрок решит сделать Shakeout (ложный пробой для сбора ликвидности перед реальным движением).
Не заходи «по маркету» до пробоя: Ждать сжатия - не значит прыгать в позицию в слепую. Заходи либо лимитным ордером у нижней границы флэта (если набираешь спот), либо на подтверждении (закрытие 5m/15m свечи ЗА пределами полосы Боллинджера с объемом).
Расчет стоп-лосса:
- Не ставь стоп «на глаз» или фиксированные 1%.
- Используй метрику ATR (Average True Range). Стоп выставляется на расстояние 1.5 * ATR от точки входа за противоположную границу диапазона накопления.
Фиксация прибыли (Take Profit):
- TP1 (50% позиции): На расстоянии первого импульса, равного полной ширине накопления (1:2 к риску). Перевод остатка в бу.
- TP2 (50% позиции): Каскадный трейлинг-стоп по 15m EMA9/EMA21, пока идет истинный тренд.
Защита от ложного сквиза: Если цена выбивает границу консолидации, но объемы моментально падают, а следующая свеча возвращается внутрь диапазона - это манипуляция. Не усредняйся, зафиксируй убыток сразу.
Запомни: истинный импульс после сжатия не дает раздумий. Если цена пробила диапазон и застряла, движения не будет, закрывай позицию.
Продвинутый «Альфа»-слой: Скрытые сигналы, которые не видят 95% трейдеров
Большинство скринеров ищут только банальное сужение цены. Но одно лишь сужение часто приводит к пиле, которая забирает стопы в обе стороны. Чтобы повысить винрейт до 75-80%, нужен второй слой фильтрации - анализ деривативного контекста.
1. Дисбаланс Открытого Интереса (OI) и Ставки Финансирования (Funding Rate)
Идеальная «пружина» формируется, когда цена зажата в узком диапазоне, но на фьючерсах происходит аномальная активность:
- Сценарий шорт-сквиза: Цена сжимается в коридоре 1%. Открытый интерес (OI) растет на 15-20% за пару часов. Funding Rate уходит в глубокий минус (например, -0.04%). Это значит, что мелкие трейдеры агрессивно шортят флэт, ожидая пробоя вниз. Маркетмейкер видит эту стену стопов и ликвидаций вверху и запускает импульс в противоположную сторону.
- Сценарий лонг-сквиза: Все зеркально. OI растет, фандинг раздувается в плюс (+0.05% и выше), цена стоит. Вверху ликвидности нет - импульс пойдет вниз, снося неосторожные лонги.
2. Мульти-таймфрейменный каскад сжатия (MTF Cascade)
Импульс на 15-минутном графике дает движение в 2-4%. Импульс, который совпал со сжатием на 1-часовом и 4-часовом таймфреймах, дает от 15% до 50% без откатов.
Ищите монеты, у которых BB Width находится в нижнем 5%-ном квантиле за последние 30 дней на 4H, но при этом на 15M прямо сейчас происходит всплеск объема (RVOL > 3.0). Это момент, когда младший таймфрейм срывает чеку с чеки старшего.
Готовый скрипт Pine Script (TradingView v5)
Если вы предпочитаете визуализировать сигналы скринера прямо на графиках TradingView, используйте этот индикатор. Он подсвечивает зоны сжатия волатильности (когда полосы Боллинджера входят внутрь Канала Кельтнера) и выдает алерты при появлении аномального объема.
//@version=5
indicator("Quant Squeeze & Volume Trigger [EXPERT v2]", overlay=true, max_labels_count=500)
// ======================================================
// Настройки
// ======================================================
groupBB = "Bollinger Bands"
groupKC = "Keltner Channels"
groupVOL = "Volume"
groupTREND = "Trend Filter"
bbLength = input.int(20, "BB Длина", minval=1, group=groupBB)
bbMult = input.float(2.0, "BB Множитель", minval=0.1, group=groupBB)
kcLength = input.int(20, "KC Длина", minval=1, group=groupKC)
kcMult = input.float(1.5, "KC Множитель", minval=0.1, group=groupKC)
rvolThreshold = input.float(2.2, "Порог RVOL (x)", minval=0.1, group=groupVOL)
emaLength = input.int(200, "EMA Тренда", minval=1, group=groupTREND)
showLongs = input.bool(true, "Показывать LONG", group=groupTREND)
showShorts = input.bool(true, "Показывать SHORT", group=groupTREND)
// ======================================================
// Bollinger Bands
// ======================================================
[bbMiddle, bbUpper, bbLower] = ta.bb(close, bbLength, bbMult)
// Защита от деления на 0
bbWidth = bbMiddle != 0 ? (bbUpper - bbLower) / bbMiddle : na
// ======================================================
// Keltner Channels
// ======================================================
kcMa = ta.ema(close, kcLength)
// ATR надежнее для 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
// ======================================================
// TTM Squeeze Logic
// ======================================================
// Bollinger полностью внутри Keltner
isSqueezed = bbUpper < kcUpper and bbLower > kcLower
// Было ли сжатие недавно
wasSqueezed = isSqueezed[1]
// Выход из сжатия
squeezeReleased = wasSqueezed and not isSqueezed
// ======================================================
// Trend Filter
// ======================================================
emaTrend = ta.ema(close, emaLength)
bullTrend = close > emaTrend
bearTrend = close < emaTrend
// ======================================================
// Breakout Confirmation
// ======================================================
// Подтверждение объемом
volumeConfirmed = not na(rvol) and rvol >= rvolThreshold
// Подтверждение ценой
bullBreakout = close > bbUpper
bearBreakout = close < bbLower
// ======================================================
// Anti-Spam Logic
// ======================================================
// Запрещаем сигналы подряд
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)
// ======================================================
// Финальные сигналы
// ======================================================
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
// ======================================================
// Визуализация
// ======================================================
// Фон во время squeeze
bgcolor(
isSqueezed
? color.new(color.orange, 88)
: na,
title="Squeeze Background"
)
// EMA тренда
plot(
emaTrend,
title="EMA Trend",
color=color.blue,
linewidth=2
)
// LONG
plotshape(
longSignal,
title="LONG Signal",
style=shape.triangleup,
location=location.belowbar,
color=color.lime,
size=size.small,
text="LONG"
)
// SHORT
plotshape(
shortSignal,
title="SHORT Signal",
style=shape.triangledown,
location=location.abovebar,
color=color.red,
size=size.small,
text="SHORT"
)
// ======================================================
// Alerts
// ======================================================
alertcondition(
longSignal,
title="LONG Breakout",
message="LONG breakout detected on {{ticker}}"
)
alertcondition(
shortSignal,
title="SHORT Breakout",
message="SHORT breakout detected on {{ticker}}"
)Анатомия ловушек: Отличие истинного пробоя от Shakeout
Крупный игрок прекрасно знает, где стоят стопы тех, кто торгует сжатие волатильности. Поэтому в 40% случаев перед реальным движением происходит заколом (Spring/Upthrust).

Как не попасться в эту ловушку:
Смотрите на Delta свечи заколы. Если цена пробивает нижнюю границу накопления, свеча рисует длинную тень снизу, а Кумулятивная Дельта показывает мощнейшие покупки по маркету (красная свеча с зеленой дельтой) - это пассивное поглощение (Absorption). Крупный лимитный покупатель принял в себя все стопы продавших.
Правило 3 свечей: Истинный импульс не возвращается в диапазон сжатия. Если после пробоя границы цена первой же или второй свечой вваливается обратно в боковик, закрывайте позицию немедленно. Это был сбор ликвидности.
Чек-лист предторговой проверки (5 секунд до клика)
Перед тем как войти в сделку по сигналу скринера волатильности, быстро прогоните монету по этому списку:
| Шаг | Что проверяем | Норма для входа | Опасный сигнал (Отмена) |
|---|---|---|---|
| 1 | Суточный объем (24h Vol) | > $10,000,000 | < $2,000,000 (Проскальзывание сожрет профит) |
| 2 | Положение к BTC | Биткоин флэтует или идет за монетой | Биткоин дампят/пампят на >1.5% прямо сейчас |
| 3 | Стакан спота/фьючерсов | Отсутствие крупных лимитных плотностей впереди | Стена из лимиток в 0.5% от текущей цены |
| 4 | Спред (Bid/Ask) | < 0.05% | > 0.2% (Низкая ликвидность) |
| 5 | Расстояние до ближайшего уровня | Есть зазор для движения минимум 1:3 | Цена уже уперлась в недельный уровень |
Прагматичный итог
Скринеры волатильности - это не хрустальный шар, который предсказывает будущее. Это инструмент экономии вашего времени, позволяющий за полминуты отсеять 98% рыночного шума и сфокусироваться на тех 2% активов, где прямо сейчас происходит завязка крупной сделки.
Не пытайтесь угадать направление движения внутри сжатия без подтверждения объемом и дельтой. Дайте рынку показать свои карты первым, зайдите на подтвержденном импульсе и заберите свои 3-8% движения с минимальным риском.