GoshawkVortexAI commited on
Commit
128ed19
·
verified ·
1 Parent(s): a4e7916

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -95
app.py CHANGED
@@ -1,6 +1,4 @@
1
  import os
2
- import io
3
- import requests
4
  import numpy as np
5
  import pandas as pd
6
  import gradio as gr
@@ -13,50 +11,43 @@ from groq import Groq
13
  # 🔌 1. GROQ CLIENT
14
  # ==========================================
15
  api_key = os.environ.get("GROQ_API_KEY")
16
- client = None
17
- if api_key:
18
- client = Groq(api_key=api_key)
19
 
20
  # ==========================================
21
- # 📊 2. CSV OKUMA VE MODEL EĞİTİMİ
22
  # ==========================================
23
- def load_dataframe(file_or_url):
24
- """Dosya yükleme veya URL'den TSV/CSV okur."""
 
 
25
  try:
26
- if isinstance(file_or_url, str): # URL
27
- headers = {"User-Agent": "Mozilla/5.0"}
28
- r = requests.get(file_or_url, headers=headers, timeout=30)
29
- r.raise_for_status()
30
- text = r.text
31
- else: # Yüklenen dosya
32
- text = open(file_or_url.name, "r", encoding="utf-8").read()
33
-
34
- # Önce tab ile dene (senin dosyan tab-separated)
35
- df = pd.read_csv(io.StringIO(text), sep="\t", header=None)
36
- if df.shape[1] < 6: # tab değilse virgülle dene
37
- df = pd.read_csv(io.StringIO(text), sep=",", header=None)
38
 
39
  if df.shape[1] < 6:
40
- return None, f"Beklenen 6 sütun bulunamadı. Bulunan: {df.shape[1]}"
41
 
42
- # Başlık yok -> manuel isimlendir
43
  df = df.iloc[:, :6]
44
  df.columns = ["date", "open", "high", "low", "close", "volume"]
45
 
46
- # Sayısal dönüşüm (bozuk satırları at)
47
- for col in ["open", "high", "low", "close", "volume"]:
48
- df[col] = pd.to_numeric(df[col], errors="coerce")
49
 
50
  df = df.dropna(subset=["close"]).reset_index(drop=True)
51
-
52
  if len(df) < 60:
53
- return None, f"Yetersiz veri. En az 60 satır gerekli, bulunan: {len(df)}"
54
 
55
  return df, None
56
  except Exception as e:
57
  return None, f"Veri okunamadı: {e}"
58
 
59
-
 
 
60
  def compute_rsi(series, period=14):
61
  delta = series.diff()
62
  gain = delta.clip(lower=0).rolling(period).mean()
@@ -64,34 +55,28 @@ def compute_rsi(series, period=14):
64
  rs = gain / loss
65
  return 100 - (100 / (1 + rs))
66
 
67
-
68
  def train_models(df):
69
- """XGBoost + KNN eğitir, en güncel gösterge değerlerini döndürür."""
70
  df = df.copy()
71
  df["ma_5"] = df["close"].rolling(5).mean()
72
  df["ma_20"] = df["close"].rolling(20).mean()
73
  df["rsi"] = compute_rsi(df["close"], 14)
74
  df["macd"] = df["close"].ewm(span=12).mean() - df["close"].ewm(span=26).mean()
75
-
76
- # Hedef: bir sonraki mumun kapanışı mevcut mumdan yüksek mi?
77
  df["target"] = (df["close"].shift(-1) > df["close"]).astype(int)
78
 
79
  df_model = df.dropna().reset_index(drop=True)
80
  if len(df_model) < 20:
81
- return None, None, None, None, "Göstergelerden sonra yeterli veri kalmadı."
82
 
83
  features = ["ma_5", "ma_20", "rsi", "macd", "volume"]
84
  X = df_model[features].values
85
  y = df_model["target"].values
86
 
87
- # XGBoost
88
  xgb_model = xgb.XGBClassifier(
89
  n_estimators=60, max_depth=3, learning_rate=0.1,
90
  objective="binary:logistic", eval_metric="logloss", random_state=42
91
  )
92
  xgb_model.fit(X, y)
93
 
94
- # KNN
95
  scaler = StandardScaler()
96
  X_scaled = scaler.fit_transform(X)
97
  knn_model = KNeighborsClassifier(n_neighbors=7)
@@ -109,15 +94,11 @@ def train_models(df):
109
  }
110
  return xgb_model, knn_model, scaler, metrics, None
111
 
112
-
113
  # ==========================================
114
- # 🧠 3. ANALİZ MOTORU
115
  # ==========================================
116
- def predict_and_analyze(file_or_url):
117
- if file_or_url is None:
118
- return "Lütfen bir CSV/TSV dosyası yükleyin veya link girin.", {}
119
-
120
- df, err = load_dataframe(file_or_url)
121
  if err:
122
  return err, {}
123
 
@@ -125,95 +106,80 @@ def predict_and_analyze(file_or_url):
125
  if err:
126
  return err, {}
127
 
128
- feat_arr = np.array([[metrics["ma5"], metrics["ma20"], metrics["rsi"], metrics["macd"], metrics["volume"]]])
129
-
130
- xgb_prob_up = float(xgb_model.predict_proba(feat_arr)[0][1])
131
- knn_prob_up = float(knn_model.predict_proba(scaler.transform(feat_arr))[0][1])
132
- ensemble_prob_up = (xgb_prob_up + knn_prob_up) / 2
133
- ensemble_prob_down = 1 - ensemble_prob_up
134
 
135
- direction = "YUKARI 📈" if ensemble_prob_up > 0.5 else "AŞAĞI 📉"
136
- confidence = max(ensemble_prob_up, ensemble_prob_down) * 100
 
 
 
 
137
 
138
  prob_dict = {
139
- "XGBoost Yükseliş": xgb_prob_up,
140
- "KNN Yükseliş": knn_prob_up,
141
- "Ensemble Yükseliş (Ortalama)": ensemble_prob_up,
142
  }
143
 
144
  prompt = f"""
145
- Sen uzman bir kripto para analisti ve teknik analiz uzmanısın.
146
-
147
- 📊 BTC/USD Son Kapanış ({metrics['last_date']}): ${metrics['last_close']:,.2f}
148
- - RSI (14): {metrics['rsi']:.2f}
149
- - MA5: ${metrics['ma5']:,.2f} | MA20: ${metrics['ma20']:,.2f}
150
- - MACD: {metrics['macd']:.4f}
151
- - Hacim: {metrics['volume']:,.2f}
152
-
153
- 🤖 Model Sonuçları:
154
- - XGBoost Yükseliş: %{xgb_prob_up*100:.1f}
155
- - KNN Yükseliş: %{knn_prob_up*100:.1f}
156
- - Ensemble Yükseliş: %{ensemble_prob_up*100:.1f}
157
- - Tahmin Yönü: {direction} (Güven: %{confidence:.1f})
158
-
159
- Türkçe bir teknik analiz raporu hazırla. Başlıklar:
160
- 1. 🎯 Model Yorumu (XGBoost + KNN karşılaştırması)
161
- 2. 📈 Teknik Analiz (RSI, MA, MACD; destek/direnç)
162
- 3. 💡 İşlem Stratejisi (Long/Short, stop-loss, take-profit)
163
-
164
- Yatırım tavsiyesi olmadığını vurgula.
165
  """
166
 
167
  if client:
168
  try:
169
- response = client.chat.completions.create(
170
  model="openai/gpt-oss-120b",
171
  messages=[{"role": "user", "content": prompt}],
172
  temperature=0.3,
173
  max_tokens=1024
174
  )
175
- analysis_result = response.choices[0].message.content
176
  except Exception as e:
177
- analysis_result = f"Groq API Hatası: {e}"
178
  else:
179
- analysis_result = "GROQ_API_KEY bulunamadı! Hugging Face Secrets'a ekleyin."
180
 
181
  header = (
182
- f"**Son Kapanış: ${metrics['last_close']:,.2f}** | RSI: {metrics['rsi']:.1f} | "
183
  f"MA5: ${metrics['ma5']:,.0f} | MA20: ${metrics['ma20']:,.0f}\n\n"
184
- f"**XGB:** %{xgb_prob_up*100:.1f} | **KNN:** %{knn_prob_up*100:.1f} | "
185
- f"**Ensemble:** %{ensemble_prob_up*100:.1f}\n\n---\n\n"
186
  )
187
- return header + analysis_result, prob_dict
188
-
189
 
190
  # ==========================================
191
- # 🎨 4. GRADIO ARAYÜZÜ
192
  # ==========================================
193
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="slate")) as demo:
194
  gr.Markdown(
195
- """
196
  # ₿ BTC/USD XGBoost + KNN & Groq AI Tahmin Radarı
197
- Verinizi **CSV/TSV dosyası** olarak yükleyin **veya** doğrudan linkini girin.
198
- Dosya **başlıksız** olmalı ve sütunlar sırasıyla:
199
- `Date, Open, High, Low, Close, Volume`
200
  """
201
  )
202
 
203
  with gr.Row():
204
  with gr.Column():
205
- gr.Markdown("### 📂 Veri Kaynağı")
206
- file_input = gr.File(label="CSV/TSV Dosyası Yükle", file_types=[".csv", ".tsv", ".txt"])
207
- url_input = gr.Textbox(label="veya CSV Linki (URL)", placeholder="https://.../BTCUSD30.csv")
208
- submit_btn = gr.Button("Analiz Et", variant="primary")
209
-
 
210
  with gr.Column():
211
  prob_output = gr.Label(label="Model Tahminleri")
212
- analysis_output = gr.Markdown(value="Veri yükleyip butona basın.")
213
 
214
- submit_btn.click(
215
  fn=predict_and_analyze,
216
- inputs=[file_input if False else url_input], # aşağıda düzelttim
217
  outputs=[analysis_output, prob_output]
218
  )
219
 
 
1
  import os
 
 
2
  import numpy as np
3
  import pandas as pd
4
  import gradio as gr
 
11
  # 🔌 1. GROQ CLIENT
12
  # ==========================================
13
  api_key = os.environ.get("GROQ_API_KEY")
14
+ client = Groq(api_key=api_key) if api_key else None
 
 
15
 
16
  # ==========================================
17
+ # 📊 2. CSV DOSYASINI OKUMA (Ana dizinden)
18
  # ==========================================
19
+ CSV_PATH = "BTCUSD_M30.csv"
20
+
21
+ def load_local_csv(path=CSV_PATH):
22
+ """Space ana dizinindeki CSV'yi okur (başlıksız, tab/virgül)."""
23
  try:
24
+ if not os.path.exists(path):
25
+ return None, f"Dosya bulunamadı: {path}"
26
+
27
+ df = pd.read_csv(path, sep="\t", header=None)
28
+ if df.shape[1] < 6:
29
+ df = pd.read_csv(path, sep=",", header=None)
 
 
 
 
 
 
30
 
31
  if df.shape[1] < 6:
32
+ return None, f"6 sütun bekleniyordu, {df.shape[1]} bulundu."
33
 
 
34
  df = df.iloc[:, :6]
35
  df.columns = ["date", "open", "high", "low", "close", "volume"]
36
 
37
+ for c in ["open", "high", "low", "close", "volume"]:
38
+ df[c] = pd.to_numeric(df[c], errors="coerce")
 
39
 
40
  df = df.dropna(subset=["close"]).reset_index(drop=True)
 
41
  if len(df) < 60:
42
+ return None, f"En az 60 satır gerekli, {len(df)} var."
43
 
44
  return df, None
45
  except Exception as e:
46
  return None, f"Veri okunamadı: {e}"
47
 
48
+ # ==========================================
49
+ # 🧮 3. TEKNİK GÖSTERGELER + MODEL
50
+ # ==========================================
51
  def compute_rsi(series, period=14):
52
  delta = series.diff()
53
  gain = delta.clip(lower=0).rolling(period).mean()
 
55
  rs = gain / loss
56
  return 100 - (100 / (1 + rs))
57
 
 
58
  def train_models(df):
 
59
  df = df.copy()
60
  df["ma_5"] = df["close"].rolling(5).mean()
61
  df["ma_20"] = df["close"].rolling(20).mean()
62
  df["rsi"] = compute_rsi(df["close"], 14)
63
  df["macd"] = df["close"].ewm(span=12).mean() - df["close"].ewm(span=26).mean()
 
 
64
  df["target"] = (df["close"].shift(-1) > df["close"]).astype(int)
65
 
66
  df_model = df.dropna().reset_index(drop=True)
67
  if len(df_model) < 20:
68
+ return None, None, None, None, "Göstergelerden sonra yetersiz veri."
69
 
70
  features = ["ma_5", "ma_20", "rsi", "macd", "volume"]
71
  X = df_model[features].values
72
  y = df_model["target"].values
73
 
 
74
  xgb_model = xgb.XGBClassifier(
75
  n_estimators=60, max_depth=3, learning_rate=0.1,
76
  objective="binary:logistic", eval_metric="logloss", random_state=42
77
  )
78
  xgb_model.fit(X, y)
79
 
 
80
  scaler = StandardScaler()
81
  X_scaled = scaler.fit_transform(X)
82
  knn_model = KNeighborsClassifier(n_neighbors=7)
 
94
  }
95
  return xgb_model, knn_model, scaler, metrics, None
96
 
 
97
  # ==========================================
98
+ # 🧠 4. ANALİZ FONKSİYONU
99
  # ==========================================
100
+ def predict_and_analyze():
101
+ df, err = load_local_csv()
 
 
 
102
  if err:
103
  return err, {}
104
 
 
106
  if err:
107
  return err, {}
108
 
109
+ feat = np.array([[metrics["ma5"], metrics["ma20"], metrics["rsi"],
110
+ metrics["macd"], metrics["volume"]]])
 
 
 
 
111
 
112
+ xgb_up = float(xgb_model.predict_proba(feat)[0][1])
113
+ knn_up = float(knn_model.predict_proba(scaler.transform(feat))[0][1])
114
+ ens_up = (xgb_up + knn_up) / 2
115
+ ens_down = 1 - ens_up
116
+ direction = "YUKARI 📈" if ens_up > 0.5 else "AŞAĞI 📉"
117
+ conf = max(ens_up, ens_down) * 100
118
 
119
  prob_dict = {
120
+ "XGBoost Yükseliş": xgb_up,
121
+ "KNN Yükseliş": knn_up,
122
+ "Ensemble Yükseliş": ens_up,
123
  }
124
 
125
  prompt = f"""
126
+ BTC/USD teknik analiz raporu (Türkçe).
127
+ Son Kapanış ({metrics['last_date']}): ${metrics['last_close']:,.2f}
128
+ RSI: {metrics['rsi']:.2f}, MA5: ${metrics['ma5']:,.2f}, MA20: ${metrics['ma20']:,.2f}, MACD: {metrics['macd']:.4f}, Hacim: {metrics['volume']:,.2f}
129
+ XGBoost Yükseliş: %{xgb_up*100:.1f}
130
+ KNN Yükseliş: %{knn_up*100:.1f}
131
+ Ensemble: %{ens_up*100:.1f} -> {direction} (Güven %{conf:.1f})
132
+ Başlıklar: 1. Model Yorumu 2. Teknik Analiz 3. İşlem Stratejisi. Yatırım tavsiyesi değildir.
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  """
134
 
135
  if client:
136
  try:
137
+ resp = client.chat.completions.create(
138
  model="openai/gpt-oss-120b",
139
  messages=[{"role": "user", "content": prompt}],
140
  temperature=0.3,
141
  max_tokens=1024
142
  )
143
+ analysis = resp.choices[0].message.content
144
  except Exception as e:
145
+ analysis = f"Groq API Hatası: {e}"
146
  else:
147
+ analysis = "GROQ_API_KEY bulunamadı!"
148
 
149
  header = (
150
+ f"**Son: ${metrics['last_close']:,.2f}** | RSI: {metrics['rsi']:.1f} | "
151
  f"MA5: ${metrics['ma5']:,.0f} | MA20: ${metrics['ma20']:,.0f}\n\n"
152
+ f"**XGB:** %{xgb_up*100:.1f} | **KNN:** %{knn_up*100:.1f} | "
153
+ f"**Ens:** %{ens_up*100:.1f}\n\n---\n\n"
154
  )
155
+ return header + analysis, prob_dict
 
156
 
157
  # ==========================================
158
+ # 🎨 5. GRADIO ARAYÜZÜ
159
  # ==========================================
160
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="slate")) as demo:
161
  gr.Markdown(
162
+ f"""
163
  # ₿ BTC/USD XGBoost + KNN & Groq AI Tahmin Radarı
164
+ Veri kaynağı: **`{CSV_PATH}`** (Space ana dizini)
 
 
165
  """
166
  )
167
 
168
  with gr.Row():
169
  with gr.Column():
170
+ analyze_btn = gr.Button("📊 CSV'yi Oku ve Analiz Et", variant="primary", size="lg")
171
+ gr.Markdown(
172
+ """
173
+ **Not**: Model, `BTCUSD_M30.csv` dosyasını her butona basışta yeniden okur ve eğitir.
174
+ """
175
+ )
176
  with gr.Column():
177
  prob_output = gr.Label(label="Model Tahminleri")
178
+ analysis_output = gr.Markdown(value="Butona basarak analizi başlatın.")
179
 
180
+ analyze_btn.click(
181
  fn=predict_and_analyze,
182
+ inputs=[],
183
  outputs=[analysis_output, prob_output]
184
  )
185