""" API-ready versions of technical indicators Streamlit bağımlılıkları olmayan versiyonlar """ import pandas as pd import numpy as np def calculate_rsi(data, window=14): """RSI hesapla""" delta = data.diff() up = delta.clip(lower=0) down = -1 * delta.clip(upper=0) ema_up = up.ewm(com=window-1, adjust=False).mean() ema_down = down.ewm(com=window-1, adjust=False).mean() rs = ema_up / ema_down return 100 - (100 / (1 + rs)) def calculate_macd(data): """MACD hesapla""" exp1 = data.ewm(span=12, adjust=False).mean() exp2 = data.ewm(span=26, adjust=False).mean() macd = exp1 - exp2 signal = macd.ewm(span=9, adjust=False).mean() histogram = macd - signal return macd, signal, histogram def calculate_bollinger_bands(data, window=20, num_std=2): """Bollinger Bands hesapla""" sma = data.rolling(window=window).mean() std = data.rolling(window=window).std() upper = sma + (std * num_std) lower = sma - (std * num_std) return upper, sma, lower def calculate_all_indicators_for_api(df): """ Tüm teknik göstergeleri hesapla ve JSON-friendly formatta döndür """ try: close = df['Close'] # RSI rsi = calculate_rsi(close) # MACD macd, signal, histogram = calculate_macd(close) # Bollinger Bands bb_upper, bb_middle, bb_lower = calculate_bollinger_bands(close) # Moving Averages sma_20 = close.rolling(window=20).mean() sma_50 = close.rolling(window=50).mean() sma_200 = close.rolling(window=200).mean() ema_12 = close.ewm(span=12, adjust=False).mean() ema_26 = close.ewm(span=26, adjust=False).mean() # Son değerleri al latest = { 'rsi': { 'value': float(rsi.iloc[-1]) if not rsi.empty else None, 'signal': 'OVERBOUGHT' if rsi.iloc[-1] > 70 else 'OVERSOLD' if rsi.iloc[-1] < 30 else 'NEUTRAL' }, 'macd': { 'macd': float(macd.iloc[-1]) if not macd.empty else None, 'signal': float(signal.iloc[-1]) if not signal.empty else None, 'histogram': float(histogram.iloc[-1]) if not histogram.empty else None, 'trend': 'BULLISH' if histogram.iloc[-1] > 0 else 'BEARISH' }, 'bollinger': { 'upper': float(bb_upper.iloc[-1]) if not bb_upper.empty else None, 'middle': float(bb_middle.iloc[-1]) if not bb_middle.empty else None, 'lower': float(bb_lower.iloc[-1]) if not bb_lower.empty else None, 'position': 'ABOVE' if close.iloc[-1] > bb_upper.iloc[-1] else 'BELOW' if close.iloc[-1] < bb_lower.iloc[-1] else 'MIDDLE' }, 'moving_averages': { 'sma_20': float(sma_20.iloc[-1]) if not sma_20.empty else None, 'sma_50': float(sma_50.iloc[-1]) if not sma_50.empty else None, 'sma_200': float(sma_200.iloc[-1]) if not sma_200.empty else None, 'ema_12': float(ema_12.iloc[-1]) if not ema_12.empty else None, 'ema_26': float(ema_26.iloc[-1]) if not ema_26.empty else None, }, 'price': { 'current': float(close.iloc[-1]), 'change_pct': float(((close.iloc[-1] - close.iloc[-2]) / close.iloc[-2] * 100)) if len(close) > 1 else 0 } } return latest except Exception as e: print(f"Indicators hesaplama hatası: {e}") return None