kaganseyda commited on
Commit
bcc5338
·
verified ·
1 Parent(s): f25f24f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +878 -115
app.py CHANGED
@@ -6,21 +6,45 @@ from datetime import datetime, timedelta
6
  import json
7
  import matplotlib.pyplot as plt
8
  import matplotlib.dates as mdates
9
- from sklearn.ensemble import RandomForestRegressor
10
- from sklearn.preprocessing import StandardScaler
11
- from sklearn.model_selection import train_test_split
12
  from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
 
13
  import plotly.graph_objects as go
14
  import plotly.express as px
15
  from plotly.subplots import make_subplots
 
 
 
 
 
 
16
  import warnings
17
  warnings.filterwarnings('ignore')
18
 
19
- class HedgeFundStockAnalyzer:
 
 
 
 
 
 
 
 
20
  def __init__(self):
21
- self.model = RandomForestRegressor(n_estimators=100, random_state=42)
22
- self.scaler = StandardScaler()
23
- self.is_trained = False
 
 
 
 
 
 
 
 
 
24
 
25
  def calculate_rsi(self, prices, period=14):
26
  delta = prices.diff()
@@ -42,7 +66,8 @@ class HedgeFundStockAnalyzer:
42
 
43
  return {
44
  'k_percent': k_percent.iloc[-1] if not k_percent.empty else 50,
45
- 'd_percent': d_percent.iloc[-1] if not d_percent.empty else 50
 
46
  }
47
 
48
  def calculate_macd(self, prices, fast=12, slow=26, signal=9):
@@ -53,9 +78,12 @@ class HedgeFundStockAnalyzer:
53
  histogram = macd_line - signal_line
54
 
55
  return {
56
- 'macd': macd_line.iloc[-1] if not macd_line.empty else 0,
57
- 'signal': signal_line.iloc[-1] if not signal_line.empty else 0,
58
- 'histogram': histogram.iloc[-1] if not histogram.empty else 0
 
 
 
59
  }
60
 
61
  def calculate_bollinger_bands(self, prices, period=20, std_dev=2):
@@ -65,9 +93,62 @@ class HedgeFundStockAnalyzer:
65
  lower_band = sma - (std * std_dev)
66
 
67
  return {
68
- 'upper': upper_band.iloc[-1] if not upper_band.empty else 0,
69
- 'middle': sma.iloc[-1] if not sma.empty else 0,
70
- 'lower': lower_band.iloc[-1] if not lower_band.empty else 0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
72
 
73
  def calculate_fibonacci_levels(self, high, low):
@@ -83,26 +164,159 @@ class HedgeFundStockAnalyzer:
83
  }
84
  return levels
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  def prepare_ml_features(self, data):
87
  df = data.copy()
88
 
89
  # Teknik göstergeler
90
  df['RSI'] = self.calculate_rsi(df['Close'])
91
- df['MACD'] = self.calculate_macd(df['Close'])['macd']
92
- df['MACD_Signal'] = self.calculate_macd(df['Close'])['signal']
93
- df['MACD_Hist'] = self.calculate_macd(df['Close'])['histogram']
94
 
95
- # Bollinger Bantları
96
- bb = self.calculate_bollinger_bands(df['Close'])
97
- df['BB_Upper'] = bb['upper']
98
- df['BB_Middle'] = bb['middle']
99
- df['BB_Lower'] = bb['lower']
100
- df['BB_Width'] = (bb['upper'] - bb['lower']) / bb['middle']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  # Hareketli ortalamalar
103
  df['MA_5'] = df['Close'].rolling(window=5).mean()
104
  df['MA_10'] = df['Close'].rolling(window=10).mean()
105
  df['MA_20'] = df['Close'].rolling(window=20).mean()
 
106
 
107
  # Fiyat değişimleri
108
  df['Price_Change'] = df['Close'].pct_change()
@@ -114,15 +328,49 @@ class HedgeFundStockAnalyzer:
114
  df['Volume_MA'] = df['Volume'].rolling(window=20).mean()
115
  df['Volume_Ratio'] = df['Volume'] / df['Volume_MA']
116
 
 
 
 
117
  # Gelecek fiyat (tahmin edilecek hedef)
118
- df['Future_Price'] = df['Close'].shift(-5) # 5 gün sonrası
 
 
119
 
120
  # Eksik değerleri temizle
121
  df.dropna(inplace=True)
122
 
123
  return df
124
 
125
- def train_model(self, symbol, start_date, end_date):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  try:
127
  # Veri çekme
128
  stock = yf.Ticker(symbol)
@@ -131,88 +379,224 @@ class HedgeFundStockAnalyzer:
131
  if data.empty:
132
  return False
133
 
134
- # Özellik hazırlama
135
  df = self.prepare_ml_features(data)
136
 
137
- if len(df) < 30: # Yeterli veri yoksa
138
  return False
139
 
140
  # Özellikler ve hedef
141
- features = df.drop(['Future_Price', 'Dividends', 'Stock Splits'], axis=1, errors='ignore')
142
- target = df['Future_Price']
 
 
143
 
144
  # Veriyi ölçeklendir
145
- features_scaled = self.scaler.fit_transform(features)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
- # Modeli eğit
148
- self.model.fit(features_scaled, target)
149
- self.is_trained = True
150
  return True
151
 
152
  except Exception as e:
153
- print(f"Model eğitimi hatası: {str(e)}")
154
  return False
155
 
156
- def predict_price(self, data):
157
- if not self.is_trained:
158
- return None
159
-
160
  try:
161
- # Özellik hazırlama
162
  df = self.prepare_ml_features(data)
163
 
164
  if df.empty:
165
- return None
166
 
167
  # Son satırı al (güncel veri)
168
- last_row = df.iloc[-1:].drop(['Future_Price', 'Dividends', 'Stock Splits'], axis=1, errors='ignore')
169
 
170
  # Ölçeklendir
171
- last_row_scaled = self.scaler.transform(last_row)
172
 
173
- # Tahmin yap
174
- prediction = self.model.predict(last_row_scaled)[0]
 
 
 
 
 
 
175
 
176
- return prediction
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
  except Exception as e:
179
- print(f"Tahmin hatası: {str(e)}")
180
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
  def analyze_stock(self, symbol, start_date, end_date, investment_type):
183
  try:
184
  # Modeli eğit
185
- model_trained = self.train_model(symbol, start_date, end_date)
186
 
187
  # Veri çekme
188
  stock = yf.Ticker(symbol)
189
  data = stock.history(start=start_date, end=end_date)
190
 
191
  if data.empty:
192
- return f"❌ No data found for {symbol}", "", None
 
 
 
 
 
 
 
 
 
193
 
194
  # Mevcut fiyat
195
  current_price = data['Close'].iloc[-1]
196
  period_high = data['High'].max()
197
  period_low = data['Low'].min()
198
 
 
 
 
199
  # Teknik göstergeler
200
  stoch_data = self.calculate_stochastic_rsi(data['Close'])
201
  k_percent = stoch_data['k_percent']
202
  d_percent = stoch_data['d_percent']
203
 
204
  macd_data = self.calculate_macd(data['Close'])
205
- macd = macd_data['macd']
206
- macd_signal = macd_data['signal']
207
- macd_hist = macd_data['histogram']
208
 
209
  bb_data = self.calculate_bollinger_bands(data['Close'])
210
- bb_upper = bb_data['upper']
211
- bb_middle = bb_data['middle']
212
- bb_lower = bb_data['lower']
213
 
214
  rsi = self.calculate_rsi(data['Close']).iloc[-1]
215
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  # Stochastic RSI Puanı
217
  if k_percent < 20 and d_percent < 20:
218
  if k_percent > d_percent:
@@ -268,6 +652,108 @@ class HedgeFundStockAnalyzer:
268
  bb_signal = "Within Bands"
269
  bb_score = 50
270
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  # Fibonacci seviyeleri
272
  fib_levels = self.calculate_fibonacci_levels(period_high, period_low)
273
 
@@ -291,34 +777,23 @@ class HedgeFundStockAnalyzer:
291
  fib_score = 35
292
  fib_position = "Resistance Zone"
293
 
294
- # Makine öğrenmesi tahmini
295
- ml_prediction = self.predict_price(data)
296
- ml_score = 50
297
- ml_signal = "No Prediction"
298
-
299
- if ml_prediction is not None:
300
- change_percent = ((ml_prediction - current_price) / current_price) * 100
301
- if change_percent > 5:
302
- ml_signal = f"Strong Buy (+{change_percent:.2f}%)"
303
- ml_score = 85
304
- elif change_percent > 2:
305
- ml_signal = f"Buy (+{change_percent:.2f}%)"
306
- ml_score = 70
307
- elif change_percent < -5:
308
- ml_signal = f"Strong Sell ({change_percent:.2f}%)"
309
- ml_score = 15
310
- elif change_percent < -2:
311
- ml_signal = f"Sell ({change_percent:.2f}%)"
312
- ml_score = 30
313
- else:
314
- ml_signal = f"Neutral ({change_percent:.2f}%)"
315
- ml_score = 50
316
-
317
  # Ağırlıklı final puanı
318
  weights = {
319
- 'short': {'stoch': 0.25, 'macd': 0.25, 'rsi': 0.2, 'bb': 0.15, 'fib': 0.1, 'ml': 0.05},
320
- 'medium': {'stoch': 0.2, 'macd': 0.2, 'rsi': 0.15, 'bb': 0.15, 'fib': 0.2, 'ml': 0.1},
321
- 'long': {'stoch': 0.15, 'macd': 0.15, 'rsi': 0.1, 'bb': 0.1, 'fib': 0.3, 'ml': 0.2}
 
 
 
 
 
 
 
 
 
 
 
 
322
  }
323
 
324
  weight = weights[investment_type]
@@ -327,8 +802,14 @@ class HedgeFundStockAnalyzer:
327
  macd_score * weight['macd'] +
328
  rsi_score * weight['rsi'] +
329
  bb_score * weight['bb'] +
 
 
 
 
 
 
330
  fib_score * weight['fib'] +
331
- ml_score * weight['ml']
332
  )
333
 
334
  # Tavsiye
@@ -344,39 +825,71 @@ class HedgeFundStockAnalyzer:
344
  recommendation = "🔴 STRONG SELL"
345
 
346
  # Grafik oluştur
347
- fig = self.create_price_chart(data, symbol, bb_data, fib_levels)
 
 
348
 
349
  # Format çıktı
350
  result_text = f"""
351
- # 📊 {symbol.upper()} Analysis
352
 
353
  ## {recommendation}
354
  ## Score: {final_score:.1f}/100
355
 
 
 
 
 
 
 
 
356
  ### 💰 Price Info:
357
  - **Current Price:** ${current_price:.2f}
358
  - **Period High:** ${period_high:.2f}
359
  - **Period Low:** ${period_low:.2f}
360
- - **ML Prediction:** ${ml_prediction:.2f if ml_prediction else 'N/A'}
361
 
362
  ### 🔄 Technical Indicators:
363
  - **Stochastic RSI:** {stoch_signal} ({k_percent:.1f}K, {d_percent:.1f}D)
364
  - **MACD:** {macd_signal_text} (MACD: {macd:.2f}, Signal: {macd_signal:.2f})
365
  - **RSI:** {rsi_signal} ({rsi:.1f})
366
  - **Bollinger Bands:** {bb_signal}
 
 
 
 
367
 
368
  ### 🔢 Fibonacci:
369
  - **Position:** {fib_position}
370
 
371
- ### 🤖 Machine Learning:
372
- - **Signal:** {ml_signal}
373
- - **Model Status:** {'Trained' if model_trained else 'Not Trained'}
 
 
 
 
 
 
 
374
 
 
 
 
 
 
 
 
375
  ### ⚖️ Weights ({investment_type.title()}):
376
  - **Stochastic RSI:** {weight['stoch']*100:.0f}%
377
  - **MACD:** {weight['macd']*100:.0f}%
378
  - **RSI:** {weight['rsi']*100:.0f}%
379
  - **Bollinger Bands:** {weight['bb']*100:.0f}%
 
 
 
 
 
 
380
  - **Fibonacci:** {weight['fib']*100:.0f}%
381
  - **Machine Learning:** {weight['ml']*100:.0f}%
382
 
@@ -386,10 +899,17 @@ class HedgeFundStockAnalyzer:
386
  # JSON için
387
  json_result = {
388
  "symbol": symbol.upper(),
 
 
 
389
  "final_score": round(final_score, 1),
390
  "recommendation": recommendation,
391
  "current_price": round(current_price, 2),
392
- "ml_prediction": round(ml_prediction, 2) if ml_prediction else None,
 
 
 
 
393
  "technical_indicators": {
394
  "stochastic_rsi": {
395
  "signal": stoch_signal,
@@ -415,6 +935,31 @@ class HedgeFundStockAnalyzer:
415
  "middle": round(bb_middle, 2),
416
  "lower": round(bb_lower, 2),
417
  "score": bb_score
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  }
419
  },
420
  "fibonacci": {
@@ -422,20 +967,36 @@ class HedgeFundStockAnalyzer:
422
  "score": fib_score,
423
  "levels": {k: round(v, 2) for k, v in fib_levels.items()}
424
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  "machine_learning": {
426
- "signal": ml_signal,
427
- "score": ml_score,
428
- "model_trained": model_trained
429
  },
430
  "analysis_date": datetime.now().isoformat()
431
  }
432
 
433
- return result_text, json.dumps(json_result, indent=2), fig
434
 
435
  except Exception as e:
436
- return f"❌ Error: {str(e)}", "", None
437
 
438
- def create_price_chart(self, data, symbol, bb_data, fib_levels):
439
  fig = make_subplots(
440
  rows=2, cols=1,
441
  shared_xaxes=True,
@@ -457,7 +1018,7 @@ class HedgeFundStockAnalyzer:
457
  # Bollinger Bantları
458
  fig.add_trace(go.Scatter(
459
  x=data.index,
460
- y=[bb_data['upper']] * len(data),
461
  mode='lines',
462
  name='BB Upper',
463
  line=dict(color='red', width=1)
@@ -465,7 +1026,7 @@ class HedgeFundStockAnalyzer:
465
 
466
  fig.add_trace(go.Scatter(
467
  x=data.index,
468
- y=[bb_data['middle']] * len(data),
469
  mode='lines',
470
  name='BB Middle',
471
  line=dict(color='blue', width=1)
@@ -473,16 +1034,36 @@ class HedgeFundStockAnalyzer:
473
 
474
  fig.add_trace(go.Scatter(
475
  x=data.index,
476
- y=[bb_data['lower']] * len(data),
477
  mode='lines',
478
  name='BB Lower',
479
  line=dict(color='red', width=1)
480
  ), row=1, col=1)
481
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
482
  # Fibonacci seviyeleri
483
  for level, value in fib_levels.items():
484
  fig.add_shape(
485
- type="line", line_color="green", line_width=1, line_dash="dot",
486
  x0=data.index[0], x1=data.index[-1], y0=value, y1=value,
487
  row=1, col=1
488
  )
@@ -514,9 +1095,178 @@ class HedgeFundStockAnalyzer:
514
  fig.update_xaxes(rangeslider_visible=False)
515
 
516
  return fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
 
518
  # Analyzer'ı başlat
519
- analyzer = HedgeFundStockAnalyzer()
520
 
521
  def analyze_interface(symbol, start_date, end_date, investment_type):
522
  return analyzer.analyze_stock(symbol, start_date, end_date, investment_type)
@@ -527,10 +1277,11 @@ def quick_analyze(symbol):
527
  return analyzer.analyze_stock(symbol, start_date, end_date, "medium")
528
 
529
  # Gradio arayüzü oluştur
530
- with gr.Blocks(title="Hedge Fund Stock Analyzer", theme=gr.themes.Soft()) as demo:
531
 
532
- gr.Markdown("# 🏆 Hedge Fund Stock Analyzer")
533
  gr.Markdown("### Professional Technical Analysis with Machine Learning")
 
534
 
535
  with gr.Row():
536
  with gr.Column(scale=3):
@@ -550,23 +1301,35 @@ with gr.Blocks(title="Hedge Fund Stock Analyzer", theme=gr.themes.Soft()) as dem
550
  amzn_btn = gr.Button("AMZN")
551
  meta_btn = gr.Button("META")
552
 
553
- with gr.Row():
554
- with gr.Column(scale=2):
555
  result_output = gr.Markdown(label="Analysis Results")
556
- with gr.Column(scale=1):
 
557
  json_output = gr.Code(label="JSON Output (for API integration)", language="json")
558
-
559
- with gr.Row():
560
- chart_output = gr.Plot(label="Price Chart with Technical Indicators")
 
 
 
 
 
 
561
 
562
  # Event handlers
563
- analyze_btn.click(analyze_interface, [symbol, start_date, end_date, investment_type], [result_output, json_output, chart_output])
564
- aapl_btn.click(lambda: quick_analyze("AAPL"), outputs=[result_output, json_output, chart_output])
565
- msft_btn.click(lambda: quick_analyze("MSFT"), outputs=[result_output, json_output, chart_output])
566
- googl_btn.click(lambda: quick_analyze("GOOGL"), outputs=[result_output, json_output, chart_output])
567
- tsla_btn.click(lambda: quick_analyze("TSLA"), outputs=[result_output, json_output, chart_output])
568
- amzn_btn.click(lambda: quick_analyze("AMZN"), outputs=[result_output, json_output, chart_output])
569
- meta_btn.click(lambda: quick_analyze("META"), outputs=[result_output, json_output, chart_output])
 
 
 
 
 
570
 
571
  if __name__ == "__main__":
572
  demo.launch(
 
6
  import json
7
  import matplotlib.pyplot as plt
8
  import matplotlib.dates as mdates
9
+ from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
10
+ from sklearn.preprocessing import StandardScaler, MinMaxScaler
11
+ from sklearn.model_selection import train_test_split, TimeSeriesSplit
12
  from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
13
+ from sklearn.svm import SVR
14
  import plotly.graph_objects as go
15
  import plotly.express as px
16
  from plotly.subplots import make_subplots
17
+ import tensorflow as tf
18
+ from tensorflow.keras.models import Sequential
19
+ from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional
20
+ from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
21
+ import requests
22
+ from bs4 import BeautifulSoup
23
  import warnings
24
  warnings.filterwarnings('ignore')
25
 
26
+ # GPU加速设置
27
+ physical_devices = tf.config.list_physical_devices('GPU')
28
+ if physical_devices:
29
+ tf.config.experimental.set_memory_growth(physical_devices[0], True)
30
+ print("GPU acceleration enabled")
31
+ else:
32
+ print("No GPU available, using CPU")
33
+
34
+ class KingStockAnalyzer:
35
  def __init__(self):
36
+ self.models = {
37
+ 'rf': RandomForestRegressor(n_estimators=200, random_state=42, n_jobs=-1),
38
+ 'gb': GradientBoostingRegressor(n_estimators=200, random_state=42),
39
+ 'svr': SVR(kernel='rbf', C=100, gamma=0.1, epsilon=0.1),
40
+ 'lstm': None # Will be built later
41
+ }
42
+ self.scalers = {
43
+ 'standard': StandardScaler(),
44
+ 'minmax': MinMaxScaler()
45
+ }
46
+ self.is_trained = {model: False for model in self.models}
47
+ self.sentiment_cache = {}
48
 
49
  def calculate_rsi(self, prices, period=14):
50
  delta = prices.diff()
 
66
 
67
  return {
68
  'k_percent': k_percent.iloc[-1] if not k_percent.empty else 50,
69
+ 'd_percent': d_percent.iloc[-1] if not d_percent.empty else 50,
70
+ 'stoch_rsi': stoch_rsi
71
  }
72
 
73
  def calculate_macd(self, prices, fast=12, slow=26, signal=9):
 
78
  histogram = macd_line - signal_line
79
 
80
  return {
81
+ 'macd': macd_line,
82
+ 'signal': signal_line,
83
+ 'histogram': histogram,
84
+ 'macd_value': macd_line.iloc[-1] if not macd_line.empty else 0,
85
+ 'signal_value': signal_line.iloc[-1] if not signal_line.empty else 0,
86
+ 'histogram_value': histogram.iloc[-1] if not histogram.empty else 0
87
  }
88
 
89
  def calculate_bollinger_bands(self, prices, period=20, std_dev=2):
 
93
  lower_band = sma - (std * std_dev)
94
 
95
  return {
96
+ 'upper': upper_band,
97
+ 'middle': sma,
98
+ 'lower': lower_band,
99
+ 'upper_value': upper_band.iloc[-1] if not upper_band.empty else 0,
100
+ 'middle_value': sma.iloc[-1] if not sma.empty else 0,
101
+ 'lower_value': lower_band.iloc[-1] if not lower_band.empty else 0
102
+ }
103
+
104
+ def calculate_adx(self, high, low, close, period=14):
105
+ plus_dm = high.diff()
106
+ minus_dm = low.diff()
107
+ plus_dm[plus_dm < 0] = 0
108
+ minus_dm[minus_dm > 0] = 0
109
+ minus_dm = minus_dm.abs()
110
+
111
+ tr1 = pd.DataFrame(high - low)
112
+ tr2 = pd.DataFrame(abs(high - close.shift()))
113
+ tr3 = pd.DataFrame(abs(low - close.shift()))
114
+ tr = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)
115
+
116
+ atr = tr.rolling(window=period).mean()
117
+
118
+ plus_di = 100 * (plus_dm.rolling(window=period).mean() / atr)
119
+ minus_di = 100 * (minus_dm.rolling(window=period).mean() / atr)
120
+
121
+ dx = 100 * (abs(plus_di - minus_di) / (plus_di + minus_di))
122
+ adx = dx.rolling(window=period).mean()
123
+
124
+ return {
125
+ 'adx': adx,
126
+ 'plus_di': plus_di,
127
+ 'minus_di': minus_di,
128
+ 'adx_value': adx.iloc[-1] if not adx.empty else 25,
129
+ 'plus_di_value': plus_di.iloc[-1] if not plus_di.empty else 25,
130
+ 'minus_di_value': minus_di.iloc[-1] if not minus_di.empty else 25
131
+ }
132
+
133
+ def calculate_cci(self, high, low, close, period=20):
134
+ tp = (high + low + close) / 3
135
+ sma = tp.rolling(window=period).mean()
136
+ mad = tp.rolling(window=period).apply(lambda x: np.fabs(x - x.mean()).mean())
137
+ cci = (tp - sma) / (0.015 * mad)
138
+
139
+ return {
140
+ 'cci': cci,
141
+ 'cci_value': cci.iloc[-1] if not cci.empty else 0
142
+ }
143
+
144
+ def calculate_williams_r(self, high, low, close, period=14):
145
+ highest_high = high.rolling(window=period).max()
146
+ lowest_low = low.rolling(window=period).min()
147
+ williams_r = -100 * (highest_high - close) / (highest_high - lowest_low)
148
+
149
+ return {
150
+ 'williams_r': williams_r,
151
+ 'williams_r_value': williams_r.iloc[-1] if not williams_r.empty else -50
152
  }
153
 
154
  def calculate_fibonacci_levels(self, high, low):
 
164
  }
165
  return levels
166
 
167
+ def calculate_ichimoku_cloud(self, high, low, close, conversion_periods=9, base_periods=26, lagging_span2_periods=52, displacement=26):
168
+ # Conversion Line
169
+ conversion_line = (high.rolling(window=conversion_periods).max() + low.rolling(window=conversion_periods).min()) / 2
170
+
171
+ # Base Line
172
+ base_line = (high.rolling(window=base_periods).max() + low.rolling(window=base_periods).min()) / 2
173
+
174
+ # Leading Span A
175
+ leading_span_a = (conversion_line + base_line) / 2
176
+
177
+ # Leading Span B
178
+ leading_span_b = (high.rolling(window=lagging_span2_periods).max() + low.rolling(window=lagging_span2_periods).min()) / 2
179
+
180
+ # Lagging Span
181
+ lagging_span = close.shift(-displacement)
182
+
183
+ return {
184
+ 'conversion_line': conversion_line,
185
+ 'base_line': base_line,
186
+ 'leading_span_a': leading_span_a,
187
+ 'leading_span_b': leading_span_b,
188
+ 'lagging_span': lagging_span,
189
+ 'conversion_value': conversion_line.iloc[-1] if not conversion_line.empty else 0,
190
+ 'base_value': base_line.iloc[-1] if not base_line.empty else 0,
191
+ 'leading_a_value': leading_span_a.iloc[-1] if not leading_span_a.empty else 0,
192
+ 'leading_b_value': leading_span_b.iloc[-1] if not leading_span_b.empty else 0
193
+ }
194
+
195
+ def calculate_volume_profile(self, data, bins=10):
196
+ price_min = data['Low'].min()
197
+ price_max = data['High'].max()
198
+ price_range = price_max - price_min
199
+ bin_size = price_range / bins
200
+
201
+ volume_profile = {}
202
+ total_volume = data['Volume'].sum()
203
+
204
+ for i in range(bins):
205
+ lower_bound = price_min + i * bin_size
206
+ upper_bound = price_min + (i + 1) * bin_size
207
+
208
+ bin_volume = data[(data['Close'] >= lower_bound) & (data['Close'] < upper_bound)]['Volume'].sum()
209
+ volume_profile[f"{lower_bound:.2f}-{upper_bound:.2f}"] = {
210
+ 'volume': bin_volume,
211
+ 'percent': (bin_volume / total_volume) * 100 if total_volume > 0 else 0
212
+ }
213
+
214
+ return volume_profile
215
+
216
+ def calculate_market_sentiment(self, symbol):
217
+ # Check cache first
218
+ if symbol in self.sentiment_cache:
219
+ return self.sentiment_cache[symbol]
220
+
221
+ try:
222
+ # This is a simplified sentiment analysis using news headlines
223
+ # In a real application, you would use a proper news API and NLP model
224
+ url = f"https://finance.yahoo.com/quote/{symbol}"
225
+ 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'}
226
+
227
+ response = requests.get(url, headers=headers)
228
+ soup = BeautifulSoup(response.text, 'html.parser')
229
+
230
+ # Extract headlines (simplified)
231
+ headlines = []
232
+ for item in soup.select('h3'):
233
+ headlines.append(item.get_text())
234
+
235
+ # Simple sentiment scoring based on keywords
236
+ positive_words = ['rise', 'gain', 'up', 'high', 'bull', 'growth', 'profit', 'success', 'strong']
237
+ negative_words = ['fall', 'loss', 'down', 'low', 'bear', 'decline', 'risk', 'weak', 'drop']
238
+
239
+ sentiment_score = 0
240
+ for headline in headlines[:10]: # Only check first 10 headlines
241
+ headline_lower = headline.lower()
242
+ for word in positive_words:
243
+ if word in headline_lower:
244
+ sentiment_score += 1
245
+ for word in negative_words:
246
+ if word in headline_lower:
247
+ sentiment_score -= 1
248
+
249
+ # Normalize to -100 to 100 scale
250
+ max_possible = len(headlines[:10]) * max(len(positive_words), len(negative_words))
251
+ if max_possible > 0:
252
+ sentiment_score = (sentiment_score / max_possible) * 100
253
+
254
+ # Cache the result
255
+ self.sentiment_cache[symbol] = {
256
+ 'score': max(-100, min(100, sentiment_score)),
257
+ 'headlines': headlines[:5] # Store first 5 headlines
258
+ }
259
+
260
+ return self.sentiment_cache[symbol]
261
+
262
+ except Exception as e:
263
+ print(f"Sentiment analysis error: {str(e)}")
264
+ return {'score': 0, 'headlines': []}
265
+
266
+ def build_lstm_model(self, input_shape):
267
+ model = Sequential([
268
+ Bidirectional(LSTM(128, return_sequences=True), input_shape=input_shape),
269
+ Dropout(0.2),
270
+ Bidirectional(LSTM(64, return_sequences=True)),
271
+ Dropout(0.2),
272
+ Bidirectional(LSTM(32)),
273
+ Dropout(0.2),
274
+ Dense(32, activation='relu'),
275
+ Dense(1)
276
+ ])
277
+
278
+ model.compile(optimizer='adam', loss='mse', metrics=['mae'])
279
+ return model
280
+
281
  def prepare_ml_features(self, data):
282
  df = data.copy()
283
 
284
  # Teknik göstergeler
285
  df['RSI'] = self.calculate_rsi(df['Close'])
 
 
 
286
 
287
+ macd_data = self.calculate_macd(df['Close'])
288
+ df['MACD'] = macd_data['macd']
289
+ df['MACD_Signal'] = macd_data['signal']
290
+ df['MACD_Hist'] = macd_data['histogram']
291
+
292
+ bb_data = self.calculate_bollinger_bands(df['Close'])
293
+ df['BB_Upper'] = bb_data['upper']
294
+ df['BB_Middle'] = bb_data['middle']
295
+ df['BB_Lower'] = bb_data['lower']
296
+ df['BB_Width'] = (bb_data['upper'] - bb_data['lower']) / bb_data['middle']
297
+
298
+ adx_data = self.calculate_adx(df['High'], df['Low'], df['Close'])
299
+ df['ADX'] = adx_data['adx']
300
+ df['Plus_DI'] = adx_data['plus_di']
301
+ df['Minus_DI'] = adx_data['minus_di']
302
+
303
+ cci_data = self.calculate_cci(df['High'], df['Low'], df['Close'])
304
+ df['CCI'] = cci_data['cci']
305
+
306
+ williams_data = self.calculate_williams_r(df['High'], df['Low'], df['Close'])
307
+ df['Williams_R'] = williams_data['williams_r']
308
+
309
+ ichimoku_data = self.calculate_ichimoku_cloud(df['High'], df['Low'], df['Close'])
310
+ df['Conversion_Line'] = ichimoku_data['conversion_line']
311
+ df['Base_Line'] = ichimoku_data['base_line']
312
+ df['Leading_Span_A'] = ichimoku_data['leading_span_a']
313
+ df['Leading_Span_B'] = ichimoku_data['leading_span_b']
314
 
315
  # Hareketli ortalamalar
316
  df['MA_5'] = df['Close'].rolling(window=5).mean()
317
  df['MA_10'] = df['Close'].rolling(window=10).mean()
318
  df['MA_20'] = df['Close'].rolling(window=20).mean()
319
+ df['MA_50'] = df['Close'].rolling(window=50).mean()
320
 
321
  # Fiyat değişimleri
322
  df['Price_Change'] = df['Close'].pct_change()
 
328
  df['Volume_MA'] = df['Volume'].rolling(window=20).mean()
329
  df['Volume_Ratio'] = df['Volume'] / df['Volume_MA']
330
 
331
+ # Volatilite
332
+ df['Volatility'] = df['Price_Change'].rolling(window=20).std()
333
+
334
  # Gelecek fiyat (tahmin edilecek hedef)
335
+ df['Future_Price_1d'] = df['Close'].shift(-1)
336
+ df['Future_Price_5d'] = df['Close'].shift(-5)
337
+ df['Future_Price_10d'] = df['Close'].shift(-10)
338
 
339
  # Eksik değerleri temizle
340
  df.dropna(inplace=True)
341
 
342
  return df
343
 
344
+ def prepare_lstm_data(self, data, look_back=30):
345
+ df = self.prepare_ml_features(data)
346
+
347
+ # Özellikler ve hedef
348
+ features = df.drop(['Future_Price_1d', 'Future_Price_5d', 'Future_Price_10d', 'Dividends', 'Stock Splits'], axis=1, errors='ignore')
349
+ targets = {
350
+ '1d': df['Future_Price_1d'],
351
+ '5d': df['Future_Price_5d'],
352
+ '10d': df['Future_Price_10d']
353
+ }
354
+
355
+ # Veriyi ölçeklendir
356
+ features_scaled = self.scalers['minmax'].fit_transform(features)
357
+
358
+ # LSTM için veri hazırlama
359
+ X, y = {}, {}
360
+ for horizon in ['1d', '5d', '10d']:
361
+ X[horizon] = []
362
+ y[horizon] = []
363
+
364
+ for i in range(look_back, len(features_scaled)):
365
+ X[horizon].append(features_scaled[i-look_back:i])
366
+ y[horizon].append(targets[horizon].iloc[i])
367
+
368
+ X[horizon] = np.array(X[horizon])
369
+ y[horizon] = np.array(y[horizon])
370
+
371
+ return X, y, features.columns
372
+
373
+ def train_models(self, symbol, start_date, end_date):
374
  try:
375
  # Veri çekme
376
  stock = yf.Ticker(symbol)
 
379
  if data.empty:
380
  return False
381
 
382
+ # Geleneksel ML modelleri için veri hazırlama
383
  df = self.prepare_ml_features(data)
384
 
385
+ if len(df) < 60: # Yeterli veri yoksa
386
  return False
387
 
388
  # Özellikler ve hedef
389
+ features = df.drop(['Future_Price_1d', 'Future_Price_5d', 'Future_Price_10d', 'Dividends', 'Stock Splits'], axis=1, errors='ignore')
390
+ target_1d = df['Future_Price_1d']
391
+ target_5d = df['Future_Price_5d']
392
+ target_10d = df['Future_Price_10d']
393
 
394
  # Veriyi ölçeklendir
395
+ features_scaled = self.scalers['standard'].fit_transform(features)
396
+
397
+ # Geleneksel ML modellerini eğit
398
+ for model_name in ['rf', 'gb', 'svr']:
399
+ try:
400
+ self.models[model_name].fit(features_scaled, target_5d)
401
+ self.is_trained[model_name] = True
402
+ except Exception as e:
403
+ print(f"Error training {model_name}: {str(e)}")
404
+ self.is_trained[model_name] = False
405
+
406
+ # LSTM modelini eğit
407
+ try:
408
+ X_lstm, y_lstm, feature_names = self.prepare_lstm_data(data)
409
+
410
+ # Modeli oluştur
411
+ self.models['lstm'] = {
412
+ '1d': self.build_lstm_model((X_lstm['1d'].shape[1], X_lstm['1d'].shape[2])),
413
+ '5d': self.build_lstm_model((X_lstm['5d'].shape[1], X_lstm['5d'].shape[2])),
414
+ '10d': self.build_lstm_model((X_lstm['10d'].shape[1], X_lstm['10d'].shape[2]))
415
+ }
416
+
417
+ # Callbacks
418
+ early_stopping = EarlyStopping(patience=10, restore_best_weights=True)
419
+ reduce_lr = ReduceLROnPlateau(factor=0.1, patience=5)
420
+
421
+ # Her ufuk için modeli eğit
422
+ for horizon in ['1d', '5d', '10d']:
423
+ self.models['lstm'][horizon].fit(
424
+ X_lstm[horizon], y_lstm[horizon],
425
+ epochs=50,
426
+ batch_size=32,
427
+ validation_split=0.2,
428
+ callbacks=[early_stopping, reduce_lr],
429
+ verbose=0
430
+ )
431
+
432
+ self.is_trained['lstm'] = True
433
+ except Exception as e:
434
+ print(f"Error training LSTM: {str(e)}")
435
+ self.is_trained['lstm'] = False
436
 
 
 
 
437
  return True
438
 
439
  except Exception as e:
440
+ print(f"Model training error: {str(e)}")
441
  return False
442
 
443
+ def predict_prices(self, data):
444
+ predictions = {}
445
+
 
446
  try:
447
+ # Geleneksel ML modelleri için veri hazırlama
448
  df = self.prepare_ml_features(data)
449
 
450
  if df.empty:
451
+ return predictions
452
 
453
  # Son satırı al (güncel veri)
454
+ last_row = df.iloc[-1:].drop(['Future_Price_1d', 'Future_Price_5d', 'Future_Price_10d', 'Dividends', 'Stock Splits'], axis=1, errors='ignore')
455
 
456
  # Ölçeklendir
457
+ last_row_scaled = self.scalers['standard'].transform(last_row)
458
 
459
+ # Geleneksel ML modelleri ile tahmin yap
460
+ for model_name in ['rf', 'gb', 'svr']:
461
+ if self.is_trained[model_name]:
462
+ try:
463
+ pred = self.models[model_name].predict(last_row_scaled)[0]
464
+ predictions[model_name] = pred
465
+ except Exception as e:
466
+ print(f"Error predicting with {model_name}: {str(e)}")
467
 
468
+ # LSTM ile tahmin yap
469
+ if self.is_trained['lstm']:
470
+ try:
471
+ X_lstm, _, _ = self.prepare_lstm_data(data)
472
+
473
+ for horizon in ['1d', '5d', '10d']:
474
+ if horizon in X_lstm and len(X_lstm[horizon]) > 0:
475
+ pred = self.models['lstm'][horizon].predict(X_lstm[horizon][-1:])[0][0]
476
+ predictions[f'lstm_{horizon}'] = pred
477
+ except Exception as e:
478
+ print(f"Error predicting with LSTM: {str(e)}")
479
+
480
+ return predictions
481
 
482
  except Exception as e:
483
+ print(f"Prediction error: {str(e)}")
484
+ return predictions
485
+
486
+ def calculate_portfolio_metrics(self, data, risk_free_rate=0.02):
487
+ try:
488
+ # Günlük getirileri hesapla
489
+ daily_returns = data['Close'].pct_change().dropna()
490
+
491
+ # Yıllık getiriyi hesapla
492
+ annual_return = daily_returns.mean() * 252
493
+
494
+ # Yıllık volatiliteyi hesapla
495
+ annual_volatility = daily_returns.std() * np.sqrt(252)
496
+
497
+ # Sharpe Oranı
498
+ sharpe_ratio = (annual_return - risk_free_rate) / annual_volatility if annual_volatility > 0 else 0
499
+
500
+ # Maksimum Çekilme
501
+ cumulative_returns = (1 + daily_returns).cumprod()
502
+ running_max = cumulative_returns.cummax()
503
+ drawdown = (cumulative_returns - running_max) / running_max
504
+ max_drawdown = drawdown.min()
505
+
506
+ # Sortino Oranı
507
+ downside_returns = daily_returns[daily_returns < 0]
508
+ downside_volatility = downside_returns.std() * np.sqrt(252) if len(downside_returns) > 0 else 0
509
+ sortino_ratio = (annual_return - risk_free_rate) / downside_volatility if downside_volatility > 0 else 0
510
+
511
+ # Calmar Oranı
512
+ calmar_ratio = annual_return / abs(max_drawdown) if max_drawdown != 0 else 0
513
+
514
+ # VaR (Value at Risk)
515
+ var_95 = daily_returns.quantile(0.05)
516
+
517
+ return {
518
+ 'annual_return': annual_return,
519
+ 'annual_volatility': annual_volatility,
520
+ 'sharpe_ratio': sharpe_ratio,
521
+ 'max_drawdown': max_drawdown,
522
+ 'sortino_ratio': sortino_ratio,
523
+ 'calmar_ratio': calmar_ratio,
524
+ 'var_95': var_95
525
+ }
526
+
527
+ except Exception as e:
528
+ print(f"Portfolio metrics error: {str(e)}")
529
+ return {}
530
 
531
  def analyze_stock(self, symbol, start_date, end_date, investment_type):
532
  try:
533
  # Modeli eğit
534
+ model_trained = self.train_models(symbol, start_date, end_date)
535
 
536
  # Veri çekme
537
  stock = yf.Ticker(symbol)
538
  data = stock.history(start=start_date, end=end_date)
539
 
540
  if data.empty:
541
+ return f"❌ No data found for {symbol}", "", None, None
542
+
543
+ # Temel bilgileri al
544
+ info = stock.info
545
+ company_name = info.get('shortName', 'Unknown')
546
+ sector = info.get('sector', 'Unknown')
547
+ industry = info.get('industry', 'Unknown')
548
+ market_cap = info.get('marketCap', 0)
549
+ pe_ratio = info.get('trailingPE', 0)
550
+ eps = info.get('trailingEps', 0)
551
 
552
  # Mevcut fiyat
553
  current_price = data['Close'].iloc[-1]
554
  period_high = data['High'].max()
555
  period_low = data['Low'].min()
556
 
557
+ # Piyasa duyarlılığı
558
+ sentiment = self.calculate_market_sentiment(symbol)
559
+
560
  # Teknik göstergeler
561
  stoch_data = self.calculate_stochastic_rsi(data['Close'])
562
  k_percent = stoch_data['k_percent']
563
  d_percent = stoch_data['d_percent']
564
 
565
  macd_data = self.calculate_macd(data['Close'])
566
+ macd = macd_data['macd_value']
567
+ macd_signal = macd_data['signal_value']
568
+ macd_hist = macd_data['histogram_value']
569
 
570
  bb_data = self.calculate_bollinger_bands(data['Close'])
571
+ bb_upper = bb_data['upper_value']
572
+ bb_middle = bb_data['middle_value']
573
+ bb_lower = bb_data['lower_value']
574
 
575
  rsi = self.calculate_rsi(data['Close']).iloc[-1]
576
 
577
+ adx_data = self.calculate_adx(data['High'], data['Low'], data['Close'])
578
+ adx = adx_data['adx_value']
579
+ plus_di = adx_data['plus_di_value']
580
+ minus_di = adx_data['minus_di_value']
581
+
582
+ cci_data = self.calculate_cci(data['High'], data['Low'], data['Close'])
583
+ cci = cci_data['cci_value']
584
+
585
+ williams_data = self.calculate_williams_r(data['High'], data['Low'], data['Close'])
586
+ williams_r = williams_data['williams_r_value']
587
+
588
+ ichimoku_data = self.calculate_ichimoku_cloud(data['High'], data['Low'], data['Close'])
589
+ conversion = ichimoku_data['conversion_value']
590
+ base = ichimoku_data['base_value']
591
+ leading_a = ichimoku_data['leading_a_value']
592
+ leading_b = ichimoku_data['leading_b_value']
593
+
594
+ # Hacim profili
595
+ volume_profile = self.calculate_volume_profile(data)
596
+
597
+ # Portföy metrikleri
598
+ portfolio_metrics = self.calculate_portfolio_metrics(data)
599
+
600
  # Stochastic RSI Puanı
601
  if k_percent < 20 and d_percent < 20:
602
  if k_percent > d_percent:
 
652
  bb_signal = "Within Bands"
653
  bb_score = 50
654
 
655
+ # ADX Puanı
656
+ if adx > 25:
657
+ if plus_di > minus_di:
658
+ adx_signal = "Strong Bullish Trend"
659
+ adx_score = 80
660
+ else:
661
+ adx_signal = "Strong Bearish Trend"
662
+ adx_score = 20
663
+ else:
664
+ adx_signal = "Weak Trend"
665
+ adx_score = 50
666
+
667
+ # CCI Puanı
668
+ if cci < -100:
669
+ cci_signal = "Oversold"
670
+ cci_score = 80
671
+ elif cci > 100:
672
+ cci_signal = "Overbought"
673
+ cci_score = 20
674
+ else:
675
+ cci_signal = "Neutral"
676
+ cci_score = 50
677
+
678
+ # Williams %R Puanı
679
+ if williams_r < -80:
680
+ williams_signal = "Oversold"
681
+ williams_score = 80
682
+ elif williams_r > -20:
683
+ williams_signal = "Overbought"
684
+ williams_score = 20
685
+ else:
686
+ williams_signal = "Neutral"
687
+ williams_score = 50
688
+
689
+ # Ichimoku Puanı
690
+ if current_price > leading_a and current_price > leading_b and conversion > base:
691
+ ichimoku_signal = "Strong Bullish"
692
+ ichimoku_score = 85
693
+ elif current_price < leading_a and current_price < leading_b and conversion < base:
694
+ ichimoku_signal = "Strong Bearish"
695
+ ichimoku_score = 15
696
+ elif current_price > leading_a and conversion > base:
697
+ ichimoku_signal = "Bullish"
698
+ ichimoku_score = 70
699
+ elif current_price < leading_a and conversion < base:
700
+ ichimoku_signal = "Bearish"
701
+ ichimoku_score = 30
702
+ else:
703
+ ichimoku_signal = "Neutral"
704
+ ichimoku_score = 50
705
+
706
+ # Piyasa Duyarlılığı Puanı
707
+ if sentiment['score'] > 30:
708
+ sentiment_signal = "Bullish Sentiment"
709
+ sentiment_score = 75
710
+ elif sentiment['score'] < -30:
711
+ sentiment_signal = "Bearish Sentiment"
712
+ sentiment_score = 25
713
+ else:
714
+ sentiment_signal = "Neutral Sentiment"
715
+ sentiment_score = 50
716
+
717
+ # Portföy Metrikleri Puanı
718
+ sharpe = portfolio_metrics.get('sharpe_ratio', 0)
719
+ max_dd = portfolio_metrics.get('max_drawdown', 0)
720
+
721
+ if sharpe > 1.5 and max_dd > -0.2:
722
+ portfolio_signal = "Excellent Risk-Return"
723
+ portfolio_score = 85
724
+ elif sharpe > 1.0 and max_dd > -0.3:
725
+ portfolio_signal = "Good Risk-Return"
726
+ portfolio_score = 70
727
+ elif sharpe > 0.5 and max_dd > -0.4:
728
+ portfolio_signal = "Average Risk-Return"
729
+ portfolio_score = 55
730
+ else:
731
+ portfolio_signal = "Poor Risk-Return"
732
+ portfolio_score = 30
733
+
734
+ # Makine öğrenmesi tahminleri
735
+ predictions = self.predict_prices(data)
736
+ ml_scores = {}
737
+
738
+ for model, pred in predictions.items():
739
+ if pred is not None:
740
+ change_percent = ((pred - current_price) / current_price) * 100
741
+ if change_percent > 5:
742
+ ml_scores[model] = {'signal': f"Strong Buy (+{change_percent:.2f}%)", 'score': 85}
743
+ elif change_percent > 2:
744
+ ml_scores[model] = {'signal': f"Buy (+{change_percent:.2f}%)", 'score': 70}
745
+ elif change_percent < -5:
746
+ ml_scores[model] = {'signal': f"Strong Sell ({change_percent:.2f}%)", 'score': 15}
747
+ elif change_percent < -2:
748
+ ml_scores[model] = {'signal': f"Sell ({change_percent:.2f}%)", 'score': 30}
749
+ else:
750
+ ml_scores[model] = {'signal': f"Neutral ({change_percent:.2f}%)", 'score': 50}
751
+ else:
752
+ ml_scores[model] = {'signal': "No Prediction", 'score': 50}
753
+
754
+ # Tüm ML modellerinin ortalama puanı
755
+ ml_avg_score = np.mean([ml_scores[model]['score'] for model in ml_scores]) if ml_scores else 50
756
+
757
  # Fibonacci seviyeleri
758
  fib_levels = self.calculate_fibonacci_levels(period_high, period_low)
759
 
 
777
  fib_score = 35
778
  fib_position = "Resistance Zone"
779
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780
  # Ağırlıklı final puanı
781
  weights = {
782
+ 'short': {
783
+ 'stoch': 0.15, 'macd': 0.15, 'rsi': 0.1, 'bb': 0.1,
784
+ 'adx': 0.1, 'cci': 0.05, 'williams': 0.05, 'ichimoku': 0.1,
785
+ 'sentiment': 0.05, 'portfolio': 0.05, 'fib': 0.05, 'ml': 0.05
786
+ },
787
+ 'medium': {
788
+ 'stoch': 0.1, 'macd': 0.1, 'rsi': 0.08, 'bb': 0.08,
789
+ 'adx': 0.08, 'cci': 0.05, 'williams': 0.05, 'ichimoku': 0.08,
790
+ 'sentiment': 0.08, 'portfolio': 0.1, 'fib': 0.1, 'ml': 0.1
791
+ },
792
+ 'long': {
793
+ 'stoch': 0.05, 'macd': 0.05, 'rsi': 0.05, 'bb': 0.05,
794
+ 'adx': 0.05, 'cci': 0.05, 'williams': 0.05, 'ichimoku': 0.05,
795
+ 'sentiment': 0.1, 'portfolio': 0.2, 'fib': 0.15, 'ml': 0.15
796
+ }
797
  }
798
 
799
  weight = weights[investment_type]
 
802
  macd_score * weight['macd'] +
803
  rsi_score * weight['rsi'] +
804
  bb_score * weight['bb'] +
805
+ adx_score * weight['adx'] +
806
+ cci_score * weight['cci'] +
807
+ williams_score * weight['williams'] +
808
+ ichimoku_score * weight['ichimoku'] +
809
+ sentiment_score * weight['sentiment'] +
810
+ portfolio_score * weight['portfolio'] +
811
  fib_score * weight['fib'] +
812
+ ml_avg_score * weight['ml']
813
  )
814
 
815
  # Tavsiye
 
825
  recommendation = "🔴 STRONG SELL"
826
 
827
  # Grafik oluştur
828
+ price_chart = self.create_price_chart(data, symbol, bb_data, fib_levels, ichimoku_data)
829
+ indicators_chart = self.create_indicators_chart(data, symbol, stoch_data, macd_data, rsi, adx_data, cci_data, williams_data)
830
+ volume_profile_chart = self.create_volume_profile_chart(data, symbol, volume_profile)
831
 
832
  # Format çıktı
833
  result_text = f"""
834
+ # 📊 {symbol.upper()} - {company_name} Analysis
835
 
836
  ## {recommendation}
837
  ## Score: {final_score:.1f}/100
838
 
839
+ ### 💰 Company Info:
840
+ - **Sector:** {sector}
841
+ - **Industry:** {industry}
842
+ - **Market Cap:** ${market_cap:,.0f}
843
+ - **P/E Ratio:** {pe_ratio:.2f}
844
+ - **EPS:** ${eps:.2f}
845
+
846
  ### 💰 Price Info:
847
  - **Current Price:** ${current_price:.2f}
848
  - **Period High:** ${period_high:.2f}
849
  - **Period Low:** ${period_low:.2f}
 
850
 
851
  ### 🔄 Technical Indicators:
852
  - **Stochastic RSI:** {stoch_signal} ({k_percent:.1f}K, {d_percent:.1f}D)
853
  - **MACD:** {macd_signal_text} (MACD: {macd:.2f}, Signal: {macd_signal:.2f})
854
  - **RSI:** {rsi_signal} ({rsi:.1f})
855
  - **Bollinger Bands:** {bb_signal}
856
+ - **ADX:** {adx_signal} ({adx:.1f})
857
+ - **CCI:** {cci_signal} ({cci:.1f})
858
+ - **Williams %R:** {williams_signal} ({williams_r:.1f})
859
+ - **Ichimoku:** {ichimoku_signal}
860
 
861
  ### 🔢 Fibonacci:
862
  - **Position:** {fib_position}
863
 
864
+ ### 📈 Market Sentiment:
865
+ - **Signal:** {sentiment_signal}
866
+ - **Score:** {sentiment['score']:.1f}/100
867
+
868
+ ### 📊 Portfolio Metrics:
869
+ - **Signal:** {portfolio_signal}
870
+ - **Sharpe Ratio:** {sharpe:.2f}
871
+ - **Max Drawdown:** {max_dd:.2%}
872
+ - **Annual Return:** {portfolio_metrics.get('annual_return', 0):.2%}
873
+ - **Volatility:** {portfolio_metrics.get('annual_volatility', 0):.2%}
874
 
875
+ ### 🤖 Machine Learning Predictions:
876
+ """
877
+
878
+ for model, pred_info in ml_scores.items():
879
+ result_text += f"- **{model.upper()}:** {pred_info['signal']}\n"
880
+
881
+ result_text += f"""
882
  ### ⚖️ Weights ({investment_type.title()}):
883
  - **Stochastic RSI:** {weight['stoch']*100:.0f}%
884
  - **MACD:** {weight['macd']*100:.0f}%
885
  - **RSI:** {weight['rsi']*100:.0f}%
886
  - **Bollinger Bands:** {weight['bb']*100:.0f}%
887
+ - **ADX:** {weight['adx']*100:.0f}%
888
+ - **CCI:** {weight['cci']*100:.0f}%
889
+ - **Williams %R:** {weight['williams']*100:.0f}%
890
+ - **Ichimoku:** {weight['ichimoku']*100:.0f}%
891
+ - **Sentiment:** {weight['sentiment']*100:.0f}%
892
+ - **Portfolio Metrics:** {weight['portfolio']*100:.0f}%
893
  - **Fibonacci:** {weight['fib']*100:.0f}%
894
  - **Machine Learning:** {weight['ml']*100:.0f}%
895
 
 
899
  # JSON için
900
  json_result = {
901
  "symbol": symbol.upper(),
902
+ "company_name": company_name,
903
+ "sector": sector,
904
+ "industry": industry,
905
  "final_score": round(final_score, 1),
906
  "recommendation": recommendation,
907
  "current_price": round(current_price, 2),
908
+ "fundamentals": {
909
+ "market_cap": market_cap,
910
+ "pe_ratio": pe_ratio,
911
+ "eps": eps
912
+ },
913
  "technical_indicators": {
914
  "stochastic_rsi": {
915
  "signal": stoch_signal,
 
935
  "middle": round(bb_middle, 2),
936
  "lower": round(bb_lower, 2),
937
  "score": bb_score
938
+ },
939
+ "adx": {
940
+ "signal": adx_signal,
941
+ "adx": round(adx, 1),
942
+ "plus_di": round(plus_di, 1),
943
+ "minus_di": round(minus_di, 1),
944
+ "score": adx_score
945
+ },
946
+ "cci": {
947
+ "signal": cci_signal,
948
+ "value": round(cci, 1),
949
+ "score": cci_score
950
+ },
951
+ "williams_r": {
952
+ "signal": williams_signal,
953
+ "value": round(williams_r, 1),
954
+ "score": williams_score
955
+ },
956
+ "ichimoku": {
957
+ "signal": ichimoku_signal,
958
+ "conversion": round(conversion, 2),
959
+ "base": round(base, 2),
960
+ "leading_a": round(leading_a, 2),
961
+ "leading_b": round(leading_b, 2),
962
+ "score": ichimoku_score
963
  }
964
  },
965
  "fibonacci": {
 
967
  "score": fib_score,
968
  "levels": {k: round(v, 2) for k, v in fib_levels.items()}
969
  },
970
+ "market_sentiment": {
971
+ "signal": sentiment_signal,
972
+ "score": sentiment['score'],
973
+ "headlines": sentiment['headlines'][:3]
974
+ },
975
+ "portfolio_metrics": {
976
+ "signal": portfolio_signal,
977
+ "sharpe_ratio": sharpe,
978
+ "max_drawdown": max_dd,
979
+ "annual_return": portfolio_metrics.get('annual_return', 0),
980
+ "annual_volatility": portfolio_metrics.get('annual_volatility', 0),
981
+ "sortino_ratio": portfolio_metrics.get('sortino_ratio', 0),
982
+ "calmar_ratio": portfolio_metrics.get('calmar_ratio', 0),
983
+ "var_95": portfolio_metrics.get('var_95', 0),
984
+ "score": portfolio_score
985
+ },
986
  "machine_learning": {
987
+ "predictions": {model: {'signal': pred_info['signal'], 'score': pred_info['score']} for model, pred_info in ml_scores.items()},
988
+ "average_score": ml_avg_score,
989
+ "models_trained": model_trained
990
  },
991
  "analysis_date": datetime.now().isoformat()
992
  }
993
 
994
+ return result_text, json.dumps(json_result, indent=2), price_chart, indicators_chart, volume_profile_chart
995
 
996
  except Exception as e:
997
+ return f"❌ Error: {str(e)}", "", None, None, None
998
 
999
+ def create_price_chart(self, data, symbol, bb_data, fib_levels, ichimoku_data):
1000
  fig = make_subplots(
1001
  rows=2, cols=1,
1002
  shared_xaxes=True,
 
1018
  # Bollinger Bantları
1019
  fig.add_trace(go.Scatter(
1020
  x=data.index,
1021
+ y=bb_data['upper'],
1022
  mode='lines',
1023
  name='BB Upper',
1024
  line=dict(color='red', width=1)
 
1026
 
1027
  fig.add_trace(go.Scatter(
1028
  x=data.index,
1029
+ y=bb_data['middle'],
1030
  mode='lines',
1031
  name='BB Middle',
1032
  line=dict(color='blue', width=1)
 
1034
 
1035
  fig.add_trace(go.Scatter(
1036
  x=data.index,
1037
+ y=bb_data['lower'],
1038
  mode='lines',
1039
  name='BB Lower',
1040
  line=dict(color='red', width=1)
1041
  ), row=1, col=1)
1042
 
1043
+ # Ichimoku Cloud
1044
+ fig.add_trace(go.Scatter(
1045
+ x=data.index,
1046
+ y=ichimoku_data['leading_span_a'],
1047
+ mode='lines',
1048
+ name='Leading Span A',
1049
+ line=dict(color='green', width=1),
1050
+ fill=None
1051
+ ), row=1, col=1)
1052
+
1053
+ fig.add_trace(go.Scatter(
1054
+ x=data.index,
1055
+ y=ichimoku_data['leading_span_b'],
1056
+ mode='lines',
1057
+ name='Leading Span B',
1058
+ line=dict(color='red', width=1),
1059
+ fill='tonexty',
1060
+ fillcolor='rgba(0,255,0,0.1)'
1061
+ ), row=1, col=1)
1062
+
1063
  # Fibonacci seviyeleri
1064
  for level, value in fib_levels.items():
1065
  fig.add_shape(
1066
+ type="line", line_color="purple", line_width=1, line_dash="dot",
1067
  x0=data.index[0], x1=data.index[-1], y0=value, y1=value,
1068
  row=1, col=1
1069
  )
 
1095
  fig.update_xaxes(rangeslider_visible=False)
1096
 
1097
  return fig
1098
+
1099
+ def create_indicators_chart(self, data, symbol, stoch_data, macd_data, rsi, adx_data, cci_data, williams_data):
1100
+ fig = make_subplots(
1101
+ rows=3, cols=2,
1102
+ shared_xaxes=True,
1103
+ vertical_spacing=0.05,
1104
+ subplot_titles=(
1105
+ 'Stochastic RSI', 'RSI',
1106
+ 'MACD', 'ADX',
1107
+ 'CCI', 'Williams %R'
1108
+ ),
1109
+ row_heights=[0.33, 0.33, 0.33]
1110
+ )
1111
+
1112
+ # Stochastic RSI
1113
+ fig.add_trace(go.Scatter(
1114
+ x=data.index,
1115
+ y=stoch_data['stoch_rsi'],
1116
+ mode='lines',
1117
+ name='Stoch RSI',
1118
+ line=dict(color='blue')
1119
+ ), row=1, col=1)
1120
+
1121
+ fig.add_hline(y=80, line_dash="dash", line_color="red", row=1, col=1)
1122
+ fig.add_hline(y=20, line_dash="dash", line_color="green", row=1, col=1)
1123
+
1124
+ # RSI
1125
+ rsi_series = self.calculate_rsi(data['Close'])
1126
+ fig.add_trace(go.Scatter(
1127
+ x=data.index,
1128
+ y=rsi_series,
1129
+ mode='lines',
1130
+ name='RSI',
1131
+ line=dict(color='purple')
1132
+ ), row=1, col=2)
1133
+
1134
+ fig.add_hline(y=70, line_dash="dash", line_color="red", row=1, col=2)
1135
+ fig.add_hline(y=30, line_dash="dash", line_color="green", row=1, col=2)
1136
+
1137
+ # MACD
1138
+ fig.add_trace(go.Scatter(
1139
+ x=data.index,
1140
+ y=macd_data['macd'],
1141
+ mode='lines',
1142
+ name='MACD',
1143
+ line=dict(color='blue')
1144
+ ), row=2, col=1)
1145
+
1146
+ fig.add_trace(go.Scatter(
1147
+ x=data.index,
1148
+ y=macd_data['signal'],
1149
+ mode='lines',
1150
+ name='Signal',
1151
+ line=dict(color='red')
1152
+ ), row=2, col=1)
1153
+
1154
+ fig.add_trace(go.Bar(
1155
+ x=data.index,
1156
+ y=macd_data['histogram'],
1157
+ name='Histogram',
1158
+ marker_color='green'
1159
+ ), row=2, col=1)
1160
+
1161
+ # ADX
1162
+ fig.add_trace(go.Scatter(
1163
+ x=data.index,
1164
+ y=adx_data['adx'],
1165
+ mode='lines',
1166
+ name='ADX',
1167
+ line=dict(color='black')
1168
+ ), row=2, col=2)
1169
+
1170
+ fig.add_trace(go.Scatter(
1171
+ x=data.index,
1172
+ y=adx_data['plus_di'],
1173
+ mode='lines',
1174
+ name='+DI',
1175
+ line=dict(color='green')
1176
+ ), row=2, col=2)
1177
+
1178
+ fig.add_trace(go.Scatter(
1179
+ x=data.index,
1180
+ y=adx_data['minus_di'],
1181
+ mode='lines',
1182
+ name='-DI',
1183
+ line=dict(color='red')
1184
+ ), row=2, col=2)
1185
+
1186
+ fig.add_hline(y=25, line_dash="dash", line_color="blue", row=2, col=2)
1187
+
1188
+ # CCI
1189
+ fig.add_trace(go.Scatter(
1190
+ x=data.index,
1191
+ y=cci_data['cci'],
1192
+ mode='lines',
1193
+ name='CCI',
1194
+ line=dict(color='orange')
1195
+ ), row=3, col=1)
1196
+
1197
+ fig.add_hline(y=100, line_dash="dash", line_color="red", row=3, col=1)
1198
+ fig.add_hline(y=-100, line_dash="dash", line_color="green", row=3, col=1)
1199
+
1200
+ # Williams %R
1201
+ fig.add_trace(go.Scatter(
1202
+ x=data.index,
1203
+ y=williams_data['williams_r'],
1204
+ mode='lines',
1205
+ name='Williams %R',
1206
+ line=dict(color='cyan')
1207
+ ), row=3, col=2)
1208
+
1209
+ fig.add_hline(y=-20, line_dash="dash", line_color="red", row=3, col=2)
1210
+ fig.add_hline(y=-80, line_dash="dash", line_color="green", row=3, col=2)
1211
+
1212
+ # Grafik düzeni
1213
+ fig.update_layout(
1214
+ title=f'{symbol} Technical Indicators',
1215
+ template='plotly_dark',
1216
+ height=800,
1217
+ legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1)
1218
+ )
1219
+
1220
+ fig.update_xaxes(rangeslider_visible=False)
1221
+
1222
+ return fig
1223
+
1224
+ def create_volume_profile_chart(self, data, symbol, volume_profile):
1225
+ # Create a volume profile chart
1226
+ price_levels = []
1227
+ volumes = []
1228
+
1229
+ for price_range, info in volume_profile.items():
1230
+ low, high = map(float, price_range.split('-'))
1231
+ mid_price = (low + high) / 2
1232
+ price_levels.append(mid_price)
1233
+ volumes.append(info['volume'])
1234
+
1235
+ fig = go.Figure()
1236
+
1237
+ fig.add_trace(go.Bar(
1238
+ x=volumes,
1239
+ y=price_levels,
1240
+ orientation='h',
1241
+ marker_color='green',
1242
+ name='Volume Profile'
1243
+ ))
1244
+
1245
+ # Add current price line
1246
+ current_price = data['Close'].iloc[-1]
1247
+ fig.add_hline(y=current_price, line_dash="dash", line_color="red",
1248
+ annotation_text=f"Current Price: ${current_price:.2f}")
1249
+
1250
+ # Add high and low lines
1251
+ period_high = data['High'].max()
1252
+ period_low = data['Low'].min()
1253
+ fig.add_hline(y=period_high, line_dash="dot", line_color="blue",
1254
+ annotation_text=f"Period High: ${period_high:.2f}")
1255
+ fig.add_hline(y=period_low, line_dash="dot", line_color="blue",
1256
+ annotation_text=f"Period Low: ${period_low:.2f}")
1257
+
1258
+ fig.update_layout(
1259
+ title=f'{symbol} Volume Profile',
1260
+ xaxis_title='Volume',
1261
+ yaxis_title='Price ($)',
1262
+ template='plotly_dark',
1263
+ height=600
1264
+ )
1265
+
1266
+ return fig
1267
 
1268
  # Analyzer'ı başlat
1269
+ analyzer = KingStockAnalyzer()
1270
 
1271
  def analyze_interface(symbol, start_date, end_date, investment_type):
1272
  return analyzer.analyze_stock(symbol, start_date, end_date, investment_type)
 
1277
  return analyzer.analyze_stock(symbol, start_date, end_date, "medium")
1278
 
1279
  # Gradio arayüzü oluştur
1280
+ with gr.Blocks(title="King Hedge Fund Stock Analyzer", theme=gr.themes.Soft()) as demo:
1281
 
1282
+ gr.Markdown("# 👑 King Hedge Fund Stock Analyzer")
1283
  gr.Markdown("### Professional Technical Analysis with Machine Learning")
1284
+ gr.Markdown("10-15 levels above ChatGPT and Claude")
1285
 
1286
  with gr.Row():
1287
  with gr.Column(scale=3):
 
1301
  amzn_btn = gr.Button("AMZN")
1302
  meta_btn = gr.Button("META")
1303
 
1304
+ with gr.Tabs():
1305
+ with gr.TabItem("Analysis Results"):
1306
  result_output = gr.Markdown(label="Analysis Results")
1307
+
1308
+ with gr.TabItem("JSON Output"):
1309
  json_output = gr.Code(label="JSON Output (for API integration)", language="json")
1310
+
1311
+ with gr.TabItem("Price Chart"):
1312
+ price_chart_output = gr.Plot(label="Price Chart with Technical Indicators")
1313
+
1314
+ with gr.TabItem("Indicators Chart"):
1315
+ indicators_chart_output = gr.Plot(label="Technical Indicators")
1316
+
1317
+ with gr.TabItem("Volume Profile"):
1318
+ volume_profile_output = gr.Plot(label="Volume Profile")
1319
 
1320
  # Event handlers
1321
+ analyze_btn.click(
1322
+ analyze_interface,
1323
+ [symbol, start_date, end_date, investment_type],
1324
+ [result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output]
1325
+ )
1326
+
1327
+ aapl_btn.click(lambda: quick_analyze("AAPL"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output])
1328
+ msft_btn.click(lambda: quick_analyze("MSFT"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output])
1329
+ googl_btn.click(lambda: quick_analyze("GOOGL"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output])
1330
+ tsla_btn.click(lambda: quick_analyze("TSLA"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output])
1331
+ amzn_btn.click(lambda: quick_analyze("AMZN"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output])
1332
+ meta_btn.click(lambda: quick_analyze("META"), outputs=[result_output, json_output, price_chart_output, indicators_chart_output, volume_profile_output])
1333
 
1334
  if __name__ == "__main__":
1335
  demo.launch(