"""SFP & RSI Divergence Detection untuk BTC Scalper""" def detect_sfp(candles, lookback=10): if not candles or len(candles) < lookback + 2: return {'type': 'NONE', 'sweep_level': 0, 'score_bonus': 0} try: recent = candles[-(lookback+2):] last = recent[-2] # pakai candle sebelum terakhir (sudah close) prev = recent[:-2] # Support both list [ts,o,h,l,c,v] and dict {open,high,low,close} def _low(c): return float(c['low'] if isinstance(c,dict) else c[3]) def _high(c): return float(c['high'] if isinstance(c,dict) else c[2]) def _close(c): return float(c['close'] if isinstance(c,dict) else c[4]) last_low = _low(last) last_high = _high(last) last_close = _close(last) swing_lows = [_low(c) for c in prev[-5:]] swing_highs = [_high(c) for c in prev[-5:]] recent_swing_low = min(swing_lows) recent_swing_high = max(swing_highs) # Bullish SFP if last_low < recent_swing_low and last_close > recent_swing_low: depth = (recent_swing_low - last_low) / recent_swing_low * 100 if depth >= 0.01: return {'type': 'BULLISH', 'sweep_level': recent_swing_low, 'score_bonus': 15} # Bearish SFP if last_high > recent_swing_high and last_close < recent_swing_high: depth = (last_high - recent_swing_high) / recent_swing_high * 100 if depth >= 0.01: return {'type': 'BEARISH', 'sweep_level': recent_swing_high, 'score_bonus': 15} return {'type': 'NONE', 'sweep_level': 0, 'score_bonus': 0} except: return {'type': 'NONE', 'sweep_level': 0, 'score_bonus': 0} def detect_rsi_divergence(candles, lookback=14): if not candles or len(candles) < lookback + 6: return {'type': 'NONE', 'score_bonus': 0} try: def _cls(c): return float(c['close'] if isinstance(c,dict) else c[4]) closes = [_cls(c) for c in candles[-(lookback+6):]] def calc_rsi(cls): deltas = [cls[i]-cls[i-1] for i in range(1,len(cls))] gains = [d if d>0 else 0 for d in deltas] losses = [-d if d<0 else 0 for d in deltas] ag = sum(gains[-lookback:])/lookback al = sum(losses[-lookback:])/lookback if al == 0: return 100 return 100-(100/(1+ag/al)) rsi_now = calc_rsi(closes) rsi_prev = calc_rsi(closes[:-5]) price_now = closes[-1] price_prev = closes[-6] if price_now < price_prev and rsi_now > rsi_prev and rsi_now < 45: return {'type': 'BULLISH', 'rsi': round(rsi_now,1), 'score_bonus': 10} if price_now > price_prev and rsi_now < rsi_prev and rsi_now > 55: return {'type': 'BEARISH', 'rsi': round(rsi_now,1), 'score_bonus': 10} return {'type': 'NONE', 'score_bonus': 0} except: return {'type': 'NONE', 'score_bonus': 0}