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).
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:
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í.
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
Zatím žádné komentáře.