GoshawkVortexAI commited on
Commit
deea9c4
·
verified ·
1 Parent(s): 7b7258e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -63
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import os
 
2
  import requests
3
  import numpy as np
4
  import pandas as pd
@@ -15,49 +16,125 @@ if api_key:
15
  client = Groq(api_key=api_key)
16
 
17
  # ==========================================
18
- # 📡 2. OKX PUBLIC API VERİ ÇEKME
19
  # ==========================================
 
 
 
 
 
 
 
20
  OKX_BASE = "https://www.okx.com/api/v5"
 
21
 
 
 
 
22
  def fetch_okx_ticker(inst_id="BTC-USDT"):
23
- """OKX'ten anlık fiyat ve 24s verileri çeker (API Key gerekmez)."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  try:
25
- r = requests.get(f"{OKX_BASE}/market/ticker", params={"instId": inst_id}, timeout=10)
 
 
26
  r.raise_for_status()
27
- d = r.json()["data"][0]
28
  return {
29
- "last": float(d["last"]),
30
- "open24h": float(d["open24h"]),
31
- "high24h": float(d["high24h"]),
32
- "low24h": float(d["low24h"]),
33
- "vol24h": float(d["vol24h"]),
34
- "change_pct": (float(d["last"]) / float(d["open24h"]) - 1) * 100
 
35
  }
36
  except Exception as e:
37
- print(f"OKX ticker error: {e}")
38
  return None
39
 
40
 
41
  def fetch_okx_candles(inst_id="BTC-USDT", bar="1H", limit=100):
42
- """OKX'ten mum verisi çeker ve DataFrame döndürür."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  try:
44
- r = requests.get(f"{OKX_BASE}/market/candles",
45
- params={"instId": inst_id, "bar": bar, "limit": limit},
46
- timeout=10)
47
  r.raise_for_status()
48
- raw = r.json()["data"]
49
- # OKX mum formatı: [ts, open, high, low, close, vol, ...]
50
- df = pd.DataFrame(raw, columns=["ts", "open", "high", "low", "close", "vol"])
 
 
51
  for col in ["open", "high", "low", "close", "vol"]:
52
  df[col] = df[col].astype(float)
53
  df["ts"] = pd.to_datetime(df["ts"].astype(int), unit="ms")
54
- df = df.sort_values("ts").reset_index(drop=True)
55
- return df
56
  except Exception as e:
57
- print(f"OKX candles error: {e}")
58
  return None
59
 
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  def compute_rsi(series, period=14):
62
  delta = series.diff()
63
  gain = delta.clip(lower=0).rolling(period).mean()
@@ -65,85 +142,77 @@ def compute_rsi(series, period=14):
65
  rs = gain / loss
66
  return 100 - (100 / (1 + rs))
67
 
68
-
69
  # ==========================================
70
- # 🤖 3. XGBOOST MODEL EĞİTİMİ (OKX verisiyle)
71
  # ==========================================
72
- def train_model_from_okx():
73
- """OKX'ten çekilen mum verisiyle XGBoost modelini eğitir."""
74
- df = fetch_okx_candles(bar="1H", limit=500)
 
 
 
75
  if df is None or len(df) < 50:
76
- return None, None
77
 
78
  df["ma_5"] = df["close"].rolling(5).mean()
79
  df["ma_20"] = df["close"].rolling(20).mean()
80
  df["rsi"] = compute_rsi(df["close"], 14)
81
  df["macd"] = df["close"].ewm(span=12).mean() - df["close"].ewm(span=26).mean()
82
  df["target"] = (df["close"].shift(-1) > df["close"]).astype(int)
83
-
84
  df = df.dropna().reset_index(drop=True)
85
- features = ["ma_5", "ma_20", "rsi", "macd", "vol"]
86
- X = df[features]
87
- y = df["target"]
88
 
 
89
  model = xgb.XGBClassifier(
90
  n_estimators=50, max_depth=3, learning_rate=0.1,
91
  objective="binary:logistic", eval_metric="logloss", random_state=42
92
  )
93
- model.fit(X, y)
94
- return model, features
95
 
96
 
97
- # Başlangıçta modeli OKX verisiyle eğit
98
- xgb_model, feature_cols = train_model_from_okx()
99
  if xgb_model is None:
100
- # Fallback: OKX erişilemezse basit bir dummy model
101
  xgb_model = xgb.XGBClassifier(n_estimators=10, max_depth=2)
102
- dummy_X = np.random.rand(20, 5)
103
- dummy_y = np.random.randint(0, 2, 20)
104
- xgb_model.fit(dummy_X, dummy_y)
105
- feature_cols = ["ma_5", "ma_20", "rsi", "macd", "vol"]
106
 
107
  # ==========================================
108
- # 🧠 4. ANALİZ MOTORU
109
  # ==========================================
110
  def predict_and_analyze():
111
- # 1) OKX'ten canlı veri çek
112
- ticker = fetch_okx_ticker()
113
- candles = fetch_okx_candles(limit=30)
114
 
115
  if ticker is None or candles is None:
116
- return "❌ OKX API'sine erişilemedi. Lütfen daha sonra tekrar deneyin.", {}
117
 
118
  last_price = ticker["last"]
119
  change_pct = ticker["change_pct"]
120
  vol24h = ticker["vol24h"]
 
121
 
122
- # 2) Teknik göstergeler
123
  close = candles["close"]
124
  ma5 = close.rolling(5).mean().iloc[-1]
125
  ma20 = close.rolling(20).mean().iloc[-1]
126
  rsi = compute_rsi(close, 14).iloc[-1]
127
  macd = (close.ewm(span=12).mean() - close.ewm(span=26).mean()).iloc[-1]
128
 
129
- # 3) XGBoost tahmini
130
  features = np.array([[ma5, ma20, rsi, macd, vol24h]])
131
  prob_up = float(xgb_model.predict_proba(features)[0][1])
132
  prob_down = 1 - prob_up
 
 
133
 
134
  prob_dict = {
135
  "Yükseliş (Long) Olasılığı": prob_up,
136
  "Düşüş (Short) Olasılığı": prob_down,
137
  }
138
 
139
- direction = "YUKARI 📈" if prob_up > 0.5 else "AŞAĞI 📉"
140
- confidence = max(prob_up, prob_down) * 100
141
-
142
- # 4) Groq analizi
143
  prompt = f"""
144
  Sen uzman bir kripto para analisti ve teknik analiz uzmanısın.
145
 
146
- 📡 OKX Canlı Verileri (BTC/USDT):
147
  - Son Fiyat: ${last_price:,.2f}
148
  - 24s Değişim: %{change_pct:+.2f}
149
  - 24s Hacim: {vol24h:,.0f} BTC
@@ -181,34 +250,33 @@ def predict_and_analyze():
181
  else:
182
  analysis_result = "GROQ_API_KEY bulunamadı! Hugging Face Secrets'a ekleyin."
183
 
184
- # Başlık bilgisi
185
- header = f"**OKX Canlı: ${last_price:,.2f}** (%{change_pct:+.2f}) | RSI: {rsi:.1f} | MA5: ${ma5:,.0f} | MA20: ${ma20:,.0f}\n\n---\n\n"
 
 
186
  return header + analysis_result, prob_dict
187
 
188
-
189
  # ==========================================
190
- # 🎨 5. GRADIO ARAYÜZÜ
191
  # ==========================================
192
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="slate")) as demo:
193
  gr.Markdown(
194
  """
195
- # ₿ BTC/USD XGBoost & Groq AI Tahmin Radarı (OKX Canlı)
196
- Fiyat, hacim ve teknik göstergeler **OKX halka açık API**'sinden otomatik çekilir. **XGBoost** yön tahmini yapar, **Groq** analiz raporu üretir.
197
  """
198
  )
199
 
200
  with gr.Row():
201
  with gr.Column():
202
- analyze_btn = gr.Button("🔄 OKX'ten Veri Çek ve Analiz Et", variant="primary", size="lg")
203
  gr.Markdown(
204
- """
205
- **Not**: OKX API'si her 2 saniyede 20 istek sınırına sahiptir [citation:7]. Butona çok hızlı basmayın.
206
- """
207
  )
208
 
209
  with gr.Column():
210
  prob_output = gr.Label(label="XGBoost Yön Tahmini")
211
- analysis_output = gr.Markdown(value="Butona basarak OKX'ten canlı veri çekip analizi başlatın.")
212
 
213
  analyze_btn.click(
214
  fn=predict_and_analyze,
 
1
  import os
2
+ import time
3
  import requests
4
  import numpy as np
5
  import pandas as pd
 
16
  client = Groq(api_key=api_key)
17
 
18
  # ==========================================
19
+ # 📡 2. API İSTEK BAŞLIKLARI (Cloudflare engelini aşmak için)
20
  # ==========================================
21
+ HEADERS = {
22
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
23
+ "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
24
+ "Accept": "application/json",
25
+ "Accept-Language": "en-US,en;q=0.9",
26
+ }
27
+
28
  OKX_BASE = "https://www.okx.com/api/v5"
29
+ BINANCE_BASE = "https://api.binance.com/api/v3"
30
 
31
+ # ==========================================
32
+ # 📡 3. VERİ ÇEKME FONKSİYONLARI (Retry + Fallback)
33
+ # ==========================================
34
  def fetch_okx_ticker(inst_id="BTC-USDT"):
35
+ """OKX'ten anlık fiyat çeker. 3 kez dener."""
36
+ for attempt in range(3):
37
+ try:
38
+ r = requests.get(f"{OKX_BASE}/market/ticker",
39
+ params={"instId": inst_id},
40
+ headers=HEADERS, timeout=15)
41
+ r.raise_for_status()
42
+ d = r.json()["data"][0]
43
+ return {
44
+ "source": "OKX",
45
+ "last": float(d["last"]),
46
+ "open24h": float(d["open24h"]),
47
+ "high24h": float(d["high24h"]),
48
+ "low24h": float(d["low24h"]),
49
+ "vol24h": float(d["vol24h"]),
50
+ "change_pct": (float(d["last"]) / float(d["open24h"]) - 1) * 100
51
+ }
52
+ except Exception as e:
53
+ print(f"OKX ticker attempt {attempt+1} failed: {e}")
54
+ if attempt < 2:
55
+ time.sleep(2)
56
+ return None
57
+
58
+
59
+ def fetch_binance_ticker(symbol="BTCUSDT"):
60
+ """OKX başarısız olursa Binance'ten fiyat çeker (yedek)."""
61
  try:
62
+ r = requests.get(f"{BINANCE_BASE}/ticker/24hr",
63
+ params={"symbol": symbol},
64
+ headers=HEADERS, timeout=15)
65
  r.raise_for_status()
66
+ d = r.json()
67
  return {
68
+ "source": "Binance",
69
+ "last": float(d["lastPrice"]),
70
+ "open24h": float(d["openPrice"]),
71
+ "high24h": float(d["highPrice"]),
72
+ "low24h": float(d["lowPrice"]),
73
+ "vol24h": float(d["volume"]),
74
+ "change_pct": float(d["priceChangePercent"])
75
  }
76
  except Exception as e:
77
+ print(f"Binance ticker failed: {e}")
78
  return None
79
 
80
 
81
  def fetch_okx_candles(inst_id="BTC-USDT", bar="1H", limit=100):
82
+ """OKX'ten mum verisi çeker."""
83
+ for attempt in range(3):
84
+ try:
85
+ r = requests.get(f"{OKX_BASE}/market/candles",
86
+ params={"instId": inst_id, "bar": bar, "limit": limit},
87
+ headers=HEADERS, timeout=15)
88
+ r.raise_for_status()
89
+ raw = r.json()["data"]
90
+ df = pd.DataFrame(raw, columns=["ts", "open", "high", "low", "close", "vol"])
91
+ for col in ["open", "high", "low", "close", "vol"]:
92
+ df[col] = df[col].astype(float)
93
+ df["ts"] = pd.to_datetime(df["ts"].astype(int), unit="ms")
94
+ df = df.sort_values("ts").reset_index(drop=True)
95
+ return df
96
+ except Exception as e:
97
+ print(f"OKX candles attempt {attempt+1} failed: {e}")
98
+ if attempt < 2:
99
+ time.sleep(2)
100
+ return None
101
+
102
+
103
+ def fetch_binance_candles(symbol="BTCUSDT", interval="1h", limit=100):
104
+ """OKX başarısız olursa Binance'ten mum verisi çeker."""
105
  try:
106
+ r = requests.get(f"{BINANCE_BASE}/klines",
107
+ params={"symbol": symbol, "interval": interval, "limit": limit},
108
+ headers=HEADERS, timeout=15)
109
  r.raise_for_status()
110
+ raw = r.json()
111
+ df = pd.DataFrame(raw, columns=[
112
+ "ts", "open", "high", "low", "close", "vol",
113
+ "close_time", "quote_vol", "trades", "buy_base", "buy_quote", "ignore"
114
+ ])
115
  for col in ["open", "high", "low", "close", "vol"]:
116
  df[col] = df[col].astype(float)
117
  df["ts"] = pd.to_datetime(df["ts"].astype(int), unit="ms")
118
+ return df[["ts", "open", "high", "low", "close", "vol"]]
 
119
  except Exception as e:
120
+ print(f"Binance candles failed: {e}")
121
  return None
122
 
123
 
124
+ def fetch_market_data():
125
+ """Önce OKX'i dener, başarısız olursa Binance'e geçer."""
126
+ ticker = fetch_okx_ticker()
127
+ candles = fetch_okx_candles()
128
+
129
+ if ticker is not None and candles is not None:
130
+ return ticker, candles
131
+
132
+ print("OKX failed, switching to Binance fallback...")
133
+ ticker = fetch_binance_ticker()
134
+ candles = fetch_binance_candles()
135
+ return ticker, candles
136
+
137
+
138
  def compute_rsi(series, period=14):
139
  delta = series.diff()
140
  gain = delta.clip(lower=0).rolling(period).mean()
 
142
  rs = gain / loss
143
  return 100 - (100 / (1 + rs))
144
 
 
145
  # ==========================================
146
+ # 🤖 4. XGBOOST MODEL EĞİTİMİ
147
  # ==========================================
148
+ def train_model():
149
+ """Çekilen mum verisiyle XGBoost modelini eğitir."""
150
+ df = fetch_okx_candles(limit=500)
151
+ if df is None:
152
+ df = fetch_binance_candles(limit=500)
153
+
154
  if df is None or len(df) < 50:
155
+ return None
156
 
157
  df["ma_5"] = df["close"].rolling(5).mean()
158
  df["ma_20"] = df["close"].rolling(20).mean()
159
  df["rsi"] = compute_rsi(df["close"], 14)
160
  df["macd"] = df["close"].ewm(span=12).mean() - df["close"].ewm(span=26).mean()
161
  df["target"] = (df["close"].shift(-1) > df["close"]).astype(int)
 
162
  df = df.dropna().reset_index(drop=True)
 
 
 
163
 
164
+ features = ["ma_5", "ma_20", "rsi", "macd", "vol"]
165
  model = xgb.XGBClassifier(
166
  n_estimators=50, max_depth=3, learning_rate=0.1,
167
  objective="binary:logistic", eval_metric="logloss", random_state=42
168
  )
169
+ model.fit(df[features], df["target"])
170
+ return model
171
 
172
 
173
+ # Uygulama başlarken modeli eğit
174
+ xgb_model = train_model()
175
  if xgb_model is None:
176
+ # Fallback: API hiç çalışmazsa dummy model
177
  xgb_model = xgb.XGBClassifier(n_estimators=10, max_depth=2)
178
+ xgb_model.fit(np.random.rand(20, 5), np.random.randint(0, 2, 20))
 
 
 
179
 
180
  # ==========================================
181
+ # 🧠 5. ANALİZ MOTORU
182
  # ==========================================
183
  def predict_and_analyze():
184
+ ticker, candles = fetch_market_data()
 
 
185
 
186
  if ticker is None or candles is None:
187
+ return "❌ Hem OKX hem de Binance API'sine erişilemedi. Lütfen daha sonra tekrar deneyin.", {}
188
 
189
  last_price = ticker["last"]
190
  change_pct = ticker["change_pct"]
191
  vol24h = ticker["vol24h"]
192
+ source = ticker["source"]
193
 
 
194
  close = candles["close"]
195
  ma5 = close.rolling(5).mean().iloc[-1]
196
  ma20 = close.rolling(20).mean().iloc[-1]
197
  rsi = compute_rsi(close, 14).iloc[-1]
198
  macd = (close.ewm(span=12).mean() - close.ewm(span=26).mean()).iloc[-1]
199
 
200
+ # XGBoost tahmini
201
  features = np.array([[ma5, ma20, rsi, macd, vol24h]])
202
  prob_up = float(xgb_model.predict_proba(features)[0][1])
203
  prob_down = 1 - prob_up
204
+ direction = "YUKARI 📈" if prob_up > 0.5 else "AŞAĞI 📉"
205
+ confidence = max(prob_up, prob_down) * 100
206
 
207
  prob_dict = {
208
  "Yükseliş (Long) Olasılığı": prob_up,
209
  "Düşüş (Short) Olasılığı": prob_down,
210
  }
211
 
 
 
 
 
212
  prompt = f"""
213
  Sen uzman bir kripto para analisti ve teknik analiz uzmanısın.
214
 
215
+ 📡 Canlı Veri Kaynağı: {source} (BTC/USDT)
216
  - Son Fiyat: ${last_price:,.2f}
217
  - 24s Değişim: %{change_pct:+.2f}
218
  - 24s Hacim: {vol24h:,.0f} BTC
 
250
  else:
251
  analysis_result = "GROQ_API_KEY bulunamadı! Hugging Face Secrets'a ekleyin."
252
 
253
+ header = (
254
+ f"**Kaynak: {source}** | **Canlı: ${last_price:,.2f}** (%{change_pct:+.2f}) | "
255
+ f"RSI: {rsi:.1f} | MA5: ${ma5:,.0f} | MA20: ${ma20:,.0f}\n\n---\n\n"
256
+ )
257
  return header + analysis_result, prob_dict
258
 
 
259
  # ==========================================
260
+ # 🎨 6. GRADIO ARAYÜZÜ
261
  # ==========================================
262
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="slate")) as demo:
263
  gr.Markdown(
264
  """
265
+ # ₿ BTC/USD XGBoost & Groq AI Tahmin Radarı (Canlı)
266
+ Veriler **OKX halka açık API**'sinden çekilir; OKX'e erişilemezse otomatik olarak **Binance**'e geçilir. **XGBoost** yön tahmini yapar, **Groq** analiz raporu üretir.
267
  """
268
  )
269
 
270
  with gr.Row():
271
  with gr.Column():
272
+ analyze_btn = gr.Button("🔄 Canlı Veri Çek ve Analiz Et", variant="primary", size="lg")
273
  gr.Markdown(
274
+ "**Not**: API rate limit nedeniyle butona çok hızlı basmayın."
 
 
275
  )
276
 
277
  with gr.Column():
278
  prob_output = gr.Label(label="XGBoost Yön Tahmini")
279
+ analysis_output = gr.Markdown(value="Butona basarak canlı veri çekip analizi başlatın.")
280
 
281
  analyze_btn.click(
282
  fn=predict_and_analyze,