stochastic / app.py
kaganseyda's picture
Update app.py
bcc5338 verified
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
)