import gradio as gr import yfinance as yf import pandas as pd import numpy as np from datetime import datetime, timedelta import json import matplotlib.pyplot as plt import matplotlib.dates as mdates from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor from sklearn.preprocessing import StandardScaler, MinMaxScaler from sklearn.model_selection import train_test_split, TimeSeriesSplit from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score from sklearn.svm import SVR import plotly.graph_objects as go import plotly.express as px from plotly.subplots import make_subplots import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau import requests from bs4 import BeautifulSoup import warnings warnings.filterwarnings('ignore') # GPU加速设置 physical_devices = tf.config.list_physical_devices('GPU') if physical_devices: tf.config.experimental.set_memory_growth(physical_devices[0], True) print("GPU acceleration enabled") else: print("No GPU available, using CPU") class KingStockAnalyzer: def __init__(self): self.models = { 'rf': RandomForestRegressor(n_estimators=200, random_state=42, n_jobs=-1), 'gb': GradientBoostingRegressor(n_estimators=200, random_state=42), 'svr': SVR(kernel='rbf', C=100, gamma=0.1, epsilon=0.1), 'lstm': None # Will be built later } self.scalers = { 'standard': StandardScaler(), 'minmax': MinMaxScaler() } self.is_trained = {model: False for model in self.models} self.sentiment_cache = {} def calculate_rsi(self, prices, period=14): delta = prices.diff() gain = delta.where(delta > 0, 0) loss = -delta.where(delta < 0, 0) avg_gain = gain.rolling(window=period).mean() avg_loss = loss.rolling(window=period).mean() rs = avg_gain / avg_loss rsi = 100 - (100 / (1 + rs)) return rsi def calculate_stochastic_rsi(self, prices, period=14): rsi = self.calculate_rsi(prices, period) rsi_min = rsi.rolling(window=period).min() rsi_max = rsi.rolling(window=period).max() stoch_rsi = (rsi - rsi_min) / (rsi_max - rsi_min) * 100 k_percent = stoch_rsi.rolling(window=3).mean() d_percent = k_percent.rolling(window=3).mean() return { 'k_percent': k_percent.iloc[-1] if not k_percent.empty else 50, 'd_percent': d_percent.iloc[-1] if not d_percent.empty else 50, 'stoch_rsi': stoch_rsi } def calculate_macd(self, prices, fast=12, slow=26, signal=9): ema_fast = prices.ewm(span=fast).mean() ema_slow = prices.ewm(span=slow).mean() macd_line = ema_fast - ema_slow signal_line = macd_line.ewm(span=signal).mean() histogram = macd_line - signal_line return { 'macd': macd_line, 'signal': signal_line, 'histogram': histogram, 'macd_value': macd_line.iloc[-1] if not macd_line.empty else 0, 'signal_value': signal_line.iloc[-1] if not signal_line.empty else 0, 'histogram_value': histogram.iloc[-1] if not histogram.empty else 0 } def calculate_bollinger_bands(self, prices, period=20, std_dev=2): sma = prices.rolling(window=period).mean() std = prices.rolling(window=period).std() upper_band = sma + (std * std_dev) lower_band = sma - (std * std_dev) return { 'upper': upper_band, 'middle': sma, 'lower': lower_band, 'upper_value': upper_band.iloc[-1] if not upper_band.empty else 0, 'middle_value': sma.iloc[-1] if not sma.empty else 0, 'lower_value': lower_band.iloc[-1] if not lower_band.empty else 0 } def calculate_adx(self, high, low, close, period=14): plus_dm = high.diff() minus_dm = low.diff() plus_dm[plus_dm < 0] = 0 minus_dm[minus_dm > 0] = 0 minus_dm = minus_dm.abs() tr1 = pd.DataFrame(high - low) tr2 = pd.DataFrame(abs(high - close.shift())) tr3 = pd.DataFrame(abs(low - close.shift())) tr = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1) atr = tr.rolling(window=period).mean() plus_di = 100 * (plus_dm.rolling(window=period).mean() / atr) minus_di = 100 * (minus_dm.rolling(window=period).mean() / atr) dx = 100 * (abs(plus_di - minus_di) / (plus_di + minus_di)) adx = dx.rolling(window=period).mean() return { 'adx': adx, 'plus_di': plus_di, 'minus_di': minus_di, 'adx_value': adx.iloc[-1] if not adx.empty else 25, 'plus_di_value': plus_di.iloc[-1] if not plus_di.empty else 25, 'minus_di_value': minus_di.iloc[-1] if not minus_di.empty else 25 } def calculate_cci(self, high, low, close, period=20): tp = (high + low + close) / 3 sma = tp.rolling(window=period).mean() mad = tp.rolling(window=period).apply(lambda x: np.fabs(x - x.mean()).mean()) cci = (tp - sma) / (0.015 * mad) return { 'cci': cci, 'cci_value': cci.iloc[-1] if not cci.empty else 0 } def calculate_williams_r(self, high, low, close, period=14): highest_high = high.rolling(window=period).max() lowest_low = low.rolling(window=period).min() williams_r = -100 * (highest_high - close) / (highest_high - lowest_low) return { 'williams_r': williams_r, 'williams_r_value': williams_r.iloc[-1] if not williams_r.empty else -50 } def calculate_fibonacci_levels(self, high, low): diff = high - low levels = { '0%': high, '23.6%': high - (0.236 * diff), '38.2%': high - (0.382 * diff), '50%': high - (0.5 * diff), '61.8%': high - (0.618 * diff), '78.6%': high - (0.786 * diff), '100%': low } return levels def calculate_ichimoku_cloud(self, high, low, close, conversion_periods=9, base_periods=26, lagging_span2_periods=52, displacement=26): # Conversion Line conversion_line = (high.rolling(window=conversion_periods).max() + low.rolling(window=conversion_periods).min()) / 2 # Base Line base_line = (high.rolling(window=base_periods).max() + low.rolling(window=base_periods).min()) / 2 # Leading Span A leading_span_a = (conversion_line + base_line) / 2 # Leading Span B leading_span_b = (high.rolling(window=lagging_span2_periods).max() + low.rolling(window=lagging_span2_periods).min()) / 2 # Lagging Span lagging_span = close.shift(-displacement) return { 'conversion_line': conversion_line, 'base_line': base_line, 'leading_span_a': leading_span_a, 'leading_span_b': leading_span_b, 'lagging_span': lagging_span, 'conversion_value': conversion_line.iloc[-1] if not conversion_line.empty else 0, 'base_value': base_line.iloc[-1] if not base_line.empty else 0, 'leading_a_value': leading_span_a.iloc[-1] if not leading_span_a.empty else 0, 'leading_b_value': leading_span_b.iloc[-1] if not leading_span_b.empty else 0 } def calculate_volume_profile(self, data, bins=10): price_min = data['Low'].min() price_max = data['High'].max() price_range = price_max - price_min bin_size = price_range / bins volume_profile = {} total_volume = data['Volume'].sum() for i in range(bins): lower_bound = price_min + i * bin_size upper_bound = price_min + (i + 1) * bin_size bin_volume = data[(data['Close'] >= lower_bound) & (data['Close'] < upper_bound)]['Volume'].sum() volume_profile[f"{lower_bound:.2f}-{upper_bound:.2f}"] = { 'volume': bin_volume, 'percent': (bin_volume / total_volume) * 100 if total_volume > 0 else 0 } return volume_profile def calculate_market_sentiment(self, symbol): # Check cache first if symbol in self.sentiment_cache: return self.sentiment_cache[symbol] try: # This is a simplified sentiment analysis using news headlines # In a real application, you would use a proper news API and NLP model url = f"https://finance.yahoo.com/quote/{symbol}" headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # Extract headlines (simplified) headlines = [] for item in soup.select('h3'): headlines.append(item.get_text()) # Simple sentiment scoring based on keywords positive_words = ['rise', 'gain', 'up', 'high', 'bull', 'growth', 'profit', 'success', 'strong'] negative_words = ['fall', 'loss', 'down', 'low', 'bear', 'decline', 'risk', 'weak', 'drop'] sentiment_score = 0 for headline in headlines[:10]: # Only check first 10 headlines headline_lower = headline.lower() for word in positive_words: if word in headline_lower: sentiment_score += 1 for word in negative_words: if word in headline_lower: sentiment_score -= 1 # Normalize to -100 to 100 scale max_possible = len(headlines[:10]) * max(len(positive_words), len(negative_words)) if max_possible > 0: sentiment_score = (sentiment_score / max_possible) * 100 # Cache the result self.sentiment_cache[symbol] = { 'score': max(-100, min(100, sentiment_score)), 'headlines': headlines[:5] # Store first 5 headlines } return self.sentiment_cache[symbol] except Exception as e: print(f"Sentiment analysis error: {str(e)}") return {'score': 0, 'headlines': []} def build_lstm_model(self, input_shape): model = Sequential([ Bidirectional(LSTM(128, return_sequences=True), input_shape=input_shape), Dropout(0.2), Bidirectional(LSTM(64, return_sequences=True)), Dropout(0.2), Bidirectional(LSTM(32)), Dropout(0.2), Dense(32, activation='relu'), Dense(1) ]) model.compile(optimizer='adam', loss='mse', metrics=['mae']) return model def prepare_ml_features(self, data): df = data.copy() # Teknik göstergeler df['RSI'] = self.calculate_rsi(df['Close']) macd_data = self.calculate_macd(df['Close']) df['MACD'] = macd_data['macd'] df['MACD_Signal'] = macd_data['signal'] df['MACD_Hist'] = macd_data['histogram'] bb_data = self.calculate_bollinger_bands(df['Close']) df['BB_Upper'] = bb_data['upper'] df['BB_Middle'] = bb_data['middle'] df['BB_Lower'] = bb_data['lower'] df['BB_Width'] = (bb_data['upper'] - bb_data['lower']) / bb_data['middle'] adx_data = self.calculate_adx(df['High'], df['Low'], df['Close']) df['ADX'] = adx_data['adx'] df['Plus_DI'] = adx_data['plus_di'] df['Minus_DI'] = adx_data['minus_di'] cci_data = self.calculate_cci(df['High'], df['Low'], df['Close']) df['CCI'] = cci_data['cci'] williams_data = self.calculate_williams_r(df['High'], df['Low'], df['Close']) df['Williams_R'] = williams_data['williams_r'] ichimoku_data = self.calculate_ichimoku_cloud(df['High'], df['Low'], df['Close']) df['Conversion_Line'] = ichimoku_data['conversion_line'] df['Base_Line'] = ichimoku_data['base_line'] df['Leading_Span_A'] = ichimoku_data['leading_span_a'] df['Leading_Span_B'] = ichimoku_data['leading_span_b'] # Hareketli ortalamalar df['MA_5'] = df['Close'].rolling(window=5).mean() df['MA_10'] = df['Close'].rolling(window=10).mean() df['MA_20'] = df['Close'].rolling(window=20).mean() df['MA_50'] = df['Close'].rolling(window=50).mean() # Fiyat değişimleri df['Price_Change'] = df['Close'].pct_change() df['High_Low_Pct'] = (df['High'] - df['Low']) / df['Close'] df['Close_Open_Pct'] = (df['Close'] - df['Open']) / df['Open'] # Hacim göstergeleri df['Volume_Change'] = df['Volume'].pct_change() df['Volume_MA'] = df['Volume'].rolling(window=20).mean() df['Volume_Ratio'] = df['Volume'] / df['Volume_MA'] # Volatilite df['Volatility'] = df['Price_Change'].rolling(window=20).std() # Gelecek fiyat (tahmin edilecek hedef) df['Future_Price_1d'] = df['Close'].shift(-1) df['Future_Price_5d'] = df['Close'].shift(-5) df['Future_Price_10d'] = df['Close'].shift(-10) # Eksik değerleri temizle df.dropna(inplace=True) return df def prepare_lstm_data(self, data, look_back=30): df = self.prepare_ml_features(data) # Özellikler ve hedef features = df.drop(['Future_Price_1d', 'Future_Price_5d', 'Future_Price_10d', 'Dividends', 'Stock Splits'], axis=1, errors='ignore') targets = { '1d': df['Future_Price_1d'], '5d': df['Future_Price_5d'], '10d': df['Future_Price_10d'] } # Veriyi ölçeklendir features_scaled = self.scalers['minmax'].fit_transform(features) # LSTM için veri hazırlama X, y = {}, {} for horizon in ['1d', '5d', '10d']: X[horizon] = [] y[horizon] = [] for i in range(look_back, len(features_scaled)): X[horizon].append(features_scaled[i-look_back:i]) y[horizon].append(targets[horizon].iloc[i]) X[horizon] = np.array(X[horizon]) y[horizon] = np.array(y[horizon]) return X, y, features.columns def train_models(self, symbol, start_date, end_date): try: # Veri çekme stock = yf.Ticker(symbol) data = stock.history(start=start_date, end=end_date) if data.empty: return False # Geleneksel ML modelleri için veri hazırlama df = self.prepare_ml_features(data) if len(df) < 60: # Yeterli veri yoksa return False # Özellikler ve hedef features = df.drop(['Future_Price_1d', 'Future_Price_5d', 'Future_Price_10d', 'Dividends', 'Stock Splits'], axis=1, errors='ignore') target_1d = df['Future_Price_1d'] target_5d = df['Future_Price_5d'] target_10d = df['Future_Price_10d'] # Veriyi ölçeklendir features_scaled = self.scalers['standard'].fit_transform(features) # Geleneksel ML modellerini eğit for model_name in ['rf', 'gb', 'svr']: try: self.models[model_name].fit(features_scaled, target_5d) self.is_trained[model_name] = True except Exception as e: print(f"Error training {model_name}: {str(e)}") self.is_trained[model_name] = False # LSTM modelini eğit try: X_lstm, y_lstm, feature_names = self.prepare_lstm_data(data) # Modeli oluştur self.models['lstm'] = { '1d': self.build_lstm_model((X_lstm['1d'].shape[1], X_lstm['1d'].shape[2])), '5d': self.build_lstm_model((X_lstm['5d'].shape[1], X_lstm['5d'].shape[2])), '10d': self.build_lstm_model((X_lstm['10d'].shape[1], X_lstm['10d'].shape[2])) } # Callbacks early_stopping = EarlyStopping(patience=10, restore_best_weights=True) reduce_lr = ReduceLROnPlateau(factor=0.1, patience=5) # Her ufuk için modeli eğit for horizon in ['1d', '5d', '10d']: self.models['lstm'][horizon].fit( X_lstm[horizon], y_lstm[horizon], epochs=50, batch_size=32, validation_split=0.2, callbacks=[early_stopping, reduce_lr], verbose=0 ) self.is_trained['lstm'] = True except Exception as e: print(f"Error training LSTM: {str(e)}") self.is_trained['lstm'] = False return True except Exception as e: print(f"Model training error: {str(e)}") return False def predict_prices(self, data): predictions = {} try: # Geleneksel ML modelleri için veri hazırlama df = self.prepare_ml_features(data) if df.empty: return predictions # Son satırı al (güncel veri) last_row = df.iloc[-1:].drop(['Future_Price_1d', 'Future_Price_5d', 'Future_Price_10d', 'Dividends', 'Stock Splits'], axis=1, errors='ignore') # Ölçeklendir last_row_scaled = self.scalers['standard'].transform(last_row) # Geleneksel ML modelleri ile tahmin yap for model_name in ['rf', 'gb', 'svr']: if self.is_trained[model_name]: try: pred = self.models[model_name].predict(last_row_scaled)[0] predictions[model_name] = pred except Exception as e: print(f"Error predicting with {model_name}: {str(e)}") # LSTM ile tahmin yap if self.is_trained['lstm']: try: X_lstm, _, _ = self.prepare_lstm_data(data) for horizon in ['1d', '5d', '10d']: if horizon in X_lstm and len(X_lstm[horizon]) > 0: pred = self.models['lstm'][horizon].predict(X_lstm[horizon][-1:])[0][0] predictions[f'lstm_{horizon}'] = pred except Exception as e: print(f"Error predicting with LSTM: {str(e)}") return predictions except Exception as e: print(f"Prediction error: {str(e)}") return predictions def calculate_portfolio_metrics(self, data, risk_free_rate=0.02): try: # Günlük getirileri hesapla daily_returns = data['Close'].pct_change().dropna() # Yıllık getiriyi hesapla annual_return = daily_returns.mean() * 252 # Yıllık volatiliteyi hesapla annual_volatility = daily_returns.std() * np.sqrt(252) # Sharpe Oranı sharpe_ratio = (annual_return - risk_free_rate) / annual_volatility if annual_volatility > 0 else 0 # Maksimum Çekilme cumulative_returns = (1 + daily_returns).cumprod() running_max = cumulative_returns.cummax() drawdown = (cumulative_returns - running_max) / running_max max_drawdown = drawdown.min() # Sortino Oranı downside_returns = daily_returns[daily_returns < 0] downside_volatility = downside_returns.std() * np.sqrt(252) if len(downside_returns) > 0 else 0 sortino_ratio = (annual_return - risk_free_rate) / downside_volatility if downside_volatility > 0 else 0 # Calmar Oranı calmar_ratio = annual_return / abs(max_drawdown) if max_drawdown != 0 else 0 # VaR (Value at Risk) var_95 = daily_returns.quantile(0.05) return { 'annual_return': annual_return, 'annual_volatility': annual_volatility, 'sharpe_ratio': sharpe_ratio, 'max_drawdown': max_drawdown, 'sortino_ratio': sortino_ratio, 'calmar_ratio': calmar_ratio, 'var_95': var_95 } except Exception as e: print(f"Portfolio metrics error: {str(e)}") return {} def analyze_stock(self, symbol, start_date, end_date, investment_type): try: # Modeli eğit model_trained = self.train_models(symbol, start_date, end_date) # Veri çekme stock = yf.Ticker(symbol) data = stock.history(start=start_date, end=end_date) if data.empty: return f"❌ No data found for {symbol}", "", None, None # Temel bilgileri al info = stock.info company_name = info.get('shortName', 'Unknown') sector = info.get('sector', 'Unknown') industry = info.get('industry', 'Unknown') market_cap = info.get('marketCap', 0) pe_ratio = info.get('trailingPE', 0) eps = info.get('trailingEps', 0) # Mevcut fiyat current_price = data['Close'].iloc[-1] period_high = data['High'].max() period_low = data['Low'].min() # Piyasa duyarlılığı sentiment = self.calculate_market_sentiment(symbol) # Teknik göstergeler stoch_data = self.calculate_stochastic_rsi(data['Close']) k_percent = stoch_data['k_percent'] d_percent = stoch_data['d_percent'] macd_data = self.calculate_macd(data['Close']) macd = macd_data['macd_value'] macd_signal = macd_data['signal_value'] macd_hist = macd_data['histogram_value'] bb_data = self.calculate_bollinger_bands(data['Close']) bb_upper = bb_data['upper_value'] bb_middle = bb_data['middle_value'] bb_lower = bb_data['lower_value'] rsi = self.calculate_rsi(data['Close']).iloc[-1] adx_data = self.calculate_adx(data['High'], data['Low'], data['Close']) adx = adx_data['adx_value'] plus_di = adx_data['plus_di_value'] minus_di = adx_data['minus_di_value'] cci_data = self.calculate_cci(data['High'], data['Low'], data['Close']) cci = cci_data['cci_value'] williams_data = self.calculate_williams_r(data['High'], data['Low'], data['Close']) williams_r = williams_data['williams_r_value'] ichimoku_data = self.calculate_ichimoku_cloud(data['High'], data['Low'], data['Close']) conversion = ichimoku_data['conversion_value'] base = ichimoku_data['base_value'] leading_a = ichimoku_data['leading_a_value'] leading_b = ichimoku_data['leading_b_value'] # Hacim profili volume_profile = self.calculate_volume_profile(data) # Portföy metrikleri portfolio_metrics = self.calculate_portfolio_metrics(data) # Stochastic RSI Puanı if k_percent < 20 and d_percent < 20: if k_percent > d_percent: stoch_signal = "Strong Buy" stoch_score = 85 else: stoch_signal = "Oversold" stoch_score = 75 elif k_percent > 80 and d_percent > 80: if k_percent < d_percent: stoch_signal = "Strong Sell" stoch_score = 15 else: stoch_signal = "Overbought" stoch_score = 25 elif k_percent > d_percent: stoch_signal = "Bullish" stoch_score = 70 else: stoch_signal = "Bearish" stoch_score = 30 # MACD Puanı if macd > macd_signal and macd_hist > 0: macd_signal_text = "Bullish" macd_score = 75 elif macd < macd_signal and macd_hist < 0: macd_signal_text = "Bearish" macd_score = 25 else: macd_signal_text = "Neutral" macd_score = 50 # RSI Puanı if rsi < 30: rsi_signal = "Oversold" rsi_score = 80 elif rsi > 70: rsi_signal = "Overbought" rsi_score = 20 else: rsi_signal = "Neutral" rsi_score = 50 # Bollinger Bantları Puanı if current_price < bb_lower: bb_signal = "Below Lower Band - Buy Signal" bb_score = 80 elif current_price > bb_upper: bb_signal = "Above Upper Band - Sell Signal" bb_score = 20 else: bb_signal = "Within Bands" bb_score = 50 # ADX Puanı if adx > 25: if plus_di > minus_di: adx_signal = "Strong Bullish Trend" adx_score = 80 else: adx_signal = "Strong Bearish Trend" adx_score = 20 else: adx_signal = "Weak Trend" adx_score = 50 # CCI Puanı if cci < -100: cci_signal = "Oversold" cci_score = 80 elif cci > 100: cci_signal = "Overbought" cci_score = 20 else: cci_signal = "Neutral" cci_score = 50 # Williams %R Puanı if williams_r < -80: williams_signal = "Oversold" williams_score = 80 elif williams_r > -20: williams_signal = "Overbought" williams_score = 20 else: williams_signal = "Neutral" williams_score = 50 # Ichimoku Puanı if current_price > leading_a and current_price > leading_b and conversion > base: ichimoku_signal = "Strong Bullish" ichimoku_score = 85 elif current_price < leading_a and current_price < leading_b and conversion < base: ichimoku_signal = "Strong Bearish" ichimoku_score = 15 elif current_price > leading_a and conversion > base: ichimoku_signal = "Bullish" ichimoku_score = 70 elif current_price < leading_a and conversion < base: ichimoku_signal = "Bearish" ichimoku_score = 30 else: ichimoku_signal = "Neutral" ichimoku_score = 50 # Piyasa Duyarlılığı Puanı if sentiment['score'] > 30: sentiment_signal = "Bullish Sentiment" sentiment_score = 75 elif sentiment['score'] < -30: sentiment_signal = "Bearish Sentiment" sentiment_score = 25 else: sentiment_signal = "Neutral Sentiment" sentiment_score = 50 # Portföy Metrikleri Puanı sharpe = portfolio_metrics.get('sharpe_ratio', 0) max_dd = portfolio_metrics.get('max_drawdown', 0) if sharpe > 1.5 and max_dd > -0.2: portfolio_signal = "Excellent Risk-Return" portfolio_score = 85 elif sharpe > 1.0 and max_dd > -0.3: portfolio_signal = "Good Risk-Return" portfolio_score = 70 elif sharpe > 0.5 and max_dd > -0.4: portfolio_signal = "Average Risk-Return" portfolio_score = 55 else: portfolio_signal = "Poor Risk-Return" portfolio_score = 30 # Makine öğrenmesi tahminleri predictions = self.predict_prices(data) ml_scores = {} for model, pred in predictions.items(): if pred is not None: change_percent = ((pred - current_price) / current_price) * 100 if change_percent > 5: ml_scores[model] = {'signal': f"Strong Buy (+{change_percent:.2f}%)", 'score': 85} elif change_percent > 2: ml_scores[model] = {'signal': f"Buy (+{change_percent:.2f}%)", 'score': 70} elif change_percent < -5: ml_scores[model] = {'signal': f"Strong Sell ({change_percent:.2f}%)", 'score': 15} elif change_percent < -2: ml_scores[model] = {'signal': f"Sell ({change_percent:.2f}%)", 'score': 30} else: ml_scores[model] = {'signal': f"Neutral ({change_percent:.2f}%)", 'score': 50} else: ml_scores[model] = {'signal': "No Prediction", 'score': 50} # Tüm ML modellerinin ortalama puanı ml_avg_score = np.mean([ml_scores[model]['score'] for model in ml_scores]) if ml_scores else 50 # Fibonacci seviyeleri fib_levels = self.calculate_fibonacci_levels(period_high, period_low) # Fibonacci Puanı fib_score = 50 fib_position = "Neutral" if current_price <= fib_levels['78.6%']: fib_score = 85 fib_position = "Strong Support Zone" elif current_price <= fib_levels['61.8%']: fib_score = 75 fib_position = "Good Support Zone" elif current_price <= fib_levels['50%']: fib_score = 65 fib_position = "Medium Support" elif current_price <= fib_levels['38.2%']: fib_score = 55 fib_position = "Weak Support" elif current_price >= fib_levels['23.6%']: fib_score = 35 fib_position = "Resistance Zone" # Ağırlıklı final puanı weights = { 'short': { 'stoch': 0.15, 'macd': 0.15, 'rsi': 0.1, 'bb': 0.1, 'adx': 0.1, 'cci': 0.05, 'williams': 0.05, 'ichimoku': 0.1, 'sentiment': 0.05, 'portfolio': 0.05, 'fib': 0.05, 'ml': 0.05 }, 'medium': { 'stoch': 0.1, 'macd': 0.1, 'rsi': 0.08, 'bb': 0.08, 'adx': 0.08, 'cci': 0.05, 'williams': 0.05, 'ichimoku': 0.08, 'sentiment': 0.08, 'portfolio': 0.1, 'fib': 0.1, 'ml': 0.1 }, 'long': { 'stoch': 0.05, 'macd': 0.05, 'rsi': 0.05, 'bb': 0.05, 'adx': 0.05, 'cci': 0.05, 'williams': 0.05, 'ichimoku': 0.05, 'sentiment': 0.1, 'portfolio': 0.2, 'fib': 0.15, 'ml': 0.15 } } weight = weights[investment_type] final_score = ( stoch_score * weight['stoch'] + macd_score * weight['macd'] + rsi_score * weight['rsi'] + bb_score * weight['bb'] + adx_score * weight['adx'] + cci_score * weight['cci'] + williams_score * weight['williams'] + ichimoku_score * weight['ichimoku'] + sentiment_score * weight['sentiment'] + portfolio_score * weight['portfolio'] + fib_score * weight['fib'] + ml_avg_score * weight['ml'] ) # Tavsiye if final_score >= 75: recommendation = "🟢 STRONG BUY" elif final_score >= 60: recommendation = "🔵 BUY" elif final_score >= 40: recommendation = "🟡 HOLD" elif final_score >= 25: recommendation = "🟠 SELL" else: recommendation = "🔴 STRONG SELL" # Grafik oluştur price_chart = self.create_price_chart(data, symbol, bb_data, fib_levels, ichimoku_data) indicators_chart = self.create_indicators_chart(data, symbol, stoch_data, macd_data, rsi, adx_data, cci_data, williams_data) volume_profile_chart = self.create_volume_profile_chart(data, symbol, volume_profile) # Format çıktı result_text = f""" # 📊 {symbol.upper()} - {company_name} Analysis ## {recommendation} ## Score: {final_score:.1f}/100 ### 💰 Company Info: - **Sector:** {sector} - **Industry:** {industry} - **Market Cap:** ${market_cap:,.0f} - **P/E Ratio:** {pe_ratio:.2f} - **EPS:** ${eps:.2f} ### 💰 Price Info: - **Current Price:** ${current_price:.2f} - **Period High:** ${period_high:.2f} - **Period Low:** ${period_low:.2f} ### 🔄 Technical Indicators: - **Stochastic RSI:** {stoch_signal} ({k_percent:.1f}K, {d_percent:.1f}D) - **MACD:** {macd_signal_text} (MACD: {macd:.2f}, Signal: {macd_signal:.2f}) - **RSI:** {rsi_signal} ({rsi:.1f}) - **Bollinger Bands:** {bb_signal} - **ADX:** {adx_signal} ({adx:.1f}) - **CCI:** {cci_signal} ({cci:.1f}) - **Williams %R:** {williams_signal} ({williams_r:.1f}) - **Ichimoku:** {ichimoku_signal} ### 🔢 Fibonacci: - **Position:** {fib_position} ### 📈 Market Sentiment: - **Signal:** {sentiment_signal} - **Score:** {sentiment['score']:.1f}/100 ### 📊 Portfolio Metrics: - **Signal:** {portfolio_signal} - **Sharpe Ratio:** {sharpe:.2f} - **Max Drawdown:** {max_dd:.2%} - **Annual Return:** {portfolio_metrics.get('annual_return', 0):.2%} - **Volatility:** {portfolio_metrics.get('annual_volatility', 0):.2%} ### 🤖 Machine Learning Predictions: """ for model, pred_info in ml_scores.items(): result_text += f"- **{model.upper()}:** {pred_info['signal']}\n" result_text += f""" ### ⚖️ Weights ({investment_type.title()}): - **Stochastic RSI:** {weight['stoch']*100:.0f}% - **MACD:** {weight['macd']*100:.0f}% - **RSI:** {weight['rsi']*100:.0f}% - **Bollinger Bands:** {weight['bb']*100:.0f}% - **ADX:** {weight['adx']*100:.0f}% - **CCI:** {weight['cci']*100:.0f}% - **Williams %R:** {weight['williams']*100:.0f}% - **Ichimoku:** {weight['ichimoku']*100:.0f}% - **Sentiment:** {weight['sentiment']*100:.0f}% - **Portfolio Metrics:** {weight['portfolio']*100:.0f}% - **Fibonacci:** {weight['fib']*100:.0f}% - **Machine Learning:** {weight['ml']*100:.0f}% ### 📅 Period: {start_date} to {end_date} """ # JSON için json_result = { "symbol": symbol.upper(), "company_name": company_name, "sector": sector, "industry": industry, "final_score": round(final_score, 1), "recommendation": recommendation, "current_price": round(current_price, 2), "fundamentals": { "market_cap": market_cap, "pe_ratio": pe_ratio, "eps": eps }, "technical_indicators": { "stochastic_rsi": { "signal": stoch_signal, "k_percent": round(k_percent, 1), "d_percent": round(d_percent, 1), "score": stoch_score }, "macd": { "signal": macd_signal_text, "macd": round(macd, 2), "signal_line": round(macd_signal, 2), "histogram": round(macd_hist, 2), "score": macd_score }, "rsi": { "signal": rsi_signal, "value": round(rsi, 1), "score": rsi_score }, "bollinger_bands": { "signal": bb_signal, "upper": round(bb_upper, 2), "middle": round(bb_middle, 2), "lower": round(bb_lower, 2), "score": bb_score }, "adx": { "signal": adx_signal, "adx": round(adx, 1), "plus_di": round(plus_di, 1), "minus_di": round(minus_di, 1), "score": adx_score }, "cci": { "signal": cci_signal, "value": round(cci, 1), "score": cci_score }, "williams_r": { "signal": williams_signal, "value": round(williams_r, 1), "score": williams_score }, "ichimoku": { "signal": ichimoku_signal, "conversion": round(conversion, 2), "base": round(base, 2), "leading_a": round(leading_a, 2), "leading_b": round(leading_b, 2), "score": ichimoku_score } }, "fibonacci": { "position": fib_position, "score": fib_score, "levels": {k: round(v, 2) for k, v in fib_levels.items()} }, "market_sentiment": { "signal": sentiment_signal, "score": sentiment['score'], "headlines": sentiment['headlines'][:3] }, "portfolio_metrics": { "signal": portfolio_signal, "sharpe_ratio": sharpe, "max_drawdown": max_dd, "annual_return": portfolio_metrics.get('annual_return', 0), "annual_volatility": portfolio_metrics.get('annual_volatility', 0), "sortino_ratio": portfolio_metrics.get('sortino_ratio', 0), "calmar_ratio": portfolio_metrics.get('calmar_ratio', 0), "var_95": portfolio_metrics.get('var_95', 0), "score": portfolio_score }, "machine_learning": { "predictions": {model: {'signal': pred_info['signal'], 'score': pred_info['score']} for model, pred_info in ml_scores.items()}, "average_score": ml_avg_score, "models_trained": model_trained }, "analysis_date": datetime.now().isoformat() } return result_text, json.dumps(json_result, indent=2), price_chart, indicators_chart, volume_profile_chart except Exception as e: return f"❌ Error: {str(e)}", "", None, None, None def create_price_chart(self, data, symbol, bb_data, fib_levels, ichimoku_data): fig = make_subplots( rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.1, subplot_titles=(f'{symbol} Price with Technical Indicators', 'Volume'), row_width=[0.7, 0.3] ) # Fiyat grafiği fig.add_trace(go.Candlestick( x=data.index, open=data['Open'], high=data['High'], low=data['Low'], close=data['Close'], name='Price' ), row=1, col=1) # Bollinger Bantları fig.add_trace(go.Scatter( x=data.index, y=bb_data['upper'], mode='lines', name='BB Upper', line=dict(color='red', width=1) ), row=1, col=1) fig.add_trace(go.Scatter( x=data.index, y=bb_data['middle'], mode='lines', name='BB Middle', line=dict(color='blue', width=1) ), row=1, col=1) fig.add_trace(go.Scatter( x=data.index, y=bb_data['lower'], mode='lines', name='BB Lower', line=dict(color='red', width=1) ), row=1, col=1) # Ichimoku Cloud fig.add_trace(go.Scatter( x=data.index, y=ichimoku_data['leading_span_a'], mode='lines', name='Leading Span A', line=dict(color='green', width=1), fill=None ), row=1, col=1) fig.add_trace(go.Scatter( x=data.index, y=ichimoku_data['leading_span_b'], mode='lines', name='Leading Span B', line=dict(color='red', width=1), fill='tonexty', fillcolor='rgba(0,255,0,0.1)' ), row=1, col=1) # Fibonacci seviyeleri for level, value in fib_levels.items(): fig.add_shape( type="line", line_color="purple", line_width=1, line_dash="dot", x0=data.index[0], x1=data.index[-1], y0=value, y1=value, row=1, col=1 ) fig.add_annotation( x=data.index[-1], y=value, text=f"Fib {level}: ${value:.2f}", showarrow=False, xshift=10, row=1, col=1 ) # Hacim grafiği colors = ['green' if row['Open'] - row['Close'] <= 0 else 'red' for index, row in data.iterrows()] fig.add_trace(go.Bar( x=data.index, y=data['Volume'], name='Volume', marker_color=colors ), row=2, col=1) # Grafik düzeni fig.update_layout( title=f'{symbol} Technical Analysis', xaxis_title='Date', yaxis_title='Price ($)', template='plotly_dark', height=800, legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1) ) fig.update_xaxes(rangeslider_visible=False) return fig def create_indicators_chart(self, data, symbol, stoch_data, macd_data, rsi, adx_data, cci_data, williams_data): fig = make_subplots( rows=3, cols=2, shared_xaxes=True, vertical_spacing=0.05, subplot_titles=( 'Stochastic RSI', 'RSI', 'MACD', 'ADX', 'CCI', 'Williams %R' ), row_heights=[0.33, 0.33, 0.33] ) # Stochastic RSI fig.add_trace(go.Scatter( x=data.index, y=stoch_data['stoch_rsi'], mode='lines', name='Stoch RSI', line=dict(color='blue') ), row=1, col=1) fig.add_hline(y=80, line_dash="dash", line_color="red", row=1, col=1) fig.add_hline(y=20, line_dash="dash", line_color="green", row=1, col=1) # RSI rsi_series = self.calculate_rsi(data['Close']) fig.add_trace(go.Scatter( x=data.index, y=rsi_series, mode='lines', name='RSI', line=dict(color='purple') ), row=1, col=2) fig.add_hline(y=70, line_dash="dash", line_color="red", row=1, col=2) fig.add_hline(y=30, line_dash="dash", line_color="green", row=1, col=2) # MACD fig.add_trace(go.Scatter( x=data.index, y=macd_data['macd'], mode='lines', name='MACD', line=dict(color='blue') ), row=2, col=1) fig.add_trace(go.Scatter( x=data.index, y=macd_data['signal'], mode='lines', name='Signal', line=dict(color='red') ), row=2, col=1) fig.add_trace(go.Bar( x=data.index, y=macd_data['histogram'], name='Histogram', marker_color='green' ), row=2, col=1) # ADX fig.add_trace(go.Scatter( x=data.index, y=adx_data['adx'], mode='lines', name='ADX', line=dict(color='black') ), row=2, col=2) fig.add_trace(go.Scatter( x=data.index, y=adx_data['plus_di'], mode='lines', name='+DI', line=dict(color='green') ), row=2, col=2) fig.add_trace(go.Scatter( x=data.index, y=adx_data['minus_di'], mode='lines', name='-DI', line=dict(color='red') ), row=2, col=2) fig.add_hline(y=25, line_dash="dash", line_color="blue", row=2, col=2) # CCI fig.add_trace(go.Scatter( x=data.index, y=cci_data['cci'], mode='lines', name='CCI', line=dict(color='orange') ), row=3, col=1) fig.add_hline(y=100, line_dash="dash", line_color="red", row=3, col=1) fig.add_hline(y=-100, line_dash="dash", line_color="green", row=3, col=1) # Williams %R fig.add_trace(go.Scatter( x=data.index, y=williams_data['williams_r'], mode='lines', name='Williams %R', line=dict(color='cyan') ), row=3, col=2) fig.add_hline(y=-20, line_dash="dash", line_color="red", row=3, col=2) fig.add_hline(y=-80, line_dash="dash", line_color="green", row=3, col=2) # Grafik düzeni fig.update_layout( title=f'{symbol} Technical Indicators', template='plotly_dark', height=800, legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1) ) fig.update_xaxes(rangeslider_visible=False) return fig def create_volume_profile_chart(self, data, symbol, volume_profile): # Create a volume profile chart price_levels = [] volumes = [] for price_range, info in volume_profile.items(): low, high = map(float, price_range.split('-')) mid_price = (low + high) / 2 price_levels.append(mid_price) volumes.append(info['volume']) fig = go.Figure() fig.add_trace(go.Bar( x=volumes, y=price_levels, orientation='h', marker_color='green', name='Volume Profile' )) # Add current price line current_price = data['Close'].iloc[-1] fig.add_hline(y=current_price, line_dash="dash", line_color="red", annotation_text=f"Current Price: ${current_price:.2f}") # Add high and low lines period_high = data['High'].max() period_low = data['Low'].min() fig.add_hline(y=period_high, line_dash="dot", line_color="blue", annotation_text=f"Period High: ${period_high:.2f}") fig.add_hline(y=period_low, line_dash="dot", line_color="blue", annotation_text=f"Period Low: ${period_low:.2f}") fig.update_layout( title=f'{symbol} Volume Profile', xaxis_title='Volume', yaxis_title='Price ($)', template='plotly_dark', height=600 ) return fig # Analyzer'ı başlat analyzer = KingStockAnalyzer() def analyze_interface(symbol, start_date, end_date, investment_type): return analyzer.analyze_stock(symbol, start_date, end_date, investment_type) def quick_analyze(symbol): end_date = datetime.now().strftime('%Y-%m-%d') start_date = (datetime.now() - timedelta(days=180)).strftime('%Y-%m-%d') return analyzer.analyze_stock(symbol, start_date, end_date, "medium") # Gradio arayüzü oluştur with gr.Blocks(title="King Hedge Fund Stock Analyzer", theme=gr.themes.Soft()) as demo: gr.Markdown("# 👑 King Hedge Fund Stock Analyzer") gr.Markdown("### Professional Technical Analysis with Machine Learning") gr.Markdown("10-15 levels above ChatGPT and Claude") with gr.Row(): with gr.Column(scale=3): symbol = gr.Textbox(label="Stock Symbol", value="AAPL", placeholder="Enter symbol (e.g., AAPL)") start_date = gr.Textbox(label="Start Date", value=(datetime.now() - timedelta(days=180)).strftime('%Y-%m-%d')) end_date = gr.Textbox(label="End Date", value=datetime.now().strftime('%Y-%m-%d')) investment_type = gr.Radio(["short", "medium", "long"], value="medium", label="Investment Type") analyze_btn = gr.Button("🚀 Analyze Stock", variant="primary") gr.Markdown("### Quick Analysis:") with gr.Row(): aapl_btn = gr.Button("AAPL") msft_btn = gr.Button("MSFT") googl_btn = gr.Button("GOOGL") tsla_btn = gr.Button("TSLA") amzn_btn = gr.Button("AMZN") meta_btn = gr.Button("META") with gr.Tabs(): with gr.TabItem("Analysis Results"): result_output = gr.Markdown(label="Analysis Results") with gr.TabItem("JSON Output"): json_output = gr.Code(label="JSON Output (for API integration)", language="json") with gr.TabItem("Price Chart"): price_chart_output = gr.Plot(label="Price Chart with Technical Indicators") with gr.TabItem("Indicators Chart"): indicators_chart_output = gr.Plot(label="Technical Indicators") with gr.TabItem("Volume Profile"): volume_profile_output = gr.Plot(label="Volume Profile") # Event handlers analyze_btn.click( analyze_interface, [symbol, start_date, end_date, investment_type], [result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output] ) aapl_btn.click(lambda: quick_analyze("AAPL"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output]) msft_btn.click(lambda: quick_analyze("MSFT"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output]) googl_btn.click(lambda: quick_analyze("GOOGL"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output]) tsla_btn.click(lambda: quick_analyze("TSLA"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output]) amzn_btn.click(lambda: quick_analyze("AMZN"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output]) meta_btn.click(lambda: quick_analyze("META"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output]) if __name__ == "__main__": demo.launch( server_name="0.0.0.0", server_port=7860, share=True )