Naciśnij ESC, aby zamknąć

Skaner Zmienności Kryptowalut: Znajdź Wybicia w 30s

Najszybszym sposobem na złapanie rodzącego się wybicia jest śledzenie fazy krytycznej kompresji zmienności na tle ukrytej akumulacji wolumenu, zanim cena w ogóle wystrzeli.

Problem: Dlaczego zawsze kupujesz na samej górce

Każdy trader przerabiał to piekło. Odpalasz giełdę, widzisz coina z +25% w ostatnie dwie godziny, chciwie pakujesz się w longa, i… dokładnie trzy minuty później wykres zaczyna lecieć w dół jak kamień. Właśnie zostałeś płynnością dla gości, którzy wchodzili po cichu.

Większość uczestników rynku działa jak stado: reagują na sam fakt ruchu. Kiedy aktywo już leci, powiadomienia wyją, a na kanałach Telegram krzyczą o „rakiecie”, grubas już zamyka swoje pozycje o Twoje rynkowe zlecenia (market orders). Żeby przestać sponsorować cudze zyski, musisz nauczyć się wchodzić w pozycję wtedy, gdy wykres wygląda śmiertelnie nudno, a zmienność dosłownie „umarła”.

Mechanika: Co naprawdę dzieje się przed impulsem

Rynek nieustannie przechodzi przez dwie fazy: akumulację (ściskanie) i dystrybucję (rozszerzanie). Nie da się w nieskończoność ściskać sprężyny — prędzej czy później wystrzeli.

Kiedy market maker albo duży fundusz buduje pozycję na altcoinie, nie może ciągnąć ceny w górę, bo zepsułby sobie średnią cenę wejścia. Delikatnie wchłania całą podaż w wąskim zakresie cenowym. W tym momencie na wykresie dzieje się coś takiego:

  • Wygasanie amplitudy: Różnica między dziennym szczytem a dołkiem gwałtownie spada.
  • Spadek zmienności historycznej (HV): Wykres zamienia się w płaską „piłę” albo wąski konsolidacyjny flaut.
  • Czyszczenie arkusza (Orderbooka): Zlecenia drobnych graczy są wybijane albo zdejmowane, rynek zamiera.
  • Anomalie w Volume Delta: Cena stoi w miejscu, ale wewnątrz wąskiego zakresu świec zaczynają wchodzić mocne zakupy z rynku (market buy) albo widać anomalny wzrost względnego wolumenu (RVOL).

Gdy tylko wolny float (coiny w swobodnym obrocie) zostanie zjedzony z arkusza, pojawia się próżnia. Jakikolwiek strzał rzędu 50k–100k USD zleceniem rynkowym wysyła cenę w kosmos, bo w orderbooku po prostu nie ma już gęstych limitów.

Porównanie wskaźników do skreeningu

Żeby nie przeklikiwać 500 wykresów ręcznie, ustawiamy filtrowanie pod konkretne odchylenia matematyczne:

WskaźnikWartość dla „Sprężyny”Wartość dla „Wybicia”Co to oznacza w praktyce (język kasy)
BB Width (20, 2)< 0.03 - 0.05> 0.15Zmienność ściśnięta do granic możliwości, szerokość wstęg Bollingera na dołkach z ostatnich 14–30 dni.
RVOL (Relative Vol)> 2.2 przy kompresji> 5.0Cena idzie bokiem, ale obroty są 2-3 razy wyższe niż norma. Ktoś po cichu „odkurza” arkusz.
Keltner / BB RatioWewnątrz kanałówWybicie krawędziWstęgi Bollingera całkowicie weszły do wnętrza Kanału Keltnera (klasyczny TTM Squeeze).
Funding RateOkoło 0.00% lub ujemnyGwałtowny skok na + lub -Ulica jeszcze nie ogarnia, co się święci. Brak przegrzania na dźwigni.
Open Interest (OI)Stabilny albo łagodnie rośnieEksplozywny wzrostOtwarte pozycje rosną podczas konsolidacji — wchodzi gruby kapitał, a nie zwykły detal.

Algorytm szukania w 30 sekund

Jeśli używasz profesjonalnych skanerów (TradingView, Coinglass, ScalpStation czy własnego softu), Twój checklist wygląda tak:

  • Sortowanie po BBW (Bollinger Bands Width): Ustawiamy interwał 15m albo 1h. Filtrujemy listę od najniższych wartości do najwyższych.
  • Filtr Volume (24h): Wyrzucamy martwy shitcoinowy śmieć z dobowym wolumenem poniżej $5M–$10M (tam nie ma płynności, po prostu zjedzą Cię poślizgi cenowe).
  • Weryfikacja RVOL / OI: Szukamy dopasowania: BBW na samym dole listy, a RVOL na 1h czy 15m wystrzelił powyżej 200-300%.
  • Ocena struktury: Otwieramy wykres. Jeśli widzimy idealne „szpilki” albo konsolidację w granicach 1-1.5% z nagłym wyprostowaniem skumulowanej delty — coin jest w stanie tuż przed impulsem.

Profesjonalny agregator w Pythonie (Production-Ready)

Oto gotowy skrypt do wyłapywania takich anomalii. Używa biblioteki ccxt, pobiera dane z rynku futures, liczy TTM Squeeze oraz RVOL, a na koniec wypluwa w konsoli gotową listę coinów gotowych do wybicia.

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())

Zarządzanie ryzykiem i mechanika wejścia: Jak nie wyczyścić depo na fałszywym strzale

Znalezienie ściśnięcia to dopiero połowa sukcesu. Druga połowa to nie wylecieć na stopie, kiedy duży gracz postanowi zrobić Shakeout (fałszywe wybicie w celu zebrania płynności przed właściwym ruchem).

Nie wchodź „z rynkowego” (market) przed wybiciem: Czekanie na kompresję to nie ładowanie się w pozycję na ślepo. Wchodź albo zleceniem limit przy dolnej krawędzi konsolidacji (jeśli budujesz pozycję na spocie), albo po potwierdzeniu (zamknięcie świecy 5m/15m POZA obszarem wstęgi Bollingera z wyraźnym wolumenem).

Wyliczanie Stop-Lossa:

  • Nie stawiaj stopa „na oko” ani na sztywne 1%.
  • Używaj wskaźnika ATR (Average True Range). Stopa stawiamy na odległość 1.5 * ATR od punktu wejścia, za przeciwległą krawędzią strefy akumulacji.

Realizacja zysków (Take Profit):

  • TP1 (50% pozycji): W odległości pierwszego impulsu równego pełnej szerokości konsolidacji (R:R 1:2). Przesunięcie reszty pozycji na BE (break-even).
  • TP2 (50% pozycji): Kaskadowy trailing stop po 15m EMA9/EMA21, dopóki trwa czysty trend.

Ochrona przed fałszywym wyciśnięciem (squeeze): Jeśli cena wybiła krawędź konsolidacji, ale wolumen momentalnie opadł, a kolejna świeca wraca do wnętrza zakresu — to manipulacja. Nie uśredniaj, tnij stratę od razu.

Zapamiętaj: prawdziwy impuls po kompresji nie daje czasu na zastanawianie się. Jeśli cena wybiła zakres i utknęła, ruchu z tego nie będzie — zamykaj pozycję.

Zaawansowana warstwa „Alpha”: Ukryte sygnały, których nie widzi 95% traderów

Większość screenerów szuka po prostu банального ścisku ceny (kompresji). Jednak samo zawężenie zakresu często kończy się zwykłym wycinaniem stopów w obie strony. Żeby wyciągnąć winrate na poziom 75-80%, potrzebujesz drugiej warstwy filtrowania – dogłębnej analizy kontekstu z rynku instrumentów pochodnych.

1. Disbalans Otwartego Interesu (OI) i Stawki Finansowania (Funding Rate)

Idealnie napięta „sprężyna” powstaje wtedy, gdy cena utknęła w ciasnej konsolidacji, ale na kontraktach futures dzieje się coś nienaturalnego:

  • Scenariusz Short Squeeze: Cena kisi się w 1-procentowym przedziale. Otwarty Interes (OI) wystrzeliwuje o 15-20% w zaledwie parę godzin. Funding Rate leci mocno pod kreskę (np. -0.04%). Oznacza to, że ulicznicy agresywnie ładowani są w shorty wewnątrz płaskiego ruchu, licząc na wybicie w dół. Market maker widzi tę całą ścianę stop lossów i likwidacji u góry, po czym odpala potężny impuls w przeciwnym kierunku.
  • Scenariusz Long Squeeze: Układ lustrzany. OI rośnie, funding rozdmuchuje się na plusie (+0.05% i więcej), a cena stoi w miejscu. Na górze nie ma już płynności – impuls pójdzie w dół, czyszcząc po drodze nieostrożne longi.

2. Wielotramowa kaskada kompresji (MTF Cascade)

Impuls na wykresie M15 daje zazwyczaj ruch rzędu 2-4%. Jednak ten sam impuls, który nałoży się na ścisk na interwałach H1 i H4, potrafi wygenerować od 15% do 50% bezadpływowego rajdu.

Szukaj coinów, na których BB Width znajduje się w dolnym 5-procentowym kwantylu z ostatnich 30 dni na interwale H4, a jednocześnie na M15 wchodzi właśnie potężny skok wolumenu (RVOL > 3.0). To dokładnie ten moment, w którym niski interwał zrywa zawleczkę w granacie wysokiego interwału.

Gotowy skrypt Pine Script (TradingView v5)

Jeśli wolisz wizualizować sygnały ze screenera bezpośrednio na wykresach TradingView, wrzuć ten wskaźnik. Podświetla on strefy kompresji zmienności (gdy wstęgi Bollingera wchodzą wewnątrz Kanału Keltnera) i generuje alerty przy pojawieniu się anomaliów wolumenowych.

//@version=5
indicator("Quant Squeeze & Volume Trigger [EXPERT v2]", overlay=true, max_labels_count=500)
// ======================================================
// Ustawienia
// ======================================================
groupBB = "Bollinger Bands"
groupKC = "Keltner Channels"
groupVOL = "Volume"
groupTREND = "Trend Filter"
bbLength      = input.int(20, "BB Długość", minval=1, group=groupBB)
bbMult        = input.float(2.0, "BB Mnożnik", minval=0.1, group=groupBB)
kcLength      = input.int(20, "KC Długość", minval=1, group=groupKC)
kcMult        = input.float(1.5, "KC Mnożnik", minval=0.1, group=groupKC)
rvolThreshold = input.float(2.2, "Próg RVOL (x)", minval=0.1, group=groupVOL)
emaLength     = input.int(200, "EMA Trendu", minval=1, group=groupTREND)
showLongs     = input.bool(true, "Pokazuj LONG", group=groupTREND)
showShorts    = input.bool(true, "Pokazuj SHORT", group=groupTREND)
// ======================================================
// Bollinger Bands
// ======================================================
[bbMiddle, bbUpper, bbLower] = ta.bb(close, bbLength, bbMult)
// Zabezpieczenie przed dzieleniem przez 0
bbWidth = bbMiddle != 0 ? (bbUpper - bbLower) / bbMiddle : na
// ======================================================
// Keltner Channels
// ======================================================
kcMa    = ta.ema(close, kcLength)
// ATR jest pewniejszy dla Keltnera
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 całkowicie wewnątrz Keltnera
isSqueezed = bbUpper < kcUpper and bbLower > kcLower
// Czy ścisk był niedawno
wasSqueezed = isSqueezed[1]
// Wyjście ze ścisku
squeezeReleased = wasSqueezed and not isSqueezed
// ======================================================
// Trend Filter
// ======================================================
emaTrend = ta.ema(close, emaLength)
bullTrend = close > emaTrend
bearTrend = close < emaTrend
// ======================================================
// Breakout Confirmation
// ======================================================
// Potwierdzenie wolumenem
volumeConfirmed = not na(rvol) and rvol >= rvolThreshold
// Potwierdzenie ceną
bullBreakout = close > bbUpper
bearBreakout = close < bbLower
// ======================================================
// Anti-Spam Logic
// ======================================================
// Blokada sygnałów świeca po świecy
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)
// ======================================================
// Sygnały końcowe
// ======================================================
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
// ======================================================
// Wizualizacja
// ======================================================
// Tło podczas squeeze
bgcolor(
    isSqueezed
    ? color.new(color.orange, 88)
    : na,
    title="Squeeze Background"
)
// EMA trendu
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"
)
// ======================================================
// Alerty
// ======================================================
alertcondition(
    longSignal,
    title="LONG Breakout",
    message="LONG breakout detected on {{ticker}}"
)
alertcondition(
    shortSignal,
    title="SHORT Breakout",
    message="SHORT breakout detected on {{ticker}}"
)

Anatomia pułapek: Jak odróżnić prawdziwe wybicie od Shakeoutu

Grubi gracze doskonale wiedzą, gdzie poustawiane są stopy osób handlujących kompresję zmienności. Dlatgo w 40% przypadków przed właściwym ruchem następuje fałszywka / wybitka (Spring/Upthrust).

Shakeout
 

Jak nie dać się złapać na ten haczyk:

Obserwuj deltę świecy wybijającej. Jeśli cena przebija dolną granicę konsolidacji, świeca zostawia długi knot od dołu, a Skumulowana Delta pokazuje potężne kupowanie rynkiem (czerwona świeca z zieloną deltą) – mamy do czynienia z pasywną absorpcją (Absorption). Duży gracz limitami wchłonął całą sprzedaż ze stop lossów.

Zasada 3 świec: Prawdziwy impuls nie wraca do strefy kompresji. Jeśli po wybiciu krawędzi cena już pierwszą lub drugą świecą wraca do boczniaka, zamykaj pozycję bez zastanowienia. To było zwykłe polowanie na płynność.

Szybki check-list przed wejściem (5 sekund przed kliknięciem)

Zanim załadujesz się w pozycję na podstawie sygnału ze screenera, przefiltruj coina przez tę listę kontrolną:

KrokCo sprawdzamyWarunek do wejściaCzerwona flaga (Anuluj)
1Wolumen dobowy (24h Vol)> $10,000,000< $2,000,000 (Slippage zje cały zysk)
2Zachowanie względem BTCBitcoin w konsolidacji lub idzie za coinemBitcoin właśnie robi dump/pump o >1.5%
3Księga zleceń spot/futures (Książka)Brak dużych ścian limitowych na drodzeŚciana zleceń limit zaledwie 0.5% od aktualnej ceny
4Spread (Bid/Ask)< 0.05%> 0.2% (Słaba płynność)
5Miejsce do najbliższego poziomuManoewr daje miejsce na R:R minimum 1:3Cena wbiła się prosto w poziom tygodniowy (W1)

Pragmatyczne podsumowanie

Screenery zmienności to nie kryształowa kula do przepowiadania przyszłości. To po prostu narzędzie do oszczędzania Twojego czasu, które pozwala w pół minuty odsiać 98% rynkowego szumu i skupić się na tych 2% aktywów, gdzie właśnie rozgrywa się gruba akcja.

Nie zgaduj kierunku wewnątrz ścisku bez jasnego potwierdzenia w wolumenie i delcie. Daj rynkowi najpierw odkryć karty, wejdź na potwerdzonym impulsie i zgarnij swoje 3-8% ruchu przy minimalnym ryzyku.

Podsumuj ten wpis na blogu za pomocą:

FAQ

Wykrywanie kryptowalut przed wybuchem zmienności wymaga filtrowania aktywów pod kątem ściskania wstęg Bollingera (BB Width poniżej 0.05) połączonego z nagłym skokiem wolumenu względnego (RVOL > 2.5). Taki układ sygnalizuje akumulację i wyczyszczenie arkusza zleceń z płynności przez instytucjonalnego gracza przed ekspansją ceny. Analitycy monitorują interwały 15m i 1h, weryfikując rosnący Open Interest oraz neutralny Funding Rate, co gwarantuje brak przelwarowania rynku przez drobnych inwestorów.

Optymalne konfigurowanie skanera zmienności opiera się na połączeniu wstęg Bollingera (okres 20, odchylenie 2.0) z kanałami Keltnera (okres 20, mnożnik ATR 1.5) do wyizolowania stanu TTM Squeeze. Skaner musi filtrować wolumen dobowy powyżej 10 mln USD w celu uniknięcia poślizgu cenowego, wyłapując szerokość wstęgi poniżej 0.05 przy wskaźniku RVOL powyżej 2.2. Zastosowanie filtra trendu EMA 200 na interwale 15m eliminuje sygnały przeciwtrendowe i fałszywe wejścia w trakcie konsolidacji.

Prawdziwe wybicie utrzymuje cenę zamknięcia poza zakresem zmienności przy stałej ekspansji wskaźnika Cumulative Volume Delta (CVD), podczas gdy fałszywy impuls błyskawicznie wraca do wnętrza konsolidacji. Prawidłowe wyjście z zakresu nie pozwala cenie na ponowny powrót do strefy ściskania w ciągu dwóch do trzech świec. Jeśli skok przebija granicę, ale pokazuje agresywną pasywną absorpcję ze strony zleceń limit, animator rynku zebrał płynność ze zleceń stop przed odwróceniem kierunku.
Piter Wacker

I am a trading specialist with expertise in market analysis, risk management, and investment strategies. I focus on identifying opportunities, executing trades with discipline, and delivering consistent results.

...

Dodaj opinię

Twój adres e-mail nie zostanie opublikowany. Obowiązkowe pola są oznaczone*