Zpět na domů

Automatizace hledání zón supply demand na Bybit

Systém automatizuje hledání zón supply/demand na Bybit prostřednictvím order a rejection blocks s ATR filtry. Potvrzení vstupu pinbarem na 5m-TF s odesláním grafů do Telegramu. Kompletní rozbor kódu pro middle/senior vývojáře.

Python-bot: zóny poptávky/nabídky Bybit + Telegram
Advertisement 728x90

Automatizovaný systém pro vyhledávání zón nabídky a poptávky s Telegram upozorněními na Bybit

Systém v Pythonu skenuje všechny USDT páry na Bybit, identifikuje zóny poptávky a nabídky podle konceptu Smart Money, sleduje návraty ceny s formováním pinbar a okamžitě odesílá obchodní signály do Telegramu s označením grafu. Zpracování stovek aktiv trvá minuty místo hodin manuální analýzy.

Logika je postavena na řetězci: detekce zóny → návrat ceny → reakce ve formě price action → generování signálu. Zóny jsou filtrovány podle ATR, průrazů a překryvů pro vyloučení neaktuálních úrovní.

Teorie zón nabídky a poptávky

Zóny likvidity jsou klíčové oblasti, kde dochází k akumulaci pozic a následnému impulsu. Zóny poptávky se formují tam, odkud cena agresivně rostla, zóny nabídky odkud prudce klesala. Signál vzniká při návratu ceny do zóny s potvrzením pinbar (svíce s dlouhým knotem).

Google AdInline article slot

Kritéria platnosti zón:

  • Impuls před zónou > 2 ATR
  • Impuls po zóně > 2 ATR
  • Velikost zóny 1–6 ATR
  • Absence průrazu po formování
MAX_ZONE_ATR = 7
MIN_ZONE_ATR = 1
LOOKBACK_PRE = 8
LOOKAHEAD_POST = 8
MIN_PRE_MOVE_ATR = 2
MIN_POST_MOVE_ATR = 2
MIN_ZONE_SIZE_ATR = 1.0
MAX_ZONE_SIZE_ATR = 6.0

Parametry nastavují citlivost: 4H-timeframe pro zóny, ATR-perioda 100 pro hodnocení volatility, skenování každých 300 sekund.

Integrace s Bybit API

Systém načítá seznam symbolů a historické svíce:

Google AdInline article slot
def get_symbols():
    data = client.get_instruments_info(category="linear")
    symbols = []
    for item in data["result"]["list"]:
        if item["quoteCoin"] == "USDT":
            symbols.append(item["symbol"])
    return symbols

def get_klines(symbol, interval, limit):
    data = client.get_kline(
        category="linear",
        symbol=symbol,
        interval=interval,
        limit=limit
    )
    klines = data["result"]["list"]
    klines.reverse()  # od starých k novým
    return klines

Filtrují se pouze USDT páry. Data jsou zpracována v pandas DataFrame s vypočteným ATR.

Detekce order blocks

Order blocks jsou základní struktury pro zóny. Demand OB: medvědí svíce za ní následuje býčí impuls nad high předchozí.

def detect_order_blocks(df):
    for i in range(1, len(df)):
        o1 = df.open.iloc[i-1]
        c1 = df.close.iloc[i-1]
        h1 = df.high.iloc[i-1]
        l1 = df.low.iloc[i-1]
        o2 = df.open.iloc[i]
        c2 = df.close.iloc[i]
        atr = df.atr.iloc[i]

        # DEMAND OB
        if c1 < o1 and c2 > o2 and c2 > h1:
            impulse = c2 - l1
            if impulse > atr * 1.5:
                zones.append({
                    "type": "demand",
                    "kind": "orderblock",
                    "low": l1,
                    "high": o1,
                    "start_bar": i-1
                })

Analogicky pro nabídku. Impuls je filtrován >1.5 ATR pro vyloučení pohybů v rozmezí.

Google AdInline article slot

Rejection blocks a pokročilé zóny

Rejection blocks jsou detekovány podle proporcí svíce: dolní knot >55% rozsahu, tělo <35%.

def detect_rejection_blocks(df):
    for i in range(2, len(df)-1):
        o = df.open.iloc[i]
        c = df.close.iloc[i]
        h = df.high.iloc[i]
        l = df.low.iloc[i]
        atr = df.atr.iloc[i]
        body = abs(c - o)
        full = h - l
        upper_wick = h - max(o,c)
        lower_wick = min(o,c) - l
        body_ratio = body / full
        lower_ratio = lower_wick / full

        # DEMAND rejection
        if lower_ratio > 0.55 and body_ratio < 0.35:
            zones.append({
                "type": "demand",
                "kind": "rejection",
                "low": l,
                "high": min(o,c),
                "start_bar": i
            })

Pokročilý filtr kontroluje impulsy před/po zóně vzhledem k ATR.

Funkce invalidace:

def is_zone_broken(df, zone):
    start_idx = zone['start_bar'] + 1
    slice_df = df.iloc[start_idx:]
    if zone['type'] == 'supply':
        break_level = slice_df['high'].max() if INVALIDATION_METHOD == "wick" else slice_df['close'].max()
        return break_level > zone['high']
    else:
        break_level = slice_df['low'].min() if INVALIDATION_METHOD == "wick" else slice_df['close'].min()
        return break_level < zone['low']

Odstranění překrývajících se zón třídí podle čerstvosti a vylučuje překryvy.

Výběr nejbližších zón a pinbar-spouštěč

Vyberou se 2 nejbližší zóny k aktuální ceně:

def get_nearest_zones(price, zones, n=2):
    def zone_distance(z):
        if price < z["low"]:
            return z["low"] - price
        elif price > z["high"]:
            return price - z["high"]
        return 0
    return sorted(zones, key=zone_distance)[:n]

Pinbar na 5m-TF:

def is_bullish_pinbar(candle):
    o, h, l, c = float(candle[1]), float(candle[2]), float(candle[3]), float(candle[4])
    body = abs(c - o)
    total_range = h - l
    if body > 0.3 * total_range or c <= o or lower_wick < body * 2 or upper_wick > body * 0.5:
        return False
    return True

Generování a odesílání signálů

Kontrola long-signálu:

def check_long_signal(symbol, klines_5m, zones):
    last = klines_5m[-2]  # uzavřená svíce
    price = float(last[4])
    if not is_bullish_pinbar(last):
        return None
    for zone in zones:
        if price_in_zone(price, zone):
            key = f"{symbol}_{last[0]}_long"
            if key in sent_signals:
                return None
            sent_signals[key] = True
            return zone
    return None

Signál je vizualizován na grafu s označením zón a odeslán do Telegramu přes bot API.

Co je důležité

  • Systém používá 4H pro zóny a 5m pro spouštěče, filtruje šum nižších TF.
  • ATR-normalizace přizpůsobuje zóny volatilitě aktiva bez vazby na BTC.
  • Ochrana před duplikáty přes sent_signals a invalidace proražených zón.
  • Zpracování všech USDT párů Bybit za minuty s důrazem na nejbližší zóny.
  • Price action (pinbar) jako finální spouštěč po strukturálním potvrzení.

— Editorial Team

Advertisement 728x90

Číst dál