borsa / analysis /indicators_api.py
veteroner's picture
chore: Vercel proxy, Supabase edge fn, vscode settings, deno config
3452823
"""
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